added click outside sidebars handling, fixed some spacing issues
This commit is contained in:
		
							parent
							
								
									0df624df40
								
							
						
					
					
						commit
						119c8a2e6c
					
				
					 7 changed files with 132 additions and 52 deletions
				
			
		| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { createSignal, type Component } from "solid-js";
 | 
			
		||||
import { createSignal, onMount, type Component } from "solid-js";
 | 
			
		||||
 | 
			
		||||
import { LoadingSpinner, MenuToX, XToMenu } from "@icons";
 | 
			
		||||
import { Tree } from "./Tree";
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import type { NavProps } from "../types";
 | 
			
		|||
const NavComponent: Component<NavProps> = props => {
 | 
			
		||||
  const [open, setOpen] = createSignal<boolean>(false);
 | 
			
		||||
  const { tree, mobile, routes } = props;
 | 
			
		||||
  let navRef: HTMLDivElement;
 | 
			
		||||
 | 
			
		||||
  if (!tree) {
 | 
			
		||||
    return <LoadingSpinner />;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,8 +29,29 @@ const NavComponent: Component<NavProps> = props => {
 | 
			
		|||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const handleClickOutside = (event: MouseEvent) => {
 | 
			
		||||
    const isLink = "href" in (event.target || {});
 | 
			
		||||
    if (
 | 
			
		||||
      isLink ||
 | 
			
		||||
      (document.body.contains(event.target as Node) &&
 | 
			
		||||
        !navRef.contains(event.target as Node))
 | 
			
		||||
    ) {
 | 
			
		||||
      setOpen(false);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  onMount(() => {
 | 
			
		||||
    window.addEventListener("click", handleClickOutside);
 | 
			
		||||
    return () => {
 | 
			
		||||
      window.removeEventListener("click", handleClickOutside);
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div class="nav-toggle">
 | 
			
		||||
    <div
 | 
			
		||||
      class="nav-toggle"
 | 
			
		||||
      ref={navRef!}
 | 
			
		||||
    >
 | 
			
		||||
      <div onclick={e => toggle(e)}>
 | 
			
		||||
        {open() ? (
 | 
			
		||||
          <MenuToX class="nav-icon" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { createSignal, type Component } from "solid-js";
 | 
			
		||||
import { createSignal, onMount, type Component } from "solid-js";
 | 
			
		||||
 | 
			
		||||
import { Article } from "@icons";
 | 
			
		||||
import { Table } from "./Table";
 | 
			
		||||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import { buildHierarchy } from "@config/io/helpers";
 | 
			
		|||
const TableOfContents: Component<TOCProps> = props => {
 | 
			
		||||
  const [open, setOpen] = createSignal<boolean>(false);
 | 
			
		||||
  const { mobile, config, type } = props;
 | 
			
		||||
  let tocRef: HTMLDivElement;
 | 
			
		||||
 | 
			
		||||
  function toggle(e: MouseEvent) {
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
| 
						 | 
				
			
			@ -21,9 +22,29 @@ const TableOfContents: Component<TOCProps> = props => {
 | 
			
		|||
      <Table configTOC={buildHierarchy(config!)} />
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  const handleClickOutside = (event: MouseEvent) => {
 | 
			
		||||
    const isLink = "href" in (event.target || {});
 | 
			
		||||
    if (
 | 
			
		||||
      isLink ||
 | 
			
		||||
      (document.body.contains(event.target as Node) &&
 | 
			
		||||
        !tocRef.contains(event.target as Node))
 | 
			
		||||
    ) {
 | 
			
		||||
      setOpen(false);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  onMount(() => {
 | 
			
		||||
    window.addEventListener("click", handleClickOutside);
 | 
			
		||||
    return () => {
 | 
			
		||||
      window.removeEventListener("click", handleClickOutside);
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div class="toc-toggle">
 | 
			
		||||
    <div
 | 
			
		||||
      class="toc-toggle"
 | 
			
		||||
      ref={tocRef!}
 | 
			
		||||
    >
 | 
			
		||||
      <div onclick={e => toggle(e)}>
 | 
			
		||||
        <Article />
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
  border-radius: 6px;
 | 
			
		||||
  border: 1px solid hsla(var(--blue) 10 15 / 0.6);
 | 
			
		||||
  margin-top: 1rem;
 | 
			
		||||
  margin-inline: 1.272rem;
 | 
			
		||||
 | 
			
		||||
  & .root-nav-entry {
 | 
			
		||||
    position: relative;
 | 
			
		||||
| 
						 | 
				
			
			@ -33,10 +34,12 @@
 | 
			
		|||
        left: 0;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 1px;
 | 
			
		||||
        background: linear-gradient(90deg,
 | 
			
		||||
            transparent 25%,
 | 
			
		||||
            hsla(var(--accent-500) / 0.88) 50%,
 | 
			
		||||
            transparent 75%);
 | 
			
		||||
        background: linear-gradient(
 | 
			
		||||
          90deg,
 | 
			
		||||
          transparent 25%,
 | 
			
		||||
          hsla(var(--accent-500) / 0.88) 50%,
 | 
			
		||||
          transparent 75%
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +63,7 @@
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#injectedMd {
 | 
			
		||||
  &>p:not(:first-child) {
 | 
			
		||||
  & > p:not(:first-child) {
 | 
			
		||||
    margin-block: 0.724rem;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +77,7 @@
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.typedocs-content {
 | 
			
		||||
  &>p {
 | 
			
		||||
  & > p {
 | 
			
		||||
    margin-block: 0.618rem;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +105,7 @@
 | 
			
		|||
    padding: 1.272rem;
 | 
			
		||||
    transition: border 0.3s;
 | 
			
		||||
 | 
			
		||||
    &>.typedata-name {
 | 
			
		||||
    & > .typedata-name {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      font-size: 1.272rem;
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +141,7 @@
 | 
			
		|||
 | 
			
		||||
  & .typedata-detailsdata,
 | 
			
		||||
  .typedocs-subheading {
 | 
			
		||||
    &>p {
 | 
			
		||||
    & > p {
 | 
			
		||||
      margin-top: 0.618rem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +201,7 @@
 | 
			
		|||
  width: max-content;
 | 
			
		||||
  transition: opacity 0.5s;
 | 
			
		||||
 | 
			
		||||
  &>a {
 | 
			
		||||
  & > a {
 | 
			
		||||
    opacity: inherit;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +268,7 @@ html.dark .typeprops {
 | 
			
		|||
        align-items: center;
 | 
			
		||||
        gap: 0.117rem;
 | 
			
		||||
 | 
			
		||||
        &>svg {
 | 
			
		||||
        & > svg {
 | 
			
		||||
          height: 1.272rem;
 | 
			
		||||
          width: 1.272rem;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +320,7 @@ html.dark .typefuncs {
 | 
			
		|||
        align-items: center;
 | 
			
		||||
        gap: 0.117rem;
 | 
			
		||||
 | 
			
		||||
        &>svg {
 | 
			
		||||
        & > svg {
 | 
			
		||||
          height: 1.272rem;
 | 
			
		||||
          width: 1.272rem;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -386,9 +389,11 @@ html.dark .typevariants {
 | 
			
		|||
 | 
			
		||||
        &::before {
 | 
			
		||||
          width: 0;
 | 
			
		||||
          background: linear-gradient(to right,
 | 
			
		||||
              hsla(var(--accent-400) / 0.5) var(--percent),
 | 
			
		||||
              hsla(var(--accent-400) / 0) 100%);
 | 
			
		||||
          background: linear-gradient(
 | 
			
		||||
            to right,
 | 
			
		||||
            hsla(var(--accent-400) / 0.5) var(--percent),
 | 
			
		||||
            hsla(var(--accent-400) / 0) 100%
 | 
			
		||||
          );
 | 
			
		||||
          animation: percentToZero 250ms ease-in-out forwards;
 | 
			
		||||
          transition: width 0.25s ease-in-out;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -419,7 +424,7 @@ html.dark .typevariants {
 | 
			
		|||
      min-width: 30svw;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &>p {
 | 
			
		||||
    & > p {
 | 
			
		||||
      margin-block: 1.217rem;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.heading {
 | 
			
		||||
  &>[id] {
 | 
			
		||||
  & > [id] {
 | 
			
		||||
    width: max-content;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ ul {
 | 
			
		|||
.markdown-alert {
 | 
			
		||||
  margin-block: 0.618rem;
 | 
			
		||||
 | 
			
		||||
  &>*:not(:first-child) {
 | 
			
		||||
  & > *:not(:first-child) {
 | 
			
		||||
    margin-block: 0.724rem;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +83,7 @@ ul {
 | 
			
		|||
.markdown-alert-title {
 | 
			
		||||
  text-transform: lowercase;
 | 
			
		||||
  text-transform: capitalize;
 | 
			
		||||
  margin-block: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width: 65rem) {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,17 +111,16 @@ ul {
 | 
			
		|||
    flex-direction: row;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .docslayout-inner {
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
    max-width: 80rem;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .docs {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .docs-content {
 | 
			
		||||
    & section {
 | 
			
		||||
      max-width: 45svw;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .docslayout-inner {
 | 
			
		||||
    min-width: 33.8rem;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
  max-height: 500px;
 | 
			
		||||
  scrollbar-width: none;
 | 
			
		||||
  -ms-overflow-style: none;
 | 
			
		||||
  --width: 30rem;
 | 
			
		||||
 | 
			
		||||
  &::-webkit-scrollbar {
 | 
			
		||||
    display: none;
 | 
			
		||||
| 
						 | 
				
			
			@ -45,14 +46,15 @@
 | 
			
		|||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    transition: width 0.3s ease,
 | 
			
		||||
    height 0.3s ease,
 | 
			
		||||
    background-color 0.3s ease,
 | 
			
		||||
    backdrop-filter 0.3s ease,
 | 
			
		||||
    padding 0.3s ease;
 | 
			
		||||
    transition:
 | 
			
		||||
      width 0.3s ease,
 | 
			
		||||
      height 0.3s ease,
 | 
			
		||||
      background-color 0.3s ease,
 | 
			
		||||
      backdrop-filter 0.3s ease,
 | 
			
		||||
      padding 0.3s ease;
 | 
			
		||||
 | 
			
		||||
    &.shown {
 | 
			
		||||
      width: 100svw;
 | 
			
		||||
      width: var(--width);
 | 
			
		||||
      background-color: hsl(var(--bg-900) / 0.6);
 | 
			
		||||
      backdrop-filter: blur(3px) saturate(180%);
 | 
			
		||||
      display: flex;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +97,7 @@
 | 
			
		|||
            max-width: 70%;
 | 
			
		||||
            margin-left: 3.33em;
 | 
			
		||||
 | 
			
		||||
            &>div {
 | 
			
		||||
            & > div {
 | 
			
		||||
              min-height: 4em;
 | 
			
		||||
              display: grid;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +115,18 @@
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 55rem) {
 | 
			
		||||
  .nav-toggle {
 | 
			
		||||
    --width: 45svw;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 38rem) {
 | 
			
		||||
  .nav-toggle {
 | 
			
		||||
    --width: 100svw;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width: 85rem) {
 | 
			
		||||
  .nav-wrapper-mobile {
 | 
			
		||||
    display: none;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@
 | 
			
		|||
  font-size: 1.614rem;
 | 
			
		||||
  max-height: 500px;
 | 
			
		||||
 | 
			
		||||
  &>svg {
 | 
			
		||||
  & > svg {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    width: 24px;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +54,7 @@
 | 
			
		|||
    top: 2.6rem;
 | 
			
		||||
    right: -1rem;
 | 
			
		||||
    width: 0;
 | 
			
		||||
    height: 0;
 | 
			
		||||
    height: max(min(100svh, 800px), calc(100svh - 8rem));
 | 
			
		||||
    font-size: 0.745rem;
 | 
			
		||||
    font-weight: 600;
 | 
			
		||||
    scrollbar-width: none;
 | 
			
		||||
| 
						 | 
				
			
			@ -64,11 +64,12 @@
 | 
			
		|||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    transition: width 0.3s ease,
 | 
			
		||||
    height 0.3s ease,
 | 
			
		||||
    background-color 0.3s ease,
 | 
			
		||||
    backdrop-filter 0.3s ease,
 | 
			
		||||
    padding 0.3s ease;
 | 
			
		||||
    transition:
 | 
			
		||||
      width 0.3s ease,
 | 
			
		||||
      height 0.3s ease,
 | 
			
		||||
      background-color 0.3s ease,
 | 
			
		||||
      backdrop-filter 0.3s ease,
 | 
			
		||||
      padding 0.3s ease;
 | 
			
		||||
 | 
			
		||||
    &.shown {
 | 
			
		||||
      overflow-y: scroll;
 | 
			
		||||
| 
						 | 
				
			
			@ -84,16 +85,23 @@
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width: 65rem) {
 | 
			
		||||
@media (max-width: 55rem) {
 | 
			
		||||
  .toc-toggle {
 | 
			
		||||
    --width: 25svw;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .toc-wrapper {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width: 65rem) {
 | 
			
		||||
  .toc-wrapper-mobile {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .toc-wrapper {
 | 
			
		||||
    --width: 25svw;
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
    display: block;
 | 
			
		||||
    position: sticky;
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +125,7 @@
 | 
			
		|||
      list-style: none;
 | 
			
		||||
 | 
			
		||||
      &.active {
 | 
			
		||||
        &>.toc_a {
 | 
			
		||||
        & > .toc_a {
 | 
			
		||||
          color: hsl(var(--green) 72 60);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -133,3 +141,9 @@
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width: 85rem) {
 | 
			
		||||
  .toc-wrapper {
 | 
			
		||||
    width: max-content;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,11 +122,13 @@ footer {
 | 
			
		|||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  padding-inline: 1rem;
 | 
			
		||||
  background: linear-gradient(150deg,
 | 
			
		||||
      hsla(var(--blue) 60 5 / 1) 10%,
 | 
			
		||||
      hsla(var(--blue) 75 6 / 1) 25%,
 | 
			
		||||
      hsla(var(--blue) 80 8 / 1) 55%,
 | 
			
		||||
      hsla(var(--blue) 77 7 / 1) 80%);
 | 
			
		||||
  background: linear-gradient(
 | 
			
		||||
    150deg,
 | 
			
		||||
    hsla(var(--blue) 60 5 / 1) 10%,
 | 
			
		||||
    hsla(var(--blue) 75 6 / 1) 25%,
 | 
			
		||||
    hsla(var(--blue) 80 8 / 1) 55%,
 | 
			
		||||
    hsla(var(--blue) 77 7 / 1) 80%
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  & ._credits {
 | 
			
		||||
    display: flex;
 | 
			
		||||
| 
						 | 
				
			
			@ -184,6 +186,12 @@ footer {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width: 65rem) {
 | 
			
		||||
  .search {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width: 85rem) {
 | 
			
		||||
  html {
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
| 
						 | 
				
			
			@ -202,10 +210,6 @@ footer {
 | 
			
		|||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .search {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .spacer-desktop {
 | 
			
		||||
    display: block;
 | 
			
		||||
    font-size: 1.374rem;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue