feat: in-heading testing

This commit is contained in:
TrèsAbhi committed 2026-03-18 20:43:41 -05:00
1 parent 8ad110f73b
commit 841b5708ae
5 files changed
+89 -25

No files matched your search

@@ -2,8 +2,6 @@
import type { CollectionEntry } from "astro:content";
import { api } from "../core/api/dynamic";
import { ApiTester } from "./ApiTester";
import { Code } from "./Code";
import { Heading } from "./Heading";
import { MarkdownCustom } from "./MarkdownCustom";
interface Props {
@@ -25,10 +23,6 @@ const hasSlugs = apiData.id.includes("[");
</style>
<div class="container">
<Heading size="3">
<Code>{apiData.id}</Code>
</Heading>
<ApiTester client:idle {locale} path={apiData.id} />
<MarkdownCustom body={apiData.data.docs ?? strings.api.no_docs} />
@@ -3,9 +3,9 @@
align-items: center;
gap: var(--space-4);
.slug {
.title {
display: flex;
align-items: center;
gap: var(--space-3);
gap: var(--space-2);
}
}
@@ -5,6 +5,8 @@ import {
} from "../../hooks/useLocale";
import { useStrings } from "../../hooks/useStrings";
import { Button } from "../Button";
import { Code } from "../Code";
import { Heading } from "../Heading";
import { Link } from "../Link";
import { TextField } from "../TextField";
import styles from "./index.module.css";
@@ -38,19 +40,36 @@ function Content({ path }: Props) {
return (
<div className={styles.tester}>
{slugs.map((slug) => (
<div className={styles.slug}>
{slug}:{" "}
<TextField
value={values[slug]}
onChange={(event) => {
setValues((state) => ({ ...state, [slug]: event.target.value }));
}}
/>
</div>
))}
<Heading size="3">
<Code className={styles.title}>
{path.split(slugPattern).map((text, index) => {
const slug = slugs[index - 1];
<Link href={href} target="_blank">
return (
<>
{index > 0 && (
<TextField
className={styles.slug}
placeholder={`${slug}`}
monospace
align="center"
autoWidth
onChange={(event) => {
setValues((state) => ({
...state,
[slug]: event.target.value,
}));
}}
/>
)}
<span key={index}>{text}</span>
</>
);
})}
</Code>
</Heading>
<Link underline="never" href={href} target="_blank">
<Button>{strings.api.test}</Button>
</Link>
</div>
@@ -53,8 +53,7 @@
font-size: inherit;
font-weight: medium;
padding: var(--space-3) 0;
padding-left: var(--space-4);
padding: var(--space-3) var(--space-4);
color: var(--gray-12);
@@ -65,5 +64,16 @@
&:focus {
outline: none;
}
&[data-align="center"] {
text-align: center;
}
&[data-align="right"] {
text-align: right;
}
&[data-monospace="true"] {
font-family: var(--font-family-mono);
}
}
}
@@ -1,7 +1,9 @@
import {
forwardRef,
useCallback,
useImperativeHandle,
useRef,
type ChangeEvent,
type ComponentProps,
type ReactNode,
} from "react";
@@ -10,12 +12,40 @@ import "./index.css";
export interface TextFieldProps extends ComponentProps<"input"> {
children?: ReactNode;
align?: "left" | "center" | "right";
monospace?: boolean;
autoWidth?: boolean;
}
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
({ children, className, placeholder, disabled, ...props }, ref) => {
(
{
children,
className,
monospace,
autoWidth,
placeholder,
align,
disabled,
value,
onChange,
...props
},
ref,
) => {
const input = useRef<HTMLInputElement>(null);
const handleChange = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
if (autoWidth && input.current) {
input.current.style.width = `${event.target.value.length || event.target.placeholder.length}ch`;
}
onChange?.(event);
},
[onChange],
);
useImperativeHandle(ref, () => input.current!, []);
return (
@@ -26,8 +56,19 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
data-disabled={disabled}
>
{children}
<input disabled={disabled} ref={input} placeholder={placeholder} />
<input
data-align={align === "left" ? undefined : align}
data-monospace={monospace}
disabled={disabled}
ref={input}
onChange={handleChange}
placeholder={placeholder}
value={value}
style={{
width: `${value?.toString().length || placeholder?.length || 0}ch`,
}}
/>
</div>
);
}
},
);