Files
kjol/web/kit/General.tsx

120 lines
3.3 KiB
TypeScript

import { For, JSXElement, Show } from "solid-js";
import { A } from "@solidjs/router";
import { Icon } from "./Icons.tsx";
interface PageContainerProps {
children?: JSXElement;
}
export function PageContainer(props: PageContainerProps) {
return <div class="admin-page-container">{props.children}</div>;
}
export function Divider() {
return <hr class="text-neutral-200 mt-1 mb-3"/>;
}
interface CodeBoxProps {
code: string;
class?: string;
}
export function CodeBox(props: CodeBoxProps) {
return (
<div class={"text-xs p-3 bg-neutral-800 text-neutral-100 border border-neutral-700 rounded-default " + (props.class || "")}>
<pre><code>{props.code}</code></pre>
</div>
);
}
interface PageHeaderProps {
text: string;
class?: string;
}
export function PageHeader(props: PageHeaderProps) {
return (
<header class={props.class || ""}>
<div class="mt-1">
<h1 class="text-center text-2xl font-light text-neutral-800 mb-2">{props.text}</h1>
<hr class="text-neutral-200 mb-2"/>
</div>
</header>
);
}
interface PageLinkProps {
href: string;
newTab?: boolean;
class?: string;
children?: JSXElement;
}
export function PageLink(props: PageLinkProps) {
return (
<a
href={props.href}
class={"text-sky-700 hover:text-sky-800 hover:underline hover:decoration-1 " + (props.class || "")}
target={props.newTab ? "_blank" : undefined} rel={props.newTab ? "noopener noreferrer" : undefined}>{props.children}
</a>
);
}
export function Loader() {
return (
<div class="flex items-center justify-center p-8">
<div class="h-8 w-8 border-4 border-sky-700 border-t-transparent rounded-full animate-spin"></div>
</div>
);
}
interface BreadcrumbItem {
url: string;
displayText: string;
}
interface BreadcrumbsProps {
items: BreadcrumbItem[];
}
export function Breadcrumbs(props: BreadcrumbsProps) {
return (
<div class="flex flex-row items-center text-neutral-400 text-xs">
<For each={props.items}>{(crumb, index) => (
index() !== props.items.length - 1
? (
<span class="flex items-center">
<A href={crumb.url} class="text-neutral-500 cursor-pointer no-underline hover:text-neutral-700 hover:underline">{crumb.displayText}</A>
<Icon icon="chevron-right" size={12} class="mx-[0.15rem] opacity-50"/>
</span>
)
: (
<span class="text-neutral-700 font-medium">{crumb.displayText}</span>
)
)}</For>
</div>
);
}
interface ManagerPageHeaderProps {
title: string;
description?: string;
action?: JSXElement;
}
export function ManagerPageHeader(props: ManagerPageHeaderProps) {
return (
<div class="page-header">
<div>
<h2 class="page-title">{props.title}</h2>
<Show when={props.description}>
<p class="page-desc">{props.description}</p>
</Show>
</div>
<Show when={props.action}>
{props.action}
</Show>
</div>
);
}