@teaui/react
Version:
React Reconciler and renderer for TeaUI
407 lines • 20.9 kB
JavaScript
import React, { forwardRef, useCallback, useMemo, useState } from 'react';
import { isMouseClicked } from '@teaui/core';
export { FontStyle } from './components/FontStyle.js';
export const Align = forwardRef(function Align({ children, ...props }, ref) {
return (React.createElement("tui-align", { ref: ref, ...props }, children));
});
Align.down = forwardRef(function AlignDown({ children, ...props }, ref) {
return (React.createElement("tui-align", { ref: ref, direction: "down", ...props }, children));
});
Align.up = forwardRef(function AlignUp({ children, ...props }, ref) {
return (React.createElement("tui-align", { ref: ref, direction: "up", ...props }, children));
});
Align.right = forwardRef(function AlignRight({ children, ...props }, ref) {
return (React.createElement("tui-align", { ref: ref, direction: "right", ...props }, children));
});
Align.left = forwardRef(function AlignLeft({ children, ...props }, ref) {
return (React.createElement("tui-align", { ref: ref, direction: "left", ...props }, children));
});
Align.column = Align.right;
Align.Row = function AlignRow({ children, ...props }) {
return React.createElement("tui-align-row", { ...props }, children);
};
Align.Column = Align.Row;
export function Br() {
return React.createElement("tui-br", null);
}
export const Badge = forwardRef(function Badge(reactProps, ref) {
return React.createElement("tui-badge", { ref: ref, ...reactProps });
});
export const Breadcrumb = forwardRef(function Breadcrumb(reactProps, ref) {
return React.createElement("tui-breadcrumb", { ref: ref, ...reactProps });
});
export const Calendar = forwardRef(function Calendar(reactProps, ref) {
return React.createElement("tui-calendar", { ref: ref, ...reactProps });
});
export const Canvas = forwardRef(function Canvas(reactProps, ref) {
return React.createElement("tui-canvas", { ref: ref, ...reactProps });
});
export const Checkbox = forwardRef(function Checkbox(reactProps, ref) {
return React.createElement("tui-checkbox", { ref: ref, ...reactProps });
});
export const Toggle = forwardRef(function Toggle(reactProps, ref) {
return React.createElement("tui-toggle", { ref: ref, ...reactProps });
});
export const CollapsibleText = forwardRef(function CollapsibleText(reactProps, ref) {
return React.createElement("tui-collapsible-text", { ref: ref, ...reactProps });
});
export const ConsoleLog = forwardRef(function ConsoleLog(reactProps, ref) {
return React.createElement("tui-console", { ref: ref, ...reactProps });
});
export const Digits = forwardRef(function Digits(reactProps, ref) {
return React.createElement("tui-digits", { ref: ref, ...reactProps });
});
export function Dropdown(reactProps) {
return React.createElement("tui-dropdown", { ...reactProps });
}
export const HotKey = forwardRef(function HotKey(reactProps, ref) {
return React.createElement("tui-hotkey", { ref: ref, ...reactProps });
});
export const Keyboard = forwardRef(function Keyboard({ children, ...props }, ref) {
return (React.createElement("tui-keyboard", { ref: ref, ...props }, children));
});
export const Mouse = forwardRef(function Mouse({ children, ...props }, ref) {
return (React.createElement("tui-mouse", { ref: ref, ...props }, children));
});
export const H1 = forwardRef(function H1({ children, ...reactProps }, ref) {
return React.createElement("tui-h1", { ref: ref, text: children ?? reactProps.text, ...reactProps });
});
export const H2 = forwardRef(function H2({ children, ...reactProps }, ref) {
return React.createElement("tui-h2", { ref: ref, text: children ?? reactProps.text, ...reactProps });
});
export const H3 = forwardRef(function H3({ children, ...reactProps }, ref) {
return React.createElement("tui-h3", { ref: ref, text: children ?? reactProps.text, ...reactProps });
});
export const H4 = forwardRef(function H4({ children, ...reactProps }, ref) {
return React.createElement("tui-h4", { ref: ref, text: children ?? reactProps.text, ...reactProps });
});
export const H5 = forwardRef(function H5({ children, ...reactProps }, ref) {
return React.createElement("tui-h5", { ref: ref, text: children ?? reactProps.text, ...reactProps });
});
export const H6 = forwardRef(function H6({ children, ...reactProps }, ref) {
return React.createElement("tui-h6", { ref: ref, text: children ?? reactProps.text, ...reactProps });
});
export const Input = forwardRef(function Input(reactProps, ref) {
return React.createElement("tui-input", { ref: ref, ...reactProps });
});
export const Legend = forwardRef(function Legend(reactProps, ref) {
return React.createElement("tui-legend", { ref: ref, ...reactProps });
});
export const AutoLegend = forwardRef(function AutoLegend(reactProps, ref) {
return React.createElement("tui-auto-legend", { ref: ref, ...reactProps });
});
export const Progress = forwardRef(function Progress(reactProps, ref) {
return React.createElement("tui-progress", { ref: ref, ...reactProps });
});
export const Separator = forwardRef(function Separator(reactProps, ref) {
return React.createElement("tui-separator", { ref: ref, ...reactProps });
});
Separator.horizontal = forwardRef(function SeparatorHorizontal(reactProps, ref) {
return React.createElement("tui-separator", { ref: ref, direction: "horizontal", ...reactProps });
});
Separator.vertical = forwardRef(function SeparatorVertical(reactProps, ref) {
return React.createElement("tui-separator", { ref: ref, direction: "vertical", ...reactProps });
});
export const Slider = forwardRef(function Slider(reactProps, ref) {
return React.createElement("tui-slider", { ref: ref, ...reactProps });
});
Slider.horizontal = forwardRef(function SliderHorizontal(reactProps, ref) {
return React.createElement("tui-slider", { ref: ref, direction: "horizontal", ...reactProps });
});
Slider.vertical = forwardRef(function SliderVertical(reactProps, ref) {
return React.createElement("tui-slider", { ref: ref, direction: "vertical", ...reactProps });
});
export const Space = forwardRef(function Space(reactProps, ref) {
return React.createElement("tui-space", { ref: ref, ...reactProps });
});
export const Spinner = forwardRef(function Spinner(reactProps, ref) {
return React.createElement("tui-spinner", { ref: ref, ...reactProps });
});
export const Logo = forwardRef(function Logo(reactProps, ref) {
return React.createElement("tui-logo", { ref: ref, ...reactProps });
});
export const ZStack = forwardRef(function ZStack(reactProps, ref) {
return React.createElement("tui-zstack", { ref: ref, ...reactProps });
});
export const At = forwardRef(function At({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, ...props }, children));
});
At.topLeft = forwardRef(function AtTopLeft({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "top-left", ...props }, children));
});
At.topCenter = forwardRef(function AtTopCenter({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "top-center", ...props }, children));
});
At.topRight = forwardRef(function AtTopRight({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "top-right", ...props }, children));
});
At.left = forwardRef(function AtLeft({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "left", ...props }, children));
});
At.center = forwardRef(function AtCenter({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "center", ...props }, children));
});
At.right = forwardRef(function AtRight({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "right", ...props }, children));
});
At.bottomLeft = forwardRef(function AtBottomLeft({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "bottom-left", ...props }, children));
});
At.bottomCenter = forwardRef(function AtBottomCenter({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "bottom-center", ...props }, children));
});
At.bottomRight = forwardRef(function AtBottomRight({ children, ...props }, ref) {
return (React.createElement("tui-at", { ref: ref, location: "bottom-right", ...props }, children));
});
export const ToggleGroup = forwardRef(function ToggleGroup(reactProps, ref) {
return React.createElement("tui-toggle-group", { ref: ref, ...reactProps });
});
function TreeItems({ items, render, getChildren, expanded, toggle, prefix, ancestors, }) {
return (React.createElement(React.Fragment, null, items.map((item, index) => {
const path = `${prefix}.${index}`;
const children = getChildren?.(item);
const hasChildren = children != null && children.length > 0;
const isExpanded = expanded.has(path);
const isLast = index === items.length - 1;
let line = '';
for (const ancestor of ancestors) {
line += ancestor.isLast ? ' ' : TREE_VLINE;
}
if (hasChildren) {
line += isLast ? TREE_LAST_BRANCH : TREE_BRANCH;
line += isExpanded ? TREE_EXPANDED : TREE_COLLAPSED;
}
else {
line += isLast ? TREE_LAST_LEAF : TREE_LEAF;
}
return (React.createElement(React.Fragment, { key: path },
React.createElement("tui-mouse", { mouse: "mouse.button.left", onMouse: event => {
if (hasChildren && isMouseClicked(event)) {
toggle(path);
}
} },
React.createElement("tui-stack", { direction: "right" },
React.createElement("tui-text", null, line),
render(item))),
isExpanded && hasChildren && children && (React.createElement(TreeItems, { items: children, render: render, getChildren: getChildren, expanded: expanded, toggle: toggle, prefix: path, ancestors: [...ancestors, { isLast }] }))));
})));
}
const TREE_VLINE = '│ ';
const TREE_BRANCH = '├';
const TREE_LAST_BRANCH = '└';
const TREE_LEAF = '├──╴';
const TREE_LAST_LEAF = '└──╴';
const TREE_COLLAPSED = '─╴▹';
const TREE_EXPANDED = '─╴▿';
export function Tree(reactProps) {
const { title, data, render, getChildren, ...viewProps } = reactProps;
const [expanded, setExpanded] = useState(new Set());
const toggle = useCallback((path) => {
setExpanded(prev => {
const next = new Set(prev);
if (next.has(path)) {
next.delete(path);
}
else {
next.add(path);
}
return next;
});
}, []);
return (React.createElement("tui-stack", { direction: "down", ...viewProps },
typeof title === 'string' ? React.createElement("tui-text", null, title) : title,
React.createElement(TreeItems, { items: data, render: render, getChildren: getChildren, expanded: expanded, toggle: toggle, prefix: "", ancestors: [] })));
}
export const Modal = forwardRef(function Modal({ children, ...props }, ref) {
return (React.createElement("tui-modal", { ref: ref, ...props }, children));
});
////
/// "Simple" containers
//
export function Alert({ children, ...props }) {
return React.createElement("tui-alert", { ...props }, children);
}
export const Callout = forwardRef(function Callout({ children, ...props }, ref) {
return (React.createElement("tui-callout", { ref: ref, ...props }, children));
});
export const Box = forwardRef(function Box({ children, ...props }, ref) {
return (React.createElement("tui-box", { ref: ref, ...props }, children));
});
export const Button = forwardRef(function Button({ children, ...props }, ref) {
return (React.createElement("tui-button", { ref: ref, ...props }, children));
});
export const Collapsible = forwardRef(function Collapsible({ collapsed, expanded, ...props }, ref) {
return (React.createElement("tui-collapsible", { ref: ref, ...props },
collapsed,
expanded));
});
export const Stack = forwardRef(function Stack({ children, ...props }, ref) {
return (React.createElement("tui-stack", { ref: ref, ...props }, children));
});
Stack.down = forwardRef(function StackDown({ children, ...props }, ref) {
return (React.createElement("tui-stack", { ref: ref, direction: "down", ...props }, children));
});
Stack.up = forwardRef(function StackUp({ children, ...props }, ref) {
return (React.createElement("tui-stack", { ref: ref, direction: "up", ...props }, children));
});
Stack.right = forwardRef(function StackRight({ children, ...props }, ref) {
return (React.createElement("tui-stack", { ref: ref, direction: "right", ...props }, children));
});
Stack.left = forwardRef(function StackLeft({ children, ...props }, ref) {
return (React.createElement("tui-stack", { ref: ref, direction: "left", ...props }, children));
});
export const Geometry = forwardRef(function Geometry({ children, ...props }, ref) {
return (React.createElement("tui-geometry", { ref: ref, ...props }, children));
});
export const Scrollable = forwardRef(function Scrollable({ children, ...props }, ref) {
return (React.createElement("tui-scrollable", { ref: ref, ...props }, children));
});
Scrollable.down = forwardRef(function ScrollableDown({ children, ...props }, ref) {
return (React.createElement("tui-scrollable", { ref: ref, direction: "down", ...props }, children));
});
Scrollable.up = forwardRef(function ScrollableUp({ children, ...props }, ref) {
return (React.createElement("tui-scrollable", { ref: ref, direction: "up", ...props }, children));
});
Scrollable.right = forwardRef(function ScrollableRight({ children, ...props }, ref) {
return (React.createElement("tui-scrollable", { ref: ref, direction: "right", ...props }, children));
});
Scrollable.left = forwardRef(function ScrollableLeft({ children, ...props }, ref) {
return (React.createElement("tui-scrollable", { ref: ref, direction: "left", ...props }, children));
});
/**
* <Style /> is similar to <Text/> but only allows inline styles (bold, etc).
* Does not support align or wrap (block styles). Does not support 'font', because
* font is not encodable via SGR codes (and that's how I'm styling and
* concatenating the text nodes).
*/
export const Style = forwardRef(function Style(reactProps, ref) {
return React.createElement("tui-style", { ref: ref, ...reactProps });
});
/**
* <Text /> is a container that sets the text properties of child TextLiterals
* (font, style) and TextContainers (wrap, alignment)
*/
export const Text = forwardRef(function Text(reactProps, ref) {
return React.createElement("tui-text", { ref: ref, ...reactProps });
});
/**
* List component with virtualized row rendering via React children.
*
* Similar to Table, this accepts a `renderItem` callback that returns JSX.
* The core List handles scrolling, keyboard/mouse navigation, and selection
* highlighting, while React renders each visible item.
*
* ```tsx
* <List
* data={items}
* renderItem={(item, index) => <Text>{item.name}</Text>}
* onSelect={(item) => console.info('Selected:', item)}
* />
* ```
*/
export function ScrollableList(reactProps) {
const { data, renderItem, filter, ...props } = reactProps;
const filteredData = useMemo(() => (filter ? data.filter(filter) : data), [data, filter]);
// The React List omits renderItem from the core props. Instead, it renders
// data items as React children. The core List detects the missing renderItem
// and renders its Container children by index, which the reconciler manages.
return (React.createElement("tui-list", { data: filteredData, ...props }, filteredData.map((item, index) => (React.createElement(React.Fragment, { key: index }, renderItem(item, index))))));
}
/**
* Table component with optional virtualized row rendering.
*
* When `renderItem` is provided, only visible rows are rendered as React children,
* enabling efficient rendering of large datasets. The Geometry component measures
* available space, and only the visible slice of data is passed through the reconciler.
*
* When only `format` is provided, the core Table handles all rendering directly
* (no virtualization needed since cells are plain strings).
*/
export function Table(reactProps) {
const { data, columns, renderItem, format, ...props } = reactProps;
if (!renderItem) {
// Simple mode: core Table handles everything via format callback
return (React.createElement("tui-table", { data: data, columns: columns, format: format ?? (() => ''), ...props }));
}
// Virtualized mode: React renders only visible rows.
// Geometry measures available space so we can pass the visible slice through
// the reconciler while the core Table renders the header/chrome and handles
// row highlighting.
const [bodyHeight, setBodyHeight] = useState(20);
const handleLayout = useCallback((size) => {
// Table uses 2 rows for header + separator.
setBodyHeight(Math.max(0, size.height - 2));
}, []);
const selectedIndex = props.selectedIndex ?? 0;
const scrollOffset = useMemo(() => {
const halfHeight = Math.floor(bodyHeight / 2);
let offset = 0;
if (selectedIndex > halfHeight &&
selectedIndex < data.length - halfHeight) {
offset = selectedIndex - halfHeight;
}
else if (selectedIndex >= bodyHeight) {
offset = selectedIndex - bodyHeight + 1;
}
return Math.max(0, Math.min(data.length - bodyHeight, offset));
}, [selectedIndex, bodyHeight, data.length]);
const visibleStart = scrollOffset;
const visibleEnd = Math.min(data.length, scrollOffset + bodyHeight);
const visibleData = data.slice(visibleStart, visibleEnd);
// Use format as a pass-through since child rows provide the row content.
const formatFn = format ?? (() => '');
return (React.createElement("tui-geometry", { onLayout: handleLayout },
React.createElement("tui-table", { data: data, columns: columns, format: formatFn, childOffset: visibleStart, ...props }, visibleData.map((item, index) => (React.createElement(React.Fragment, { key: visibleStart + index }, renderItem(item, visibleStart + index)))))));
}
export const Accordion = forwardRef(function Accordion({ children, ...props }, ref) {
return (React.createElement("tui-accordion", { ref: ref, ...props }, children));
});
Accordion.Section = forwardRef(function AccordionSection({ children, ...props }, ref) {
return (React.createElement("tui-accordion-section", { ref: ref, ...props }, children));
});
export const Page = forwardRef(function Page({ children, ...props }, ref) {
return (React.createElement("tui-page", { ref: ref, ...props }, children));
});
Page.Section = forwardRef(function PageSection({ children, ...props }, ref) {
return (React.createElement("tui-page-section", { ref: ref, ...props }, children));
});
export const Pane = forwardRef(function Pane({ children, ...props }, ref) {
return (React.createElement("tui-pane", { ref: ref, ...props }, children));
});
export const Drawer = forwardRef(function Drawer({ children, content, drawer, ...props }, ref) {
return (React.createElement("tui-drawer", { ref: ref, ...props },
content,
drawer,
children));
});
Drawer.top = forwardRef(function DrawerTop({ children, content, drawer, ...props }, ref) {
return (React.createElement("tui-drawer", { ref: ref, location: "top", ...props },
content,
drawer,
children));
});
Drawer.right = forwardRef(function DrawerRight({ children, content, drawer, ...props }, ref) {
return (React.createElement("tui-drawer", { ref: ref, location: "right", ...props },
content,
drawer,
children));
});
Drawer.bottom = forwardRef(function DrawerBottom({ children, content, drawer, ...props }, ref) {
return (React.createElement("tui-drawer", { ref: ref, location: "bottom", ...props },
content,
drawer,
children));
});
Drawer.left = forwardRef(function DrawerLeft({ children, content, drawer, ...props }, ref) {
return (React.createElement("tui-drawer", { ref: ref, location: "left", ...props },
content,
drawer,
children));
});
export const Tabs = forwardRef(function Tabs({ children, ...props }, ref) {
return (React.createElement("tui-tabs", { ref: ref, ...props }, children));
});
Tabs.Section = forwardRef(function TabsSection({ children, ...props }, ref) {
return (React.createElement("tui-tabs-section", { ref: ref, ...props }, children));
});
//# sourceMappingURL=components.js.map