UNPKG

clack-tree-select

Version:

Beautiful, interactive, searchable tree selection prompt for Clack CLI apps

171 lines (166 loc) 5.43 kB
import * as _clack_core from '@clack/core'; import { Prompt } from '@clack/core'; import { Readable, Writable } from 'node:stream'; /** * Represents a tree item with optional children and metadata * @template T The type of the value stored in each tree item */ interface TreeItem<T = any> { /** The unique value/identifier for this tree item */ value: T; /** Display name for the item (falls back to string representation of value) */ name?: string; /** Whether this directory should be initially expanded */ open?: boolean; /** Child items - can be TreeItems, strings, or raw values */ children?: TreeItem<T>[] | string[] | T[]; } /** * Options for configuring tree selection behavior */ interface TreeSelectConfig { /** Allow multiple selections */ multiple?: boolean; /** Require at least one selection */ required?: boolean; /** Show help text with keyboard shortcuts */ showHelp?: boolean; /** Enable inline search via typing letters */ searchable?: boolean; /** Custom icons for different item types */ icons?: { directory?: string; file?: string; expanded?: string; collapsed?: string; }; } /** * Complete options for the TreeSelectPrompt * @template T The type of values in the tree */ interface TreeSelectOptions$1<T = any> extends TreeSelectConfig { /** The tree structure to display */ tree: TreeItem<T>[] | string[] | T[]; /** Initial selected values */ initialValues?: T[]; /** Value where cursor should start */ cursorAt?: T; /** Custom validation function */ validate?: (value: T[] | undefined) => string | void; /** Optional render function consumed by Prompt */ render?: () => string; /** Optional runtime fields forwarded to Prompt environment */ signal?: AbortSignal; input?: NodeJS.ReadStream; output?: NodeJS.WriteStream; } interface FlatTreeItem<T> { value: T; name: string; level: number; isDirectory: boolean; isOpen: boolean; parent?: FlatTreeItem<T>; originalItem: TreeItem<T>; } /** * Minimal TreeSelectPrompt for testing */ declare class TreeSelectPrompt<T> extends Prompt<T[]> { tree: TreeItem<T>[]; flatTree: FlatTreeItem<T>[]; cursor: number; multiple: boolean; config: TreeSelectConfig; searchQuery: string; isSearching: boolean; constructor(opts: TreeSelectOptions$1<T>); private normalizeTree; private normalizeTreeItem; private rebuildFlatTree; /** Build a flattened list of the entire tree ignoring open/closed state */ private buildFullFlatTree; /** Return the list of items currently visible (search-filtered or by open state) */ getVisibleFlatTree(): FlatTreeItem<T>[]; /** Fuzzy match: query (spaces removed) must appear in order within name (spaces removed) */ private isFuzzyMatch; private toggleDirectory; private toggleSelection; private selectChildren; private deselectChildren; private expandAll; private collapseAll; private selectAll; private deselectAll; private areAllDirectoriesExpanded; private areAllItemsSelected; private toggleExpandAll; private toggleSelectAll; private handleCursor; getState(): { value: T[] | undefined; cursor: number; state: _clack_core.State; flatTree: FlatTreeItem<T>[]; searchQuery: string; isSearching: boolean; }; } interface CommonOptions { input?: Readable; output?: Writable; signal?: AbortSignal; } interface TreeSelectOptions<Value> extends CommonOptions { message: string; tree: TreeItem<Value>[] | Value[]; multiple?: boolean; initialValues?: Value[]; required?: boolean; cursorAt?: Value; maxItems?: number; onlyShowDirectories?: boolean; /** Enable search functionality (default: true for better UX) */ searchable?: boolean; /** Maximum tree depth to display (default: Infinity) */ maxDepth?: number; /** Custom icons for different item types */ icons?: { directory?: string; file?: string; expanded?: string; collapsed?: string; }; /** Show help text with keyboard shortcuts */ showHelp?: boolean; } interface FileSystemTreeOptions extends Omit<TreeSelectOptions<string>, 'tree'> { root: string; includeFiles?: boolean; includeHidden?: boolean; maxDepth?: number; filter?: (path: string) => boolean; } /** * Build a tree structure from a file system path */ declare function buildFileSystemTree(rootPath: string, options?: { includeFiles?: boolean; includeHidden?: boolean; maxDepth?: number; filter?: (path: string) => boolean; currentDepth?: number; }): TreeItem<string>[]; /** * Create a tree-select prompt for file system navigation */ declare const fileSystemTreeSelect: (opts: FileSystemTreeOptions) => Promise<symbol | string[]>; /** * Create a beautiful tree-select prompt with enhanced UX * @param opts Configuration options for the tree select * @returns Promise resolving to selected values */ declare const treeSelect: <Value>(opts: TreeSelectOptions<Value>) => Promise<symbol | Value[]>; export { TreeSelectPrompt, buildFileSystemTree, fileSystemTreeSelect, treeSelect }; export type { TreeSelectOptions$1 as CoreTreeSelectOptions, FileSystemTreeOptions, TreeItem, TreeSelectOptions };