Make mobile compatible

This commit is contained in:
Zack Rauen 2023-09-23 02:56:59 -04:00
parent 039a5ac2e3
commit cb19ed36bc
10 changed files with 559 additions and 456 deletions

View File

@ -8,6 +8,7 @@ import fixSubMenu from "./fixes/submenu";
import generateTOC from "./navigation/toc";
import addExternalLinks from "./fixes/externallinks";
import injectSwagger from "./other/swagger";
import makeMobileMenu from "./other/mobile";
// https://instance-name/api/notes/vW1cXaYNN7OM/download
@ -30,6 +31,8 @@ function $try<T extends (...a: unknown[]) => unknown>(func: T, ...args: Paramete
// }
// };
// Perform fixes first
$try(fixActiveLink);
$try(fixTableHeaders);
@ -44,6 +47,12 @@ $try(generateTOC);
// Finally, other features
$try(highlight);
$try(injectSwagger);
$try(makeMobileMenu);
// mobileMenu.append(document.querySelector("#menu > ul")!);
// mobileMenu.append(document.querySelector("#sidebar")!);
// try {fixActiveLink();}

View File

@ -47,4 +47,5 @@ export default function buildBreadcrumbsFromNav() {
// Add breadcrumb container to the main layout
const main = document.getElementById("main");
main?.prepend(container);
container.scrollLeft = container.scrollWidth - container.clientWidth;
}

74
src/main/other/mobile.ts Normal file
View File

@ -0,0 +1,74 @@
const parseHTML = (html: string, fragment = false) => {
const template = document.createElement("template");
template.innerHTML = html;
const node = template.content.cloneNode(true);
if (fragment) return node;
return node.childNodes.length > 1 ? node.childNodes : node.childNodes[0];
};
const goBackString = `<li id="go-back"><p><a class="type-text" href="#">↩ Back to Main Menu</a></p></li>`;
const menuButtonString = `<button id="menuButton" class="expand left" aria-label="Menu">
<span class="rectangle"></span>
<span class="rectangle"></span>
<span class="rectangle"></span>
</button>`;
const isMobileAgent = /Mobi/.test(navigator.userAgent);
const isMobileSize = window.matchMedia("only screen and (max-width: 760px)").matches;
// TODO: maybe re-work this to have #sidebar be later than #menu
// then use #menu.expanded ~ #sidebar for showing the sidebar
// that way less JS is involved to make mobile work properly
export default function makeMobileMenu() {
if (!isMobileAgent && !isMobileSize) return; // If nothing indicates mobile, bail out
const menuWrap = document.querySelector("#menu");
const mainMenu = document.querySelector("#menu > ul");
if (!menuWrap || !mainMenu) return; // Something went really wrong...
const sidebar = document.querySelector("#sidebar");
const toggleMenu = (event: MouseEvent) => {
event.stopPropagation(); // Don't preventDefault to allow links
const isVisible = menuWrap.classList.contains("expanded");
if (isVisible) {
menuWrap.classList.remove("expanded");
if (sidebar) {
mainMenu.classList.remove("active");
if (!sidebar.classList.contains("active")) sidebar.classList.add("active");
}
}
else {
menuWrap.classList.add("expanded");
}
};
const menuButton = parseHTML(menuButtonString) as HTMLButtonElement;
menuButton.addEventListener("click", toggleMenu);
window.addEventListener("click", e => {
const isVisible = menuWrap.classList.contains("expanded");
if (!isVisible) return; // This is only for when the menu is open
toggleMenu(e);
});
if (sidebar) {
const goBackButton = parseHTML(goBackString) as HTMLLIElement;
goBackButton.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
mainMenu.classList.add("active");
sidebar.classList.remove("active");
});
sidebar.prepend(goBackButton);
}
if (sidebar) sidebar.classList.add("active");
else mainMenu.classList.add("active");
menuWrap.append(menuButton);
if (sidebar) menuWrap.append(sidebar);
}

View File

@ -0,0 +1,47 @@
#breadcrumbs {
margin-bottom: 30px;
display: flex;
align-items: center;
list-style: none;
padding: 0;
overflow-x: auto;
}
#breadcrumbs li {
display: flex;
align-items: center;
}
#breadcrumbs a {
display: flex;
align-items: center;
white-space: nowrap;
padding: 5px 10px;
border-radius: 20px;
transition: color 200ms ease, transform 200ms ease, background-color 200ms ease;
}
#breadcrumbs img {
min-width: 18px;
filter: invert(100%);
}
#breadcrumbs li:not(:last-child)::after {
background: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 256 256\"><g><g><polygon points=\"79.093,0 48.907,30.187 146.72,128 48.907,225.813 79.093,256 207.093,128\"/></g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg>") center;
content: " ";
display: inline-block;
filter: invert(0.64) sepia(0.11) saturate(0) hue-rotate(149deg) brightness(0.99) contrast(0.95);
height: 8px;
margin: 0 8px;
opacity: .5;
width: 8px;
}
#breadcrumbs li:last-child a,
#breadcrumbs li a:hover {
background: #202127;
}
#breadcrumbs li a:hover {
transform: translateY(-3px);
}

View File

@ -0,0 +1,19 @@
a[href^="https://"] {
display: inline-flex;
align-items: center;
gap: 6px;
}
#main a[href^="https://"] {
padding-right: 6px;
}
a[href^="https://"]::after {
content: "";
background-color: currentcolor;
mask: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13.5\" height=\"13.5\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z\"></path></svg>");
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13.5\" height=\"13.5\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z\"></path></svg>");
width: 13.5px;
height: 13.5px;
display: inline-flex;
}

View File

@ -1,4 +1,12 @@
@import "./breadcrumbs.css";
@import "./externallinks.css";
@import "./navbar.css";
@import "./sidebar.css";
@import "./swagger.css";
@import "./toc.css";
@import "./mobile.css";
* {box-sizing: border-box;}
@ -22,6 +30,8 @@
--container-width: 1400px /*calc(100% - 10%)*/;
--pane-size: 20%;
scroll-padding-top: calc(72px + 1rem);
color-scheme: dark;
}
@ -45,79 +55,8 @@ a:hover {
color: var(--accent-color);
}
#main a {
color: var(--accent-color);
}
#main a:hover {
color: var(--text-heading);
}
/* a[href^="https://"]::after {
font-size: smaller;
content: "\2197";
vertical-align: top;
} */
a[href^="https://"] {
display: inline-flex;
align-items: center;
gap: 6px;
}
#main a[href^="https://"] {
padding-right: 6px;
}
a[href^="https://"]::after {
content: "";
background-color: currentcolor;
mask: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13.5\" height=\"13.5\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z\"></path></svg>");
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13.5\" height=\"13.5\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z\"></path></svg>");
width: 13.5px;
height: 13.5px;
display: inline-flex;
}
/* pre {
overflow: auto;
}
img {
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
iframe {
border: none;
border-radius: 0.25rem;
}
#layout {
display: flex;
flex-flow: row wrap;
justify-content: center;
min-height: 100vh;
max-width: 960px;
}
#main {
contain: content;
background-color: var(--top-layer);
padding: 2rem 3rem 2rem 3rem;
box-shadow: 0 2px 10px rgba(0,0,0,.25)!important;
order: 2;
}
#title {
text-align: center;
margin-block-end: 24px;
font-size: 32px;
line-height: 48px;
letter-spacing: 0.02em;
} */
#content {
font-size: 16px;
@ -237,252 +176,7 @@ iframe {
display: none;
}
/* .showMenu #menu {
display: block;
}
#menu strong{
color: var(--blue-strong);
} */
/* nav.grid ul {
display: flex;
flex-flow: row wrap;
gap: 1rem;
}
nav.list {
line-height: 1.5;
}
nav ul {
list-style-type: none;
padding: 0 1rem;
}
#parentLink {
display: none;
color: var(--gray);
position: relative;
left: -3rem;
top: -1rem;
}
#parentLink::before {
content: "@";
}
input:disabled {
border-radius: 3px;
background-color: #cacaca;
}
.ck-content .table table {
border: 0;
}
.ck-content .table table th {
background: #252526;
word-wrap: normal;
background-clip: padding-box;
}
.ck-content .table table th.empty {
opacity: 0;
border: 0;
}
@media screen and (min-width: 60rem) {
#main {
width: 48rem;
margin-block-start: 6rem;
margin-block-end: 6rem;
box-shadow: var(--shadow);
border-radius: 4px 4px 0px 0px;
}
#toggleMenuButton {
right: 1rem;
top: 1rem;
}
}
@media screen and (max-width: 60rem) {
#main {
width: 100%;
}
#toggleMenuButton {
right: 1rem;
bottom: 1rem;
}
}
@media screen and (max-width: 32rem) {
#main {
padding: 4rem 2rem 2rem 2rem;
}
#content h2::before {
left: 1rem;
}
#parentLink {
left: 0rem;
}
} */
#menu {
display: flex;
position: fixed;
justify-content: space-between;
align-items: center;
top: 0;
left: 0;
right: 0;
width: inherit;
margin: 0 auto;
overflow: visible;
z-index: 10;
background: var(--bottom-layer);
padding: 8px 16px;
}
#menu::before {
content: "";
position: fixed;
left: 0;
right: 0;
background: var(--bottom-layer);
height: 72px;
z-index: -1;
}
#menu > p > a {
display: flex;
white-space: nowrap;
gap: 10px;
align-items: center;
/* color: var(--text-heading); */
}
/* #menu > p > a:hover {
color: var(--accent-color);
} */
/* #menu a {
color: var(--text-heading);
}
#menu a:hover {
color: var(--accent-color);
} */
#menu > p > a::before {
content: "";
display: flex;
background: url("https://raw.githubusercontent.com/zadam/trilium/master/images/icon-color.svg");
height: 40px;
width: 53px;
}
/* #logo {
order: 1;
height: 40px;
} */
/* #menu > p > strong::before {
content: "";
display: flex;
background: url("https://notes.cloud.zerebos.com/assets/v0.60.4/images/icon-black.svg");
} */
#menu ul, #sidebar ul {
list-style: none;
padding: 0;
position: relative;
}
#menu > ul {
margin: 0;
padding: 0;
display: flex;
gap: 30px;
}
#menu > ul > li {
margin: 0;
padding: 0;
position: relative;
}
#menu > ul > li > p > a {
display: flex;
gap: 10px;
align-items: center;
font-weight: 700;
padding: 16px 0;
}
/* #menu > ul > li > p > a::after {
content: '';
border: 4px solid transparent;
border-top: 4px solid white;
display: flex;
align-items: center;
margin-bottom: -8px;
} */
#menu > ul > li.submenu-item > p > a::after {
content: "";
border-color: currentcolor #0000;
border-style: solid;
border-width: .4em .4em 0;
position: relative;
display: flex;
top: 2px;
align-items: center;
/* transform: translateY(-50%); */
}
#menu > ul > li.submenu-item.hidden > ul,
#menu > ul > li.submenu-item.hidden > p > a::after{
display: none;
}
#menu > ul > li > ul {
/* display: none; */
opacity: 0;
pointer-events: none;
position: absolute;
top: 40px;
background: #242526;
border-radius: 6px;
min-width: 150px;
right: 50%;
transform: translateX(50%);
padding: 8px;
transition: top 200ms ease, opacity 200ms ease;
}
#menu > ul > li > ul > li a {
display: flex;
border-radius: 6px;
padding: 3px 6px;
transition: background-color 200ms ease;
}
#menu > ul > li > ul > li a:hover {
background: rgba(255,255,255,0.05);
}
#menu > ul > li > ul > li > ul {
display: none;
}
#menu > ul > li:hover > ul {
/* display: flex; */
top: 50px;
opacity: 1;
pointer-events: initial;
}
body {
@ -515,12 +209,7 @@ body {
}
}
#sidebar {
flex: var(--pane-size);
height: fit-content;
position: sticky;
top: calc(72px + 1rem);
}
#main {
flex: 100%;
@ -546,57 +235,6 @@ body {
#sidebar, #sidebar ul {
list-style: none;
padding: 0;
margin: 0;
}
#sidebar {
/* padding-right: 20px; */
}
/* #sidebar .title {
text-transform: uppercase;
text-align: center;
letter-spacing: 5px;
color: #777;
font-weight: 700;
border-bottom: 1px solid #777;
} */
#sidebar p {
display: flex;
margin: 0;
}
#sidebar a {
flex: 1;
padding: 6px 6px 6px 12px;
border-radius: 6px;
transition: color 200ms ease, background-color 200ms ease;
}
#sidebar a:hover {
background: rgba(255,255,255,0.05);
}
#sidebar > li > ul > li.submenu-item > p > a {
text-transform: uppercase;
font-weight: 700;
color: #555;
}
#sidebar li > ul {
margin-top: 5px;
}
#sidebar > li > ul.hasSubmenu,
#sidebar > li > ul > li.submenu-item + li.submenu-item {
margin-top: 20px;
}
@ -605,7 +243,7 @@ body {
/* .ck-content pre {background: none;} */
.ck-content code {
background-color: var(--accent-layer);
border-radius: 6px;
@ -625,51 +263,7 @@ body {
#breadcrumbs {
margin-bottom: 30px;
display: flex;
align-items: center;
list-style: none;
padding: 0;
}
#breadcrumbs li {
display: flex;
align-items: center;
}
#breadcrumbs a {
display: flex;
align-items: center;
padding: 5px 10px;
border-radius: 20px;
transition: color 200ms ease, transform 200ms ease, background-color 200ms ease;
}
#breadcrumbs img {
width: 18px;
filter: invert(100%);
}
#breadcrumbs li:not(:last-child)::after {
background: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 256 256\"><g><g><polygon points=\"79.093,0 48.907,30.187 146.72,128 48.907,225.813 79.093,256 207.093,128\"/></g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg>") center;
content: " ";
display: inline-block;
filter: invert(0.64) sepia(0.11) saturate(0) hue-rotate(149deg) brightness(0.99) contrast(0.95);
height: 8px;
margin: 0 8px;
opacity: .5;
width: 8px;
}
#breadcrumbs li:last-child a,
#breadcrumbs li a:hover {
background: #202127;
}
#breadcrumbs li a:hover {
transform: translateY(-3px);
}
#parentLink {
display: none;
@ -679,45 +273,7 @@ body {
#toc {
flex: var(--pane-size);
position: sticky;
top: calc(72px + 1rem);
height: fit-content;
background: var(--top-layer);
margin: 0;
padding: 16px 16px 16px 32px;
border-radius: 6px;
}
#toc, #toc ul {
list-style: none;
}
#toc ul {
padding-left: 16px;
}
#toc li a {
color: var(--text-heading);
transition: color 200ms ease;
}
#toc li a:hover,
#toc li a.active {
color: var(--accent-color);
}
#toc::before {
content: "";
display: block;
position: absolute;
left: 16px;
top: 20px;
width: 2px;
height: calc(100% - 40px);
background: rgba(255, 255, 255, 0.1);
}

148
src/styles/mobile.css Normal file
View File

@ -0,0 +1,148 @@
.expand {
display: none
}
button.expand {
position: relative;
padding: 9px;
margin: 9.5px 0;
border: 0 solid #000;
border-radius: 4px;
background: 0 0;
color: #fff;
-webkit-transition: -webkit-transform .5s;
-moz-transition: transform .5s;
-o-transition: transform .5s;
transition: transform .5s
}
.expanded button.expand {
background-color: #000;
-webkit-transition: -webkit-transform .5s, background-color .5s;
-moz-transition: transform .5s, background-color .5s;
-o-transition: transform .5s, background-color .5s;
transition: transform .5s, background-color .5s;
-ms-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
transform: rotate(90deg)
}
.expanded .rectangle {
background: #fff;
}
.rectangle {
display: block;
width: 24px;
height: 4px;
border-radius: 1px;
background: var(--text-heading);
transition: transform .5s, background-color .5s;
}
.rectangle + .rectangle {
margin-top: 5px
}
@media screen and (max-width: 768px) {
#toc {
display: none;
}
#main {
padding: 1rem;
}
#layout {
overflow: hidden;
}
#menu {
width: auto;
}
.expand {
display: inline-block
}
#menu::after {
content: "";
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 100%;
width: 100%;
transition: background-color 200ms ease;
pointer-events: none;
}
#menu.expanded::after {
width: 100%;
background: rgba(0,0,0,0.7);
}
#menu > ul {
position: fixed;
transform: translateX(-100%);
transition: transform 200ms ease;
transform-origin: 0 0;
z-index: 1;
background: #040405;
display: initial;
top: 0;
left: 0;
bottom: 0;
height: 100%;
width: 70%;
padding: 1rem;
overflow: auto;
}
#menu #go-back {
margin-bottom: 20px;
}
#menu.expanded > ul.active {
transform: translateX(0);
}
#menu #sidebar .category > p > a {
font-weight: 400;
}
#menu > ul > li > p > a {
padding: 3px 6px;
}
#menu > ul > li > ul {
background: none;
opacity: 1;
position: initial;
transform: none;
margin-top: 0;
pointer-events: initial;
padding: 0;
}
#menu > ul > li.submenu-item > p > a::after {
display: none;
}
#menu > ul > li > ul > li > ul {
display: initial;
}
#menu > ul:not(#sidebar) > li > ul > li > ul {
display: none;
}
#menu > ul:not(#sidebar) ul {
margin-left: 20px;
}
}

152
src/styles/navbar.css Normal file
View File

@ -0,0 +1,152 @@
#menu {
display: flex;
position: fixed;
justify-content: space-between;
align-items: center;
top: 0;
left: 0;
right: 0;
width: inherit;
margin: 0 auto;
overflow: visible;
z-index: 10;
background: var(--bottom-layer);
padding: 8px 16px;
}
#menu::before {
content: "";
position: fixed;
left: 0;
right: 0;
background: var(--bottom-layer);
height: 72px;
z-index: -1;
}
#menu > p > a {
display: flex;
white-space: nowrap;
gap: 10px;
align-items: center;
/* color: var(--text-heading); */
}
#main a {
color: var(--accent-color);
}
#main a:hover {
color: var(--text-heading);
}
#menu > p > a::before {
content: "";
display: flex;
background: url("https://raw.githubusercontent.com/zadam/trilium/master/images/icon-color.svg");
height: 40px;
width: 53px;
}
/* #logo {
order: 1;
height: 40px;
} */
/* #menu > p > strong::before {
content: "";
display: flex;
background: url("https://notes.cloud.zerebos.com/assets/v0.60.4/images/icon-black.svg");
} */
#menu ul, #sidebar ul {
list-style: none;
padding: 0;
position: relative;
}
#menu > ul {
margin: 0;
padding: 0;
display: flex;
gap: 30px;
}
#menu > ul > li {
margin: 0;
padding: 0;
position: relative;
}
#menu > ul > li > p > a {
display: flex;
gap: 10px;
align-items: center;
font-weight: 700;
padding: 16px 0;
}
/* #menu > ul > li > p > a::after {
content: '';
border: 4px solid transparent;
border-top: 4px solid white;
display: flex;
align-items: center;
margin-bottom: -8px;
} */
#menu > ul > li.submenu-item > p > a::after {
content: "";
border-color: currentcolor #0000;
border-style: solid;
border-width: .4em .4em 0;
position: relative;
display: flex;
top: 2px;
align-items: center;
/* transform: translateY(-50%); */
}
#menu > ul > li.submenu-item.hidden > ul,
#menu > ul > li.submenu-item.hidden > p > a::after{
display: none;
}
#menu > ul > li > ul {
/* display: none; */
opacity: 0;
pointer-events: none;
position: absolute;
top: 40px;
background: #242526;
border-radius: 6px;
min-width: 150px;
right: 50%;
transform: translateX(50%);
padding: 8px;
transition: top 200ms ease, opacity 200ms ease;
}
#menu > ul > li > ul > li a {
display: flex;
border-radius: 6px;
padding: 3px 6px;
transition: background-color 200ms ease;
}
#menu > ul > li > ul > li a:hover {
background: rgba(255,255,255,0.05);
}
#menu > ul > li > ul > li > ul {
display: none;
}
#menu > ul > li:hover > ul {
/* display: flex; */
top: 50px;
opacity: 1;
pointer-events: initial;
}

58
src/styles/sidebar.css Normal file
View File

@ -0,0 +1,58 @@
#sidebar {
flex: var(--pane-size);
height: fit-content;
position: sticky;
top: calc(72px + 1rem);
}
#sidebar, #sidebar ul {
list-style: none;
padding: 0;
margin: 0;
}
#sidebar {
/* padding-right: 20px; */
}
/* #sidebar .title {
text-transform: uppercase;
text-align: center;
letter-spacing: 5px;
color: #777;
font-weight: 700;
border-bottom: 1px solid #777;
} */
#sidebar p {
display: flex;
margin: 0;
}
#sidebar a {
flex: 1;
padding: 6px 6px 6px 12px;
border-radius: 6px;
transition: color 200ms ease, background-color 200ms ease;
}
#sidebar a:hover {
background: rgba(255,255,255,0.05);
}
#sidebar > li > ul > li.submenu-item > p > a {
text-transform: uppercase;
font-weight: 700;
color: #555;
}
#sidebar li > ul {
margin-top: 5px;
}
#sidebar > li > ul.hasSubmenu,
#sidebar > li > ul > li.submenu-item + li.submenu-item {
margin-top: 20px;
}

39
src/styles/toc.css Normal file
View File

@ -0,0 +1,39 @@
#toc {
flex: var(--pane-size);
position: sticky;
top: calc(72px + 1rem);
height: fit-content;
background: var(--top-layer);
margin: 0;
padding: 16px 16px 16px 32px;
border-radius: 6px;
}
#toc, #toc ul {
list-style: none;
}
#toc ul {
padding-left: 16px;
}
#toc li a {
color: var(--text-heading);
transition: color 200ms ease;
}
#toc li a:hover,
#toc li a.active {
color: var(--accent-color);
}
#toc::before {
content: "";
display: block;
position: absolute;
left: 16px;
top: 20px;
width: 2px;
height: calc(100% - 40px);
background: rgba(255, 255, 255, 0.1);
}