"use client"; import { useEffect, useRef, useState, type ComponentProps, type ReactNode } from "react"; import { Field, FormField, IconButton, Radio, RadioGroup, Textarea, Tooltip, useToast } from "@unlocalhosted/metalui"; import { MorphIcon } from "@unlocalhosted/metalui/icons"; /* * MetalUI's form anatomy for the settings, auth and new-repository forms: the label above, 6 apart, * the control, then its description in meta ink3 (FormField), around MetalUI's regular Field and * Textarea. Every control keeps its `name`, so the forms still post to their server actions. */ type Words = { label: ReactNode; description?: ReactNode; optional?: boolean; className?: string }; function FieldLabel({ label, optional }: { label: ReactNode; optional?: boolean }) { return ( {label} {optional && · optional} ); } /** A one-line text field: MetalUI's Field at the form size (32, radius 11) with its words. */ export function TextField({ label, description, optional, className, icon, mono, ...input }: Words & { icon?: ReactNode; mono?: boolean } & Omit, "ref" | "className">) { return ( {icon && {icon}} {description && {description}} ); } /** Several lines: MetalUI's Textarea (it grows with what is written) with its words. */ export function TextareaField({ label, description, optional, className, mono, ...textarea }: Words & { mono?: boolean } & Omit, "ref" | "className">) { return (