perf(explorer): client side explorer (#1810)

* start work on client side explorer

* fix tests

* fmt

* generic test flag

* add prenav hook

* add highlight class

* make flex more consistent, remove transition

* open folders that are prefixes of current path

* make mobile look nice

* more style fixes
This commit is contained in:
Jacky Zhao
2025-03-09 14:58:26 -07:00
committed by GitHub
parent a201105442
commit 5480269d38
24 changed files with 797 additions and 674 deletions

View File

@ -16,10 +16,10 @@
box-sizing: border-box;
position: sticky;
background-color: var(--light);
padding: 1rem 0 1rem 0;
margin: 0;
}
// Hide Explorer on mobile until done loading.
// Prevents ugly animation on page load.
.hide-until-loaded ~ #explorer-content {
display: none;
}
@ -28,9 +28,21 @@
.explorer {
display: flex;
height: 100%;
flex-direction: column;
overflow-y: hidden;
flex: 0 1 auto;
&.collapsed {
flex: 0 1 1.2rem;
& .fold {
transform: rotateZ(-90deg);
}
}
& .fold {
margin-left: 0.5rem;
transition: transform 0.3s ease;
opacity: 0.8;
}
@media all and ($mobile) {
order: -1;
@ -64,18 +76,14 @@
}
}
/*&:after {
pointer-events: none;
content: "";
width: 100%;
height: 50px;
position: absolute;
left: 0;
bottom: 0;
opacity: 1;
transition: opacity 0.3s ease;
background: linear-gradient(transparent 0px, var(--light));
}*/
svg {
pointer-events: all;
transition: transform 0.35s ease;
& > polyline {
pointer-events: none;
}
}
}
button#mobile-explorer,
@ -94,77 +102,46 @@ button#desktop-explorer {
display: inline-block;
margin: 0;
}
& .fold {
margin-left: 0.5rem;
transition: transform 0.3s ease;
opacity: 0.8;
}
&.collapsed .fold {
transform: rotateZ(-90deg);
}
}
.folder-outer {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease-in-out;
}
.folder-outer.open {
grid-template-rows: 1fr;
}
.folder-outer > ul {
overflow: hidden;
}
#explorer-content {
list-style: none;
overflow: hidden;
overflow-y: auto;
max-height: 0px;
transition:
max-height 0.35s ease,
visibility 0s linear 0.35s;
margin-top: 0.5rem;
visibility: hidden;
&.collapsed {
max-height: 100%;
transition:
max-height 0.35s ease,
visibility 0s linear 0s;
visibility: visible;
}
& ul {
list-style: none;
margin: 0.08rem 0;
margin: 0;
padding: 0;
transition:
max-height 0.35s ease,
transform 0.35s ease,
opacity 0.2s ease;
& li > a {
color: var(--dark);
opacity: 0.75;
pointer-events: all;
&.active {
opacity: 1;
color: var(--tertiary);
}
}
}
> #explorer-ul {
max-height: none;
.folder-outer {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease-in-out;
}
}
svg {
pointer-events: all;
.folder-outer.open {
grid-template-rows: 1fr;
}
& > polyline {
pointer-events: none;
.folder-outer > ul {
overflow: hidden;
margin-left: 6px;
padding-left: 0.8rem;
border-left: 1px solid var(--lightgray);
}
}
@ -227,69 +204,54 @@ li:has(> .folder-outer:not(.open)) > .folder-container > svg {
color: var(--tertiary);
}
.no-background::after {
background: none !important;
}
#explorer-end {
// needs height so IntersectionObserver gets triggered
height: 4px;
// remove default margin from li
margin: 0;
}
.explorer {
@media all and ($mobile) {
#explorer-content {
box-sizing: border-box;
overscroll-behavior: none;
z-index: 100;
position: absolute;
top: 0;
background-color: var(--light);
max-width: 100dvw;
left: -100dvw;
width: 100%;
transition: transform 300ms ease-in-out;
overflow: hidden;
padding: $topSpacing 2rem 2rem;
height: 100dvh;
max-height: 100dvh;
margin-top: 0;
visibility: hidden;
&.collapsed {
flex: 0 0 34px;
&:not(.collapsed) {
transform: translateX(100dvw);
visibility: visible;
& > #explorer-content {
transform: translateX(-100vw);
visibility: hidden;
}
}
ul.overflow {
max-height: 100%;
width: 100%;
}
&:not(.collapsed) {
flex: 0 0 34px;
&.collapsed {
& > #explorer-content {
transform: translateX(0);
visibility: visible;
}
}
#mobile-explorer {
margin: 5px;
z-index: 101;
#explorer-content {
box-sizing: border-box;
z-index: 100;
position: absolute;
top: 0;
left: 0;
margin-top: 0;
background-color: var(--light);
max-width: 100vw;
width: 100%;
transform: translateX(-100vw);
transition:
transform 200ms ease,
visibility 200ms ease;
overflow: hidden;
padding: 4rem 0 2rem 0;
height: 100dvh;
max-height: 100dvh;
visibility: hidden;
}
&:not(.collapsed) .lucide-menu {
transform: rotate(-90deg);
transition: transform 200ms ease-in-out;
}
#mobile-explorer {
margin: 0;
padding: 5px;
z-index: 101;
.lucide-menu {
stroke: var(--darkgray);
transition: transform 200ms ease;
&:hover {
stroke: var(--dark);
}
}
}
}