Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
52 lines
1.3 KiB
TypeScript
52 lines
1.3 KiB
TypeScript
import type { Component } from "./tui.ts";
|
|
|
|
export const LAYOUT_NODE = Symbol.for("@earendil-works/pi-tui/layout-node");
|
|
|
|
export interface LayoutViewport {
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
export interface StackLayoutEntry {
|
|
component: Component;
|
|
basis?: number | "auto";
|
|
grow?: number;
|
|
shrink?: number;
|
|
minSize?: number;
|
|
maxSize?: number;
|
|
visible?: (viewport: LayoutViewport) => boolean;
|
|
}
|
|
|
|
export interface StackLayoutNode {
|
|
type: "vstack" | "hstack";
|
|
entries: readonly StackLayoutEntry[];
|
|
gap: number;
|
|
align: "stretch" | "start" | "center" | "end";
|
|
}
|
|
|
|
export interface ScrollLayoutState {
|
|
readonly scrollTop: number;
|
|
readonly primary: boolean;
|
|
readonly overscroll: "chain" | "contain";
|
|
readonly viewportHeight: number;
|
|
getContentWidth(width: number): number;
|
|
updateLayout(contentHeight: number, viewportHeight: number, requestRender: () => void): void;
|
|
}
|
|
|
|
export interface ScrollLayoutNode {
|
|
type: "scroll";
|
|
component: Component;
|
|
state: ScrollLayoutState;
|
|
}
|
|
|
|
export type LayoutNode = StackLayoutNode | ScrollLayoutNode;
|
|
|
|
export interface LayoutComponent extends Component {
|
|
[LAYOUT_NODE](): LayoutNode;
|
|
}
|
|
|
|
export function getLayoutNode(component: Component): LayoutNode | undefined {
|
|
const candidate = component as Partial<LayoutComponent>;
|
|
return typeof candidate[LAYOUT_NODE] === "function" ? candidate[LAYOUT_NODE]() : undefined;
|
|
}
|