mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-08 04:08:24 +00:00
Phase 4: component library
The approved element rules and ornament kit as Astro components in packages/ui: buttons, pills, chips, filters, kickers, notices, fields and cards; star paths, the header divider, tick scales and rings, seals and edge seals, gilt corners, dust and placeholder art; the site header, footer and page shell. Brand fonts are self-hosted. A gallery page shows everything, and astro check now runs with the root typecheck. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
---
|
||||
/**
|
||||
* Rule V. A labelled field: input, select or text area in the 10px box, with
|
||||
* the filament drawn across its base on focus.
|
||||
*/
|
||||
import type { HTMLAttributes } from "astro/types";
|
||||
|
||||
type Props = {
|
||||
label: string;
|
||||
name: string;
|
||||
as?: "input" | "select" | "textarea";
|
||||
hint?: string;
|
||||
error?: string;
|
||||
options?: (string | { value: string; label: string })[];
|
||||
/** Rows for a text area. */
|
||||
rows?: number;
|
||||
class?: string;
|
||||
} & HTMLAttributes<"input">;
|
||||
|
||||
const { label, name, as = "input", hint, error, options = [], rows, class: className, id = `f-${name}`, ...rest } = Astro.props;
|
||||
const describedBy = [hint && `${id}-hint`, error && `${id}-error`].filter(Boolean).join(" ") || undefined;
|
||||
const common = { id, name, class: "gk-field", "aria-describedby": describedBy, "aria-invalid": error ? ("true" as const) : undefined };
|
||||
---
|
||||
<div class:list={["gk-label", className]}>
|
||||
<label class="gk-label-text" for={id}>{label}</label>
|
||||
{as === "select" ? (
|
||||
<select {...common} {...(rest as object)}>
|
||||
{options.map((o) => (typeof o === "string" ? <option>{o}</option> : <option value={o.value}>{o.label}</option>))}
|
||||
</select>
|
||||
) : as === "textarea" ? (
|
||||
<textarea {...common} rows={rows} {...(rest as object)} />
|
||||
) : (
|
||||
<input {...common} {...rest} />
|
||||
)}
|
||||
{hint && <span class="gk-hint" id={`${id}-hint`}>{hint}</span>}
|
||||
{error && <span class="error" id={`${id}-error`}>{error}</span>}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.error {
|
||||
font-size: 12px;
|
||||
color: #f0857a;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user