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": {
|
"exports": {
|
||||||
".": "./src/index.ts",
|
".": "./src/index.ts",
|
||||||
"./navbar/*": "./src/navbar/*",
|
"./navbar/*": "./src/navbar/*",
|
||||||
"./accordion/*": "./src/accordion/*"
|
"./accordion/*": "./src/accordion/*",
|
||||||
|
"./offcanvas/*": "./src/offcanvas/*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest",
|
"@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,25 +1,20 @@
|
||||||
nav {
|
nav.msp-navbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-desktop ul {
|
ul {
|
||||||
width: fit-content;
|
|
||||||
margin-left: auto;
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
|
||||||
|
|
||||||
li > a {
|
li {
|
||||||
|
margin-bottom: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li > a {
|
||||||
padding: 0.25rem 0.5rem;
|
padding: 0.25rem 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
--boder-color: transparent;
|
--boder-color: transparent;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
@ -28,15 +23,25 @@ a {
|
||||||
transition:
|
transition:
|
||||||
background-color 200ms,
|
background-color 200ms,
|
||||||
color 200ms;
|
color 200ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.active {
|
a.active {
|
||||||
border: 1px solid var(--prj-accent-bg);
|
border: 1px solid var(--msp-color-bg-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
--border-color: var(--prj-accent-bg);
|
--border-color: var(--msp-color-bg-accent);
|
||||||
background-color: var(--prj-accent-bg);
|
background-color: var(--msp-color-bg-accent);
|
||||||
color: var(--prj-accent-text);
|
color: var(--msp-color-text-accent);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.msp-navbar-desktop ul {
|
||||||
|
width: fit-content;
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -91,6 +91,12 @@ $msp-colors: (
|
||||||
"--msp-color-transparent": transparent,
|
"--msp-color-transparent": transparent,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$anim: (
|
||||||
|
"--msp-anim-duration-sm": 0.4s,
|
||||||
|
"--msp-anim-duration-md": 0.8s,
|
||||||
|
"--msp-anim-duration-lg": 1s,
|
||||||
|
);
|
||||||
|
|
||||||
// Native CSS Variables to allow overridings and usage in external stylesheets
|
// Native CSS Variables to allow overridings and usage in external stylesheets
|
||||||
:root {
|
:root {
|
||||||
@each $variable, $value in $msp-colors {
|
@each $variable, $value in $msp-colors {
|
||||||
|
|
@ -101,6 +107,10 @@ $msp-colors: (
|
||||||
#{$variable}: #{$value};
|
#{$variable}: #{$value};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@each $variable, $value in $anim {
|
||||||
|
#{$variable}: #{$value};
|
||||||
|
}
|
||||||
|
|
||||||
// ── Borders ─────────────────────────────────────────────────────────────
|
// ── Borders ─────────────────────────────────────────────────────────────
|
||||||
--msp-border-width: 1px;
|
--msp-border-width: 1px;
|
||||||
--msp-border-color: var(--msp-color-text-transparent);
|
--msp-border-color: var(--msp-color-text-transparent);
|
||||||
|
|
|
||||||
|
|
@ -123,10 +123,18 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.msp-justify-content-start {
|
||||||
|
justify-content: start !important;
|
||||||
|
}
|
||||||
|
|
||||||
.msp-justify-content-center {
|
.msp-justify-content-center {
|
||||||
justify-content: center !important;
|
justify-content: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.msp-justify-content-end {
|
||||||
|
justify-content: end !important;
|
||||||
|
}
|
||||||
|
|
||||||
.msp-justify-content-between {
|
.msp-justify-content-between {
|
||||||
justify-content: space-between !important;
|
justify-content: space-between !important;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
import "@mini-strap/components/accordion/index.ts";
|
import "@mini-strap/components/accordion/index.ts";
|
||||||
|
import "@mini-strap/components/offcanvas/index.ts";
|
||||||
console.log("hello world!");
|
console.log("hello world!");
|
||||||
|
|
|
||||||
1
packages/website/sass/@mini-strap/core/style.scss
Symbolic link
1
packages/website/sass/@mini-strap/core/style.scss
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
/home/aleidk/Repos/Projects/mini-strap/packages/core/src/style.scss
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
@use "@mini-strap/core";
|
@use "@mini-strap/core";
|
||||||
@use "@mini-strap/components/navbar/navbar.scss";
|
@use "@mini-strap/components/navbar/navbar.scss";
|
||||||
@use "@mini-strap/components/accordion/accordion.scss";
|
@use "@mini-strap/components/accordion/accordion.scss";
|
||||||
|
@use "@mini-strap/components/offcanvas/style.scss";
|
||||||
|
|
||||||
html {
|
html {
|
||||||
// background-color: red;
|
// background-color: red;
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,26 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="description" content="Astro description" />
|
<meta name="description" content="Astro description" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<title>alecodes.page</title>
|
<title>alecodes.page</title>
|
||||||
<ViewTransitions />
|
<ViewTransitions />
|
||||||
|
|
||||||
{% block scripts %}<script src="/js/index.js"></script>{% endblock %}
|
{% block scripts %}
|
||||||
|
<script src="/js/index.js"></script>{% endblock %}
|
||||||
<link rel="stylesheet" href="/css/style.css" />
|
<link rel="stylesheet" href="/css/style.css" />
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body transition:animate="fade">
|
<body transition:animate="fade">
|
||||||
<header class="msp-position-sticky msp-py-1 msp-py-lg-3">
|
<header class="msp-py-1 msp-py-lg-3">
|
||||||
{% include "partials/header.html" %}
|
{% include "partials/header.html" %}
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,19 @@
|
||||||
<ul class="msp-list-unstyle msp-accordion">
|
<aside id="main-offcanvas" class="msp-offcanvas">
|
||||||
|
<div class="msp-offcanvas-backdrop msp-offcanvas-toggle"
|
||||||
|
data-msp-target="#main-offcanvas"></div>
|
||||||
|
|
||||||
|
<div class="msp-offcanvas-content">
|
||||||
|
<div class="msp-offcanvas-body">
|
||||||
|
<ul class="msp-list-unstyle msp-accordion">
|
||||||
<li>
|
<li>
|
||||||
<a href="/">Overview</a>
|
<a href="/">Overview</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% for item in get_taxonomy(kind="section") | get(key="items") %}
|
{% for item in get_taxonomy(kind="section") | get(key="items") %}
|
||||||
<li class="msp-accordion-item">
|
<li class="msp-accordion-item">
|
||||||
<a class="msp-accordion-header" href="{{ get_url(path="@/" ~ item.slug ~ "/_index.md") }}">{{ item.name | title }}</a>
|
<a class="msp-accordion-header" href="{{ get_url(path="@/" ~ item.slug ~ "/_index.md") }}">{{ item.name |
|
||||||
|
title
|
||||||
|
}}</a>
|
||||||
<div class="msp-accordion-collapse">
|
<div class="msp-accordion-collapse">
|
||||||
<ul class="msp-list-unstyle msp-accordion-content">
|
<ul class="msp-list-unstyle msp-accordion-content">
|
||||||
{% for page in item.pages %}
|
{% for page in item.pages %}
|
||||||
|
|
@ -17,4 +25,11 @@
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<nav class="msp-d-flex msp-justify-content-end">
|
||||||
|
<button class="msp-offcanvas-toggle" data-msp-target="#main-offcanvas">Toggle</button>
|
||||||
|
</nav>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue