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.

97 lines (96 loc) 5.7 kB
import { JSX } from 'solid-js'; /** How the tray frames the input — the SPATIAL axis (padding/inset only). * Orthogonal to {@link PromptDockAppearance}, which controls the surface. * - `inset` (default) — uniform inset frames the input on ALL edges (the classic look). * - `edge` — top/bottom inset only; the input sits FLUSH left/right so the lips span * the full width. * - `none` — no inset at all; the lips attach directly to the input as a plain stack. */ export type PromptDockFrame = 'inset' | 'edge' | 'none'; /** How the tray surface looks — the VISUAL axis (background / border / radius only). * Orthogonal to {@link PromptDockFrame}, which controls the spatial inset. Works like * a button variant. * - `soft` (default) — sunken surface + border + radius (the classic look). * - `outlined` — transparent surface + border + radius. * - `filled` — sunken surface, no border, + radius. * - `plain` — transparent surface, no border, no radius (truly bare). */ export type PromptDockAppearance = 'soft' | 'outlined' | 'filled' | 'plain'; export interface PromptDockProps { /** Optional content for the recessed band ABOVE the input (a notice, a hint). * When omitted, no top lip renders and only the input shows. */ top?: JSX.Element; /** Optional content for the recessed band BELOW the input (a mode / control row). * When omitted, no bottom lip renders. */ bottom?: JSX.Element; /** Extra classes for the TOP lip wrapper, merged over the default band styling. * Use this to give the top region its own surface (e.g. a tinted notice) without * affecting the bottom. The eventual `kai-prompt-dock` element will expose the * same region via `::part(top)`. */ topClass?: string; /** Extra classes for the BOTTOM lip wrapper, merged over the default band styling. * The eventual `kai-prompt-dock` element will expose this region via * `::part(bottom)`. */ bottomClass?: string; /** How the tray frames the input — the SPATIAL inset only. Defaults to `'inset'` * (the classic recessed look), so existing consumers are unaffected. * See {@link PromptDockFrame}. */ frame?: PromptDockFrame; /** How the tray surface looks — the VISUAL axis (background / border / radius), * orthogonal to `frame`. Defaults to `'soft'` (the classic look), so existing * consumers are unaffected. See {@link PromptDockAppearance}. */ appearance?: PromptDockAppearance; /** The prompt input - the raised card that floats on the tray. */ children: JSX.Element; /** Extra classes for the outer tray. */ class?: string; } /** * PromptDock - a recessed tray that frames a prompt input and can extend with * optional "lip" regions above and/or below it. * * The model: the input stays the prominent, fully-rounded RAISED card; the lips * sit in a slightly darker, RECESSED band tucked above and/or below it, sharing * the tray's outer rounding so the whole thing reads as one cohesive control. * When nothing is slotted top or bottom, only the input shows: no visible lip. * * Styling splits into two ORTHOGONAL axes so the spatial framing and the surface * can be set independently (like a button's size vs. its variant): * * `frame` - the SPATIAL inset (padding only): * - `inset` (default) - a small, uniform inset frames the input on EVERY side * (the tray padding plus the flex gap give a ~6px frame). The classic look. * - `edge` - top/bottom inset only; the input is FLUSH on the left / right so the * lips span the full width. Matches the Claude Code / Codex references, where the * lip is a top/bottom phenomenon. * - `none` - no inset at all; the lips attach directly to the input as a plain * vertical stack. The lips keep their own internal padding so content still has * breathing room. * * `appearance` - the SURFACE (background / border / radius): * - `soft` (default) - sunken surface + border + radius (the classic look). * - `outlined` - transparent surface + border + radius. * - `filled` - sunken surface, no border, + radius. * - `plain` - transparent surface, no border, no radius (truly bare). * * The two are independent: e.g. `frame="none" appearance="plain"` is a bare stack, * while `frame="inset" appearance="outlined"` keeps the inset but drops the fill. * * Surface, border, radius and inset come from four CSS custom-property TOKENS, so * a consumer can fine-tune the chrome without touching internals (override the var * from outside; the variant chooses the structure). Each is referenced with a * fallback so it resolves stand-alone: * - `--kai-prompt-dock-surface` - tray background (default `var(--color-surface-sunken)`) * - `--kai-prompt-dock-border` - tray border color (default `var(--color-border)`) * - `--kai-prompt-dock-radius` - outer radius (default `1.25rem`) * - `--kai-prompt-dock-inset` - frame thickness around the input (default `0.375rem`) * * Colors default to the surface tokens (surface-sunken for the tray and lips; the * input brings its own raised bg-surface), so it reads correctly in both light and * dark themes without hardcoded colors. The top and bottom lips are independently * styleable via `topClass` / `bottomClass` (e.g. a tinted notice up top over a * neutral control row below). * * The eventual `kai-prompt-dock` element will expose the same three regions via * `::part(tray)` / `::part(top)` / `::part(bottom)`; the primitive's equivalent * hooks are the `class` / `topClass` / `bottomClass` props. */ export declare function PromptDock(props: PromptDockProps): JSX.Element;