mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: in-heading testing
This commit is contained in:
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>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user