initial commit

This commit is contained in:
Xanazf 2024-09-28 02:35:19 +03:00
commit 3c2fb32b3e
73 changed files with 22349 additions and 0 deletions

View file

@ -0,0 +1,7 @@
---
import SearchComponent from "./search";
---
<div class="search-wrapper">
<SearchComponent client:only={"solid-js"}/>
</div>

View file

@ -0,0 +1,53 @@
import { For, type Component } from "solid-js";
import type { SearchResult } from "./types";
import {
getIconForLink,
getQMLTypeLink,
getQMLTypeLinkObject,
} from "@src/config/io/helpers";
const SearchModal: Component<{
results: SearchResult[];
}> = props => {
const { results } = props;
const linkRegex = /TYPE99(\w+.)99TYPE/g;
return (
<div
id="search-modal"
class="search-output"
>
<For each={results}>
{result => {
let excerpt = result.excerpt;
const linkMatch = [...excerpt.matchAll(linkRegex)];
for (const match of linkMatch) {
const unparsed = match[1];
const linkObject = getQMLTypeLinkObject(unparsed);
const linkParsed = getQMLTypeLink(linkObject);
const icon = linkObject.mtype
? getIconForLink(linkObject.mtype, false)
: "";
const bracketString = getIconForLink("func", false);
const newString = `<span class="type${linkObject.mtype}-link typedata-link">${icon}<a href=${linkParsed}>${linkObject.mname || linkObject.name}</a>${linkObject.mtype === "signal" ? bracketString : ""}</span>`;
excerpt = excerpt.replace(match[0], newString);
}
excerpt = `${excerpt}...`;
return (
<div class="search-output_item">
<h3 class="search-output_heading">
<a href={result.url}>{result.meta.title}</a>
</h3>
<section
class="search-output_excerpt"
innerHTML={excerpt}
/>
</div>
);
}}
</For>
</div>
);
};
export default SearchModal;

View file

@ -0,0 +1,59 @@
import {
createResource,
createSignal,
type Component,
} from "solid-js";
import type { SearchResult } from "./types";
import SearchModal from "./SearchModal";
const pagefind = await import("@dist/pagefind/pagefind.js");
pagefind.init();
async function PagefindSearch(query: string) {
const search = await pagefind.search(query);
const resultdata: SearchResult[] = [];
for (const result of search.results) {
const data = await result.data();
resultdata.push(data);
}
return resultdata;
}
const SearchComponent: Component = () => {
let modal!: HTMLElement;
const [query, setQuery] = createSignal("");
const [results, { refetch }] = createResource(
query,
PagefindSearch
);
function handleSearch(value: string) {
setQuery(value);
refetch();
console.log(results());
}
return (
<div class="search">
<input
id="search-input"
type="text"
role="searchbox"
incremental
value={query()}
placeholder="Search"
onChange={e => handleSearch(e.target.value)}
//onfocusout={() => setQuery("")}
/>{" "}
{!results.loading && results() && results()!.length > 0 ? (
<SearchModal
results={results()!}
ref={modal}
/>
) : null}
</div>
);
};
export default SearchComponent;

View file

@ -0,0 +1,15 @@
interface SearchResult {
url: string;
excerpt: string;
meta: {
title: string;
image?: string;
};
sub_results: {
title: string;
url: string;
excerpt: string;
}[];
}
export type { SearchResult }

View file

@ -0,0 +1,31 @@
---
import { generateTypeData } from "@config/io/generateTypeData";
import { groupRoutes } from "@config/io/helpers";
import NavComponent from "./nav";
const routes = await generateTypeData();
const groupedRoutes = groupRoutes(routes);
const url = Astro.url.pathname.split("/");
const currentRoute = url[2];
const currentModule = url[3];
const currentClass = url[4];
const treeProps = {
items: groupedRoutes,
currentRoute: currentRoute,
currentModule: currentModule,
currentClass: currentClass,
};
const { mobile } = Astro.props;
---
<aside class=`nav-wrapper${mobile ? "-mobile" : ""}`>
<NavComponent
routes={groupedRoutes}
tree={treeProps}
mobile={mobile}
client:idle
/>
</aside>

View file

@ -0,0 +1,21 @@
---
import TableOfContents from "./toc";
import type { ConfigHeading, TypeTOC } from "./types.d.ts";
export interface Props {
headings?: ConfigHeading[];
types?: TypeTOC;
mobile: boolean;
}
const { headings, types, mobile } = Astro.props;
---
<div class=`toc-wrapper${mobile ? "-mobile":""}`>
<TableOfContents
config={headings}
type={types}
mobile={mobile}
client:idle
/>
</div>

View file

@ -0,0 +1,124 @@
import { type Component, Index, For } from "solid-js";
import { Accordion } from "@ark-ui/solid";
import { ShevronSmallDown } from "@icons";
import type { TreeProps } from "../types";
export const Tree: Component<TreeProps> = props => {
const { currentRoute, currentModule, currentClass, items } =
props;
const typeKeys = items!.types && Object.keys(items!.types);
const tutorials =
items!.tutorials && items!.tutorials
? items!.tutorials.configuration
: null;
return (
<nav class="navtree">
<Accordion.Root
defaultValue={
currentRoute === "types" ? ["Types"] : ["Configuration"]
}
collapsible
multiple
>
<Accordion.Item value={"Configuration"}>
<Accordion.ItemTrigger>
<Accordion.ItemIndicator>
<ShevronSmallDown class={"nav-shevron"} />
</Accordion.ItemIndicator>
<p>
<a href={"/docs/configuration"}>Configuration</a>
</p>
</Accordion.ItemTrigger>
<Accordion.ItemContent>
<For each={tutorials}>
{item => (
<div
class={`arktree-item ${currentModule === item.type ? "__current-type-doc" : ""}`}
>
<a href={`/docs/configuration/${item.type}`}>
{item.name}
</a>
</div>
)}
</For>
</Accordion.ItemContent>
</Accordion.Item>
<Accordion.Item value={"Types"}>
<Accordion.ItemTrigger>
<Accordion.ItemIndicator>
<ShevronSmallDown class={"nav-shevron"} />
</Accordion.ItemIndicator>
<p>
<a href={"/docs/types"}>Type Definitions</a>
</p>
</Accordion.ItemTrigger>
<Accordion.ItemContent>
<Index each={typeKeys}>
{typeKey => {
return (
<Accordion.Root
defaultValue={
currentModule === typeKey()
? [typeKey()]
: [""]
}
multiple
collapsible
>
<Accordion.Item
value={typeKey()}
id={typeKey()}
class={
typeKey() === currentModule
? "__current-type-doc"
: ""
}
>
<Accordion.ItemTrigger
id={`${typeKey()}:button`}
>
<Accordion.ItemIndicator>
<ShevronSmallDown
class={"nav-shevron"}
/>
</Accordion.ItemIndicator>
<p>
<a href={`/docs/types/${typeKey()}`}>
{typeKey()}
</a>
</p>
</Accordion.ItemTrigger>
<Accordion.ItemContent>
<For each={items!.types[typeKey()]}>
{submodule => (
<div
class={
currentClass === submodule.name
? "__current-type-doc"
: ""
}
>
<a
href={`/docs/types/${submodule.type}/${submodule.name}`}
>
{submodule.name}
</a>
</div>
)}
</For>
</Accordion.ItemContent>
</Accordion.Item>
</Accordion.Root>
);
}}
</Index>
</Accordion.ItemContent>
</Accordion.Item>
</Accordion.Root>
</nav>
);
};

View file

@ -0,0 +1,52 @@
import { createSignal, type Component } from "solid-js";
import { LoadingSpinner, MenuToX, XToMenu } from "@icons";
import { Tree } from "./Tree";
import type { NavProps } from "../types";
const NavComponent: Component<NavProps> = props => {
const [open, setOpen] = createSignal<boolean>(false);
const { tree, mobile, routes } = props;
if (!tree) {
return <LoadingSpinner />;
}
function toggle(e: MouseEvent) {
e.preventDefault();
setOpen(!open());
}
if (!mobile) {
return (
<Tree
currentRoute={tree.currentRoute}
currentModule={tree.currentModule || null}
currentClass={tree.currentClass || null}
items={routes}
/>
);
}
return (
<div class="nav-toggle">
<div onclick={e => toggle(e)}>
{open() ? (
<MenuToX class="nav-icon" />
) : (
<XToMenu class="nav-icon" />
)}
</div>
<div class={`nav-items ${open() ? "shown" : ""}`}>
<Tree
currentRoute={tree.currentRoute}
currentModule={tree.currentModule}
currentClass={tree.currentClass}
items={routes}
/>
</div>
</div>
);
};
export default NavComponent;

View file

@ -0,0 +1,33 @@
import { For, type Component } from "solid-js";
import type { ConfigTOC } from "../types";
export const Heading: Component<{
heading: ConfigTOC;
index: number;
}> = props => {
const { heading, index } = props;
return (
<li class={`toc_heading toc_heading-${index}`}>
<a
class="toc_a"
href={`#${heading.slug}`}
>
{heading.text}
</a>
{heading.subheadings.length > 0 && (
<ul>
<For each={heading.subheadings}>
{subheading => (
<Heading
heading={subheading}
index={subheading.depth}
/>
)}
</For>
</ul>
)}
</li>
);
};

View file

@ -0,0 +1,111 @@
import { type Component, For } from "solid-js";
import type { TypeTOC, ConfigTOC } from "../types";
import {
LoadingSpinner,
Tag,
RoundBrackets,
PowerCord,
FourDiamonds,
} from "@icons";
import { Heading } from "./Heading";
export const Table: Component<{
typeTOC?: TypeTOC;
configTOC?: ConfigTOC[];
}> = props => {
const { typeTOC, configTOC } = props;
if (configTOC) {
return (
<div class="toc-content">
<p>Contents</p>
<For each={configTOC}>
{heading => (
<Heading
heading={heading}
index={0}
/>
)}
</For>
</div>
);
}
if (!typeTOC) {
return <LoadingSpinner />;
}
return (
<nav class="toc-content">
{typeTOC.properties ? (
<ul class="types-list props-list">
<For each={typeTOC.properties}>
{prop => (
<li class="types-item props-item">
<Tag />
<a
class="type-anchor"
href={`#${prop}`}
>
{prop}
</a>
</li>
)}
</For>
</ul>
) : null}
{typeTOC.functions ? (
<ul class="types-list funcs-list">
<For each={typeTOC.functions}>
{func => (
<li class="types-item func-item">
<RoundBrackets />
<a
class="type-anchor"
href={`#${func}`}
>
{func}
</a>
</li>
)}
</For>
</ul>
) : null}
{typeTOC.signals ? (
<ul class="types-list signals-list">
<For each={typeTOC.signals}>
{signal => (
<li class="types-item signals-item">
<PowerCord />
<a
class="type-anchor"
href={`#${signal}`}
>
{signal}
</a>
</li>
)}
</For>
</ul>
) : null}
{typeTOC.variants ? (
<ul class="types-list vars-list">
<For each={typeTOC.variants}>
{variant => (
<li class="types-item vars-item">
<FourDiamonds />
<a
class="type-anchor"
href={`#${variant}`}
>
{variant}
</a>
</li>
)}
</For>
</ul>
) : null}
</nav>
);
};

View file

@ -0,0 +1,52 @@
import { createSignal, type Component } from "solid-js";
import { Article } from "@icons";
import { Table } from "./Table";
import type {
TOCProps,
TypeTOC,
ConfigHeading,
} from "../types";
import { buildHierarchy } from "@config/io/helpers";
const TableOfContents: Component<TOCProps> = props => {
const [open, setOpen] = createSignal<boolean>(false);
const [typeProps] = createSignal<TypeTOC | undefined>(
props.type
);
const [configProps] = createSignal<
ConfigHeading[] | undefined
>(props.config);
function toggle(e: MouseEvent) {
e.preventDefault();
setOpen(!open());
}
if (!props.mobile) {
return typeProps() ? (
<Table typeTOC={typeProps()} />
) : (
<Table configTOC={buildHierarchy(configProps()!)} />
);
}
return (
<div class="menu-toggle">
<div onclick={e => toggle(e)}>
<Article />
</div>
<div class={`menu-items ${open() ? "shown" : ""}`}>
{typeProps() ? (
<Table typeTOC={typeProps()} />
) : (
<Table
configTOC={buildHierarchy(configProps()!)}
/>
)}
</div>
</div>
);
};
export default TableOfContents;

View file

@ -0,0 +1,41 @@
import { createSignal, type Component } from "solid-js";
import { Article } from "@icons";
import { Table } from "./Table";
import type { TOCProps } from "../types";
import { buildHierarchy } from "@config/io/helpers";
const TableOfContents: Component<TOCProps> = props => {
const [open, setOpen] = createSignal<boolean>(false);
const { mobile, config, type } = props;
function toggle(e: MouseEvent) {
e.preventDefault();
setOpen(!open());
}
if (!mobile) {
return type ? (
<Table typeTOC={type} />
) : (
<Table configTOC={buildHierarchy(config!)} />
);
}
return (
<div class="toc-toggle">
<div onclick={e => toggle(e)}>
<Article />
</div>
<div class={`toc-mobile ${open() ? "shown" : ""}`}>
{type ? (
<Table typeTOC={type} />
) : (
<Table configTOC={buildHierarchy(config!)} />
)}
</div>
</div>
);
};
export default TableOfContents;

View file

@ -0,0 +1,63 @@
// Left
export interface Item {
name: string;
type: string;
}
export interface GroupedRoutes {
tutorials: { [key: string]: Item[] };
types: { [key: string]: Item[] };
}
export interface TreeProps {
items: GroupedRoutes;
currentRoute?: string;
currentModule: string | null;
currentClass: string | null;
}
export interface NavProps {
routes: GroupedRoutes;
tree: TreeProps;
mobile: boolean;
}
// Right
export interface TOCProps {
config?: ConfigHeading[];
type?: TypeTableProps;
mobile: boolean;
}
// -- Config
export interface ConfigHeading {
slug: string;
text: string;
depth: number;
}
export interface ConfigTOC {
slug: string;
text: string;
depth: number;
subheadings: ConfigTOC[];
}
export interface ConfigTableProps {
content: {
title: string;
};
headings: ConfigHeading[];
frontmatter?: {
title: string;
description: string;
};
}
// -- Types
export interface TypeTOC {
properties: string[] | null;
functions: string[] | null;
signals: string[] | null;
variants: string[] | null;
}