UNPKG

@kitn.ai/ui

Version:

Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.

89 lines (88 loc) 4.64 kB
import { JSX } from 'solid-js'; type Orientation = 'horizontal' | 'vertical'; /** A size value: a number (percent), `"25%"` (percent), or `"280px"` (pixels). */ export type SizeValue = number | string; interface ResizableContextValue { orientation: Orientation; } export declare const ResizableContext: import('solid-js').Context<ResizableContextValue | undefined>; /** * Normalize a px-or-% size into a CSS length string usable as `flex-basis`. * - number → percent (`30` → `"30%"`) * - `"25%"` → percent passthrough * - `"280px"` → pixel passthrough * Returns `undefined` for unset values (caller falls back to flexible `flex: 1`). */ export declare function normalizeSize(value: SizeValue | undefined): string | undefined; /** * Resolve a px-or-% size to pixels, given the container's main-axis size. * Used to seed `data-min-size` / `data-max-size` (which the handle reads as px). * Returns `undefined` when the value is unset. */ export declare function resolveToPx(value: SizeValue | undefined, containerPx: number): number | undefined; /** * Build a panel's INITIAL `flex-basis`, clamped into its `[min, max]` bounds so * it never PAINTS past its max (or below its min). The drag handler already * clamps, but only once a drag begins — without this, a percentage default on a * wide container (e.g. `40%` against a `480px` max) renders wider than max and * then SNAPS to max on the first resize. Uses CSS `clamp()`/`min()`/`max()` so * the bound is enforced at layout time against the live container size, with * MIXED units (a `%` default vs a `px` max) resolving correctly — no JS measure. * `basis`/`min`/`max` are already-normalized CSS lengths (see `normalizeSize`); * an undefined `basis` stays undefined → the caller falls back to flexible. */ export declare function clampBasis(basis: string | undefined, min: string | undefined, max: string | undefined): string | undefined; export interface ResizablePanelGroupProps extends JSX.HTMLAttributes<HTMLDivElement> { orientation?: Orientation; children: JSX.Element; } declare function ResizablePanelGroup(props: ResizablePanelGroupProps): JSX.Element; export interface ResizablePanelProps extends JSX.HTMLAttributes<HTMLDivElement> { /** Initial main-axis size: number/`"25%"` (percent) or `"280px"` (pixels). Omitted → flexible. */ defaultSize?: SizeValue; /** Minimum size during resize (px or %). */ minSize?: SizeValue; /** Maximum size during resize (px or %). */ maxSize?: SizeValue; /** When true, the panel's size is fixed and adjacent handles are non-draggable. */ locked?: boolean; /** When true, the panel is not visible (used by the `Resizable` convenience to drop dividers). */ hidden?: boolean; children: JSX.Element; } declare function ResizablePanel(props: ResizablePanelProps): JSX.Element; export interface ResizableHandleProps extends JSX.HTMLAttributes<HTMLDivElement> { withHandle?: boolean; onPanelResize?: (delta: number) => void; /** Keyboard nudge step in pixels (default 16). Home/End jump to min/max. */ keyboardStep?: number; /** Render as a static, non-interactive divider (e.g. between locked panels). */ static?: boolean; /** Explicit axis; overrides `ResizableContext`. Needed by facades that render * handles outside a context provider (e.g. `<kai-resizable>`). */ orientation?: Orientation; } declare function ResizableHandle(props: ResizableHandleProps): JSX.Element; export interface ResizableProps { orientation?: Orientation; /** Fired on drag-end / keyboard resize / visibility change with the current panel sizes (percent). */ onChange?: (sizes: number[]) => void; /** Show a visible grip on each interactive handle. */ withHandle?: boolean; class?: string; /** Which panel index is maximized (null = none). Hides the others. */ maximizedIndex?: number | null; /** Fired when the maximized panel changes (index, or null on restore). */ onMaximizeChange?: (index: number | null) => void; /** `ResizablePanel` children. */ children: JSX.Element; } /** * Convenience group that takes `ResizablePanel` children and AUTO-INSERTS a * `ResizableHandle` between each pair of visible (non-`hidden`) panels. A handle * is interactive only between two unlocked neighbors; otherwise it renders as a * static divider. Power users who need manual control can keep using * `ResizablePanelGroup` + explicit `ResizableHandle`s. */ declare function Resizable(props: ResizableProps): JSX.Element; export { ResizablePanelGroup, ResizablePanel, ResizableHandle, Resizable };