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.

121 lines (120 loc) 6.09 kB
import { JSX } from 'solid-js'; import { CardEnvelope, CardHost, CardResolution } from '../primitives/card-contract'; export interface TasksTask { id: string; label: string; description?: string; checked?: boolean; disabled?: boolean; } export interface TasksCardData { /** * `select` (default) = checkbox rows + a confirm button that emits the contract * `submit`. `progress` = an onboarding/checklist look: a header `done / total` * count, circular indicators, per-item title + muted description, and NO confirm * button (checking a row is itself the terminal action). Both share the same * selection model (toggle by id, the `max` gate, `kai-value-change`); `progress` * is purely a presentational variant. */ mode?: 'select' | 'progress'; heading?: string; tasks: TasksTask[]; selectAll?: boolean; confirmLabel?: string; allowEmpty?: boolean; min?: number; max?: number; dismissible?: boolean; } export interface TasksCardResult { selected: string[]; } export type TasksCardEnvelope = CardEnvelope<'tasks', TasksCardData>; export declare const TASKS_CARD_TYPE: "tasks"; /** De-dupe tasks by id (first wins). Returns the usable list + an optional error. */ export declare function normalizeTasks(tasks: unknown): { tasks: TasksTask[]; error?: string; }; /** The ids of the initially-checked tasks (in input order). */ export declare function initialSelected(tasks: TasksTask[]): string[]; /** The selected ids in input order (selection set ∩ tasks, preserving task order). */ export declare function selectedInOrder(tasks: TasksTask[], selected: Set<string>): string[]; /** The toggleable (non-disabled) task ids. */ export declare function toggleableIds(tasks: TasksTask[]): string[]; export type SelectAllState = 'checked' | 'unchecked' | 'indeterminate'; /** Select-all tri-state over the toggleable rows. */ export declare function selectAllState(tasks: TasksTask[], selected: Set<string>): SelectAllState; /** Whether select-all should be shown: requested AND not blocked by `max` (since * "all" would violate max). */ export declare function showSelectAll(data: TasksCardData, tasks: TasksTask[]): boolean; /** Whether the card is in the onboarding-checklist `progress` look (no confirm). */ export declare function isProgressMode(data: TasksCardData): boolean; /** The header progress count (`done` checked / `total` rows) for `progress` mode. */ export declare function progressCount(tasks: TasksTask[], selected: Set<string>): { done: number; total: number; }; /** Whether confirm is enabled for the current selection count. */ export declare function canConfirm(data: TasksCardData, count: number): boolean; /** Whether an unchecked row is blocked because `max` is reached. */ export declare function isMaxReached(data: TasksCardData, count: number): boolean; /** The disabled-reason text for confirm (for aria-describedby), or undefined. */ export declare function confirmReason(data: TasksCardData, count: number): string | undefined; /** Imperative handle exposed via `controllerRef` — surfaces the tasks card's latent * selection model (set the checked ids, toggle one, confirm, focus the group, * dismiss/reopen) so the `<kai-tasks>` facade can forward them as instance methods. */ export interface TasksCardController { /** Set the checked ids (local-only, no emit), respecting disabled/max. No arg = select all toggleable rows. */ select(taskIds?: string[]): void; /** Toggle one task by id, honoring the max gate. */ toggle(taskId: string, checked?: boolean): void; /** Confirm the current selection (only when allowed) — emits `submit` + resolves. */ send(): void; /** Focus the task group (select-all checkbox if shown, else the first row). */ focus(options?: FocusOptions): void; /** Trigger the dismiss path (emit `dismiss` + collapse to the re-openable stub). */ dismiss(): void; /** Re-open a dismissed card from its stub (emit `reopen`). */ reopen(): void; } export interface TasksCardProps { /** The tasks definition (CardEnvelope.data). */ data?: TasksCardData; /** The card id used to correlate every emitted CardEvent. */ cardId?: string; /** The envelope title rendered in the card chrome. */ heading?: string; /** Optional explicit CardHost (otherwise read from a CardProvider, otherwise the * bubbling `kai-card` CustomEvent off `hostElement`). */ host?: CardHost; /** The custom-element host node, for the bubbling `kai-card` fallback emit. */ hostElement?: HTMLElement; class?: string; /** When set, render the chromed read-only summary instead of the interactive controls. */ resolution?: CardResolution; /** Controlled selection (task ids) — when set, this wins over internal state. */ value?: string[]; /** Uncontrolled initial selection (task ids), overlaying per-task `checked`. */ defaultValue?: string[]; /** Freeze the whole list + Confirm. */ disabled?: boolean; /** Display-only: rows can't be toggled and show the default cursor (no pointer, * no hover background, no focus ring). Keeps the visual content as-is — this only * drops the interactive affordances + a11y exposure. */ readonly?: boolean; /** Fires on every selection change with the selected ids (distinct from submit). */ onValueChange?: (payload: { value: string[]; }) => void; /** Receive the imperative controller once mounted. */ controllerRef?: (controller: TasksCardController) => void; } /** * `TasksCard` — a selectable task/plan list (checkbox rows + optional select-all * + a confirm button) inside `Card` chrome. Row toggling and select-all are local * UI state; only the final confirm emits the Card contract's `submit` verb * (`{ kind:'submit', cardId, data:{ selected } }`) with the checked ids in * input order. Emits `ready` on mount and `error` for an unusable definition. */ export declare function TasksCard(props: TasksCardProps): JSX.Element;