master @ 43 LINES
[ HISTORY ] [ UP ]
┌─ TS ───────────────────────────────────────────────────────────────────────┐
│ import type { SelectOption } from "../Select/Select"; │
│ │
│ export type ButtonSpec = { │
│ label: string; │
│ type?: "button" | "submit" | "reset"; │
│ variant?: "default" | "primary"; │
│ }; │
│ │
│ export type Field = │
│ | { kind: "text" | "password"; label: string; name: string; cells?: number } │
│ | { kind: "textarea"; label: string; name: string; rows?: number } │
│ | { kind: "select"; label: string; name: string; options: (SelectOption | string │
│ )[]; cells?: number; value?: string } │
│ | { kind: "radios"; label: string; name: string; options: string[]; value?: stri │
│ ng } │
│ | { kind: "checkbox"; label: string; name: string; checked?: boolean } │
│ | { kind: "buttons"; buttons: ButtonSpec[] } │
│ | { kind: "gap" }; │
│ │
│ export interface Props { │
│ title: string; │
│ fields: Field[]; │
│ /** Box width in cells. Defaults to the narrow frame so one render │
│ * serves both viewports (inputs can't dual-render). */ │
│ width?: number; │
│ action?: string; │
│ method?: string; │
│ } │
│ │
│ export const FORM_LABEL_W = 12; │
│ export const FORM_INDENT = 2; │
│ │
│ export function formGeometry(width: number) { │
│ const inner = width - 2; │
│ const contentW = inner - FORM_INDENT; │
│ return { │
│ inner, │
│ contentW, │
│ /** Default input width: fills the row after the label column. */ │
│ defaultCells: contentW - FORM_LABEL_W, │
│ /** Textarea spans the content area minus a right-hand indent. */ │
│ textareaCells: contentW - FORM_INDENT, │
│ }; │
│ } │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ TS ─────────────────────────────────┐
│ import type { SelectOption } from "../Select │
│ /Select"; │
│ │
│ export type ButtonSpec = { │
│ label: string; │
│ type?: "button" | "submit" | "reset"; │
│ variant?: "default" | "primary"; │
│ }; │
│ │
│ export type Field = │
│ | { kind: "text" | "password"; label: stri │
│ ng; name: string; cells?: number } │
│ | { kind: "textarea"; label: string; name: │
│ string; rows?: number } │
│ | { kind: "select"; label: string; name: s │
│ tring; options: (SelectOption | string)[]; c │
│ ells?: number; value?: string } │
│ | { kind: "radios"; label: string; name: s │
│ tring; options: string[]; value?: string } │
│ | { kind: "checkbox"; label: string; name: │
│ string; checked?: boolean } │
│ | { kind: "buttons"; buttons: ButtonSpec[] │
│ } │
│ | { kind: "gap" }; │
│ │
│ export interface Props { │
│ title: string; │
│ fields: Field[]; │
│ /** Box width in cells. Defaults to the na │
│ rrow frame so one render │
│ * serves both viewports (inputs can't du │
│ al-render). */ │
│ width?: number; │
│ action?: string; │
│ method?: string; │
│ } │
│ │
│ export const FORM_LABEL_W = 12; │
│ export const FORM_INDENT = 2; │
│ │
│ export function formGeometry(width: number) │
│ { │
│ const inner = width - 2; │
│ const contentW = inner - FORM_INDENT; │
│ return { │
│ inner, │
│ contentW, │
│ /** Default input width: fills the row a │
│ fter the label column. */ │
│ defaultCells: contentW - FORM_LABEL_W, │
│ /** Textarea spans the content area minu │
│ s a right-hand indent. */ │
│ textareaCells: contentW - FORM_INDENT, │
│ }; │
│ } │
└──────────────────────────────────────────────┘
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET