chore(repo): reinitialize repository

This commit is contained in:
2026-03-18 11:29:54 +08:00
commit 24871e213a
288 changed files with 44369 additions and 0 deletions
@@ -0,0 +1,71 @@
import type { FormEvent, ReactNode, Ref } from "react";
import Button from "./Button";
import InsetPanel from "./InsetPanel";
import TextInput from "./TextInput";
import { cx } from "./cx";
interface InlineComposerProps {
label: ReactNode;
value: string;
onChange: (value: string) => void;
onSubmit: () => void;
placeholder?: string;
hint?: ReactNode;
error?: ReactNode;
submitLabel: ReactNode;
disabled?: boolean;
inputId: string;
inputRef?: Ref<HTMLInputElement>;
className?: string;
action?: ReactNode;
}
export default function InlineComposer({
label,
value,
onChange,
onSubmit,
placeholder,
hint,
error,
submitLabel,
disabled = false,
inputId,
inputRef,
className,
action,
}: InlineComposerProps) {
return (
<InsetPanel className={cx("space-y-2.5", className)} padding="sm" as="form" onSubmit={(event: FormEvent) => {
event.preventDefault();
onSubmit();
}}
>
<label htmlFor={inputId} className="app-text-soft app-overline mb-1 block">
{label}
</label>
<div className="flex flex-col gap-2 sm:flex-row">
<TextInput
ref={inputRef}
id={inputId}
value={value}
onChange={(event) => onChange(event.target.value)}
placeholder={placeholder}
disabled={disabled}
className="flex-1"
/>
{action ?? (
<Button type="submit" disabled={disabled || !value.trim()} size="xs" variant="solid" tone="brand">
{submitLabel}
</Button>
)}
</div>
{hint ? <div className="app-text-faint app-caption mt-1">{hint}</div> : null}
{error ? (
<div role="alert" className="app-text-danger app-caption mt-2">
{error}
</div>
) : null}
</InsetPanel>
);
}