feat: zooweemama

This commit is contained in:
TrèsAbhi committed 2026-03-19 13:26:34 -05:00
1 parent 841b5708ae
commit 824169fc25
7 files changed
+97 -26

No files matched your search

@@ -0,0 +1,58 @@
---
import ApiMacroSee from "./ApiMacroSee.astro";
import { MarkdownCustom } from "./MarkdownCustom";
interface Props {
body: string;
}
const macroPattern = /@(\w+) (.+)/;
const macros: Record<string, string> = {};
const { body: bodyOriginal } = Astro.props;
let body = "";
for (const line of bodyOriginal.split("\n")) {
const match = line.match(macroPattern);
if (match === null) {
body += `${line}\n`;
continue;
}
const macro = match[1];
const value = match[2];
macros[macro] = value;
}
---
<style>
.api-description {
display: flex;
.gutter {
width: var(--space-2);
background: linear-gradient(transparent, var(--gray-6) var(--space-4));
margin: 0 var(--space-4);
}
.content {
display: flex;
flex-direction: column;
gap: var(--space-4);
padding-top: var(--space-4);
padding-bottom: var(--space-3);
}
}
</style>
<div class="api-description">
<div class="gutter"></div>
<div class="content">
<MarkdownCustom {body} />
{"see" in macros && <ApiMacroSee value={macros.see} />}
</div>
</div>
@@ -1,8 +1,8 @@
---
import type { CollectionEntry } from "astro:content";
import { api } from "../core/api/dynamic";
import ApiDescription from "./ApiDescription.astro";
import { ApiTester } from "./ApiTester";
import { MarkdownCustom } from "./MarkdownCustom";
interface Props {
locale: string;
@@ -11,19 +11,17 @@ interface Props {
const { locale, api: apiData } = Astro.props;
const strings = await api.strings(locale);
const hasSlugs = apiData.id.includes("[");
const body = apiData.data.docs ?? strings.api.no_docs;
---
<style>
.container {
display: flex;
flex-direction: column;
gap: var(--space-4);
}
</style>
<div class="container">
<ApiTester client:idle {locale} path={apiData.id} />
<MarkdownCustom body={apiData.data.docs ?? strings.api.no_docs} />
<ApiDescription {body} />
</div>
@@ -0,0 +1,21 @@
---
import { Link } from "./Link";
import { Text } from "./Text";
interface Props {
value: string;
}
const bodyPattern = /^([a-z0-9-\/\.]+) (.+)$/;
const { value } = Astro.props;
const match = value.match(bodyPattern);
if (match === null) {
throw new Error(`Invalid value for ApiMacroSee: ${value}`);
}
const path = match[1];
const message = match[2];
---
<Text><Text color="tomato">See</Text> <Link>{path}</Link> {message}</Text>
@@ -1,4 +1,5 @@
import { useState } from "react";
import { PlayIcon } from "@radix-ui/react-icons";
import { Fragment, useState } from "react";
import {
LocaleProvider,
type LocaleAcceptorProps,
@@ -6,8 +7,8 @@ import {
import { useStrings } from "../../hooks/useStrings";
import { Button } from "../Button";
import { Code } from "../Code";
import { Heading } from "../Heading";
import { Link } from "../Link";
import { Text } from "../Text";
import { TextField } from "../TextField";
import styles from "./index.module.css";
@@ -40,18 +41,17 @@ function Content({ path }: Props) {
return (
<div className={styles.tester}>
<Heading size="3">
<Text weight="medium">
<Code className={styles.title}>
{path.split(slugPattern).map((text, index) => {
const slug = slugs[index - 1];
return (
<>
<Fragment key={index}>
{index > 0 && (
<TextField
className={styles.slug}
placeholder={`${slug}`}
monospace
placeholder={`[${slug}]`}
align="center"
autoWidth
onChange={(event) => {
@@ -63,14 +63,16 @@ function Content({ path }: Props) {
/>
)}
<span key={index}>{text}</span>
</>
</Fragment>
);
})}
</Code>
</Heading>
</Text>
<Link underline="never" href={href} target="_blank">
<Button>{strings.api.test}</Button>
<Button>
{strings.api.test} <PlayIcon />
</Button>
</Link>
</div>
);
@@ -11,7 +11,7 @@
box-shadow: var(--shadow-interactive), var(--shadow-cavity);
cursor: text;
font-size: var(--font-size-regular);
font: inherit;
color: var(--gray-11);
&[data-has-icon="true"] {
@@ -51,8 +51,7 @@
border: none;
cursor: inherit;
font-size: inherit;
font-weight: medium;
font: inherit;
padding: var(--space-3) var(--space-4);
color: var(--gray-12);
@@ -71,9 +70,5 @@
&[data-align="right"] {
text-align: right;
}
&[data-monospace="true"] {
font-family: var(--font-family-mono);
}
}
}
@@ -13,7 +13,6 @@ import "./index.css";
export interface TextFieldProps extends ComponentProps<"input"> {
children?: ReactNode;
align?: "left" | "center" | "right";
monospace?: boolean;
autoWidth?: boolean;
}
@@ -22,7 +21,6 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
{
children,
className,
monospace,
autoWidth,
placeholder,
align,
@@ -58,7 +56,6 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
{children}
<input
data-align={align === "left" ? undefined : align}
data-monospace={monospace}
disabled={disabled}
ref={input}
onChange={handleChange}
@@ -10,9 +10,9 @@ export const getStaticPaths = (async () => {
}) satisfies GetStaticPaths;
/**
* Returns data on an avatar based on its id. @see avatars/list.json for a list
* of all avatar ids.
* Returns data on an avatar based on its `id`.
*
* @see avatars/list.json for all avatar ids.
* @type avatar
*/
export async function GET({ params }: APIContext<never, { id: string }>) {