/** biome-ignore-all lint/correctness/noUnusedVariables: consumed by JSX transform */
/** biome-ignore-all lint/complexity/noBannedTypes: required by JSX spec */
import type { Element as SolidElement } from "solid-js";
import type { AshlarColorInput } from "./src/core/terminal-palette.ts";
import type { TermNode } from "./src/renderer/term-node.ts";
export namespace JSX {
// Solid 2.0's control-flow components (`Show`, `For`, …) are typed to
// return Solid's universal `Element` (nodes, arrays, strings, null,
// undefined). `JSX.Element` must accept that union for them to be valid
// JSX components; concrete nodes still flow through `TermNode`.
type Element = SolidElement;
type ChildNode =
| Element
| Element[]
| ChildNode[]
| string
| number
| null
| undefined;
interface IntrinsicElements {
box: {
ref?: TermNode | ((node: TermNode) => void);
role?: string;
flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
flexGrow?: number;
flexShrink?: number;
flexBasis?: number | string;
flexWrap?: "nowrap" | "wrap" | "wrap-reverse";
alignItems?:
| "flex-start"
| "center"
| "flex-end"
| "stretch"
| "baseline";
alignSelf?:
| "auto"
| "flex-start"
| "center"
| "flex-end"
| "stretch"
| "baseline";
justifyContent?:
| "flex-start"
| "center"
| "flex-end"
| "space-between"
| "space-around"
| "space-evenly";
width?: number | string;
height?: number | string;
minWidth?: number | string;
minHeight?: number | string;
maxWidth?: number | string;
maxHeight?: number | string;
position?: "relative" | "absolute";
top?: number | string;
right?: number | string;
bottom?: number | string;
left?: number | string;
padding?: number;
paddingTop?: number;
paddingBottom?: number;
paddingLeft?: number;
paddingRight?: number;
margin?: number;
marginTop?: number;
marginBottom?: number;
marginLeft?: number;
marginRight?: number;
gap?: number;
borderStyle?:
| "single"
| "double"
| "round"
| "bold"
| "horizontal"
| "none";
/** Background color */
bg?: AshlarColorInput;
/** Border color */
color?: AshlarColorInput;
/** Dim every glyph already painted beneath this box. Useful for modal scrims. */
dimContent?: boolean;
/**
* Internal paint-time color filter: recolors every glyph cell in this
* box's region after its subtree paints, mapping local (x, y) within a
* width×height box to a packed 24-bit fg (or `undefined` to leave it).
* Set by `<Animated>` (`ashlar/animation`) — not meant for direct use.
*/
colorField?: (
x: number,
y: number,
width: number,
height: number,
) => number | undefined;
display?: "flex" | "none";
overflow?: "visible" | "hidden" | "scroll";
/** Click handler (mouse up on this node) */
onClick?: (
event: import("./src/input/parse-mouse.ts").RawMouseEvent,
) => void;
/** Mouse enter handler */
onMouseEnter?: (
event: import("./src/input/parse-mouse.ts").RawMouseEvent,
) => void;
/** Mouse leave handler */
onMouseLeave?: (
event: import("./src/input/parse-mouse.ts").RawMouseEvent,
) => void;
/** Scroll handler (mouse wheel on this node) */
onScroll?: (
event: import("./src/input/parse-mouse.ts").RawMouseEvent,
) => void;
children?: ChildNode | ChildNode[];
};
hyperlink: {
ref?: TermNode | ((node: TermNode) => void);
/** URL to link to (file://, https://, etc.) */
href: string;
color?: AshlarColorInput;
bg?: AshlarColorInput;
bold?: boolean;
italic?: boolean;
underline?: boolean;
strikethrough?: boolean;
dim?: boolean;
children?: string | number | (string | number)[] | null | undefined;
};
input: {
ref?: TermNode | ((node: TermNode) => void);
/** Current value (controlled) */
value?: string;
/** Placeholder text when empty */
placeholder?: string;
/** Called when value changes */
onChange?: (value: string) => void;
/** Called when Enter is pressed */
onSubmit?: (value: string) => void;
/** Text color */
color?: AshlarColorInput;
/** Background color */
bg?: AshlarColorInput;
/** Placeholder text color */
placeholderColor?: AshlarColorInput;
/** Whether the input is focused and accepting keys */
focused?: boolean;
/** Enable multi-line editing (Enter inserts newline, Ctrl+Enter submits). Default: false (Enter submits). */
multiline?: boolean;
/** In multiline mode, Enter submits and Shift+Enter inserts a newline. */
submitOnEnter?: boolean;
/** Cursor character (default: block via inverse) */
cursorChar?: string;
width?: number | string;
height?: number | string;
};
text: {
ref?: TermNode | ((node: TermNode) => void);
color?: AshlarColorInput;
bg?: AshlarColorInput;
bold?: boolean;
italic?: boolean;
underline?: boolean;
strikethrough?: boolean;
dim?: boolean;
inverse?: boolean;
wrap?:
| "word"
| "truncate"
| "truncate-end"
| "truncate-middle"
| "truncate-start";
onClick?: (
event: import("./src/input/parse-mouse.ts").RawMouseEvent,
) => void;
onMouseEnter?: (
event: import("./src/input/parse-mouse.ts").RawMouseEvent,
) => void;
onMouseLeave?: (
event: import("./src/input/parse-mouse.ts").RawMouseEvent,
) => void;
children?: string | number | (string | number)[] | null | undefined;
};
}
interface ElementChildrenAttribute {
children: {};
}
}