Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hip-dancers-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clack/prompts": patch
---

docs: add missing jsdoc comments
82 changes: 72 additions & 10 deletions packages/prompts/src/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,41 @@ function getSelectedOptions<T>(values: T[], options: Option<T>[]): Option<T>[] {
return results;
}

/**
* Options for the {@link autocomplete} component
*/
interface AutocompleteSharedOptions<Value> extends CommonOptions {
/**
* The message to display to the user.
*/
message: string;

/**
* Available options for the autocomplete prompt.
* The options to present, or a function that returns the options to present
* allowing for custom search/filtering.
*
* @see https://bomb.sh/docs/clack/packages/prompts/#dynamic-options-getter
*/
options: Option<Value>[] | ((this: AutocompletePrompt<Option<Value>>) => Option<Value>[]);

/**
* Maximum number of items to display at once.
*/
maxItems?: number;

/**
* Placeholder text to display when no input is provided.
* Placeholder text displayed when the search field is empty. When set, pressing
* tab copies the placeholder into the input.
*/
placeholder?: string;

/**
* Validates the value
* Allows custom validation of the value
*/
validate?: (value: Value | Value[] | undefined) => string | Error | undefined;

/**
* Custom filter function to match options against search input.
* If not provided, a default filter that matches label, hint, and value is used.
* Custom filter function to match options against the search input.
*/
filter?: (search: string, option: Option<Value>) => boolean;
}
Expand All @@ -74,12 +85,38 @@ export interface AutocompleteOptions<Value> extends AutocompleteSharedOptions<Va
* The initial selected value.
*/
initialValue?: Value;

/**
* The initial user input
* The initial text pre-filled in the search field.
*/
initialUserInput?: string;
}

/**
* The `autocomplete` prompt combines a text input with a searchable list of options.
* It's perfect for when you have a large list of options and want to help users
* find what they're looking for quickly.
*
* @see https://bomb.sh/docs/clack/packages/prompts/#autocomplete
*
* @example
* ```ts
* import { autocomplete } from '@clack/prompts';
*
* const framework = await autocomplete({
* message: 'Search for a framework',
* options: [
* { value: 'next', label: 'Next.js', hint: 'React framework' },
* { value: 'astro', label: 'Astro', hint: 'Content-focused' },
* { value: 'svelte', label: 'SvelteKit', hint: 'Compile-time framework' },
* { value: 'remix', label: 'Remix', hint: 'Full stack framework' },
* { value: 'nuxt', label: 'Nuxt', hint: 'Vue framework' },
* ],
* placeholder: 'Type to search...',
* maxItems: 5,
* });
* ```
*/
export const autocomplete = <Value>(opts: AutocompleteOptions<Value>) => {
const prompt = new AutocompletePrompt({
options: opts.options,
Expand Down Expand Up @@ -223,20 +260,45 @@ export const autocomplete = <Value>(opts: AutocompleteOptions<Value>) => {
return prompt.prompt() as Promise<Value | symbol>;
};

// Type definition for the autocompleteMultiselect component
/**
* Options for the {@link autocompleteMultiselect} component
*/
export interface AutocompleteMultiSelectOptions<Value> extends AutocompleteSharedOptions<Value> {
/**
* The initial selected values
* The initially selected values.
*/
initialValues?: Value[];

/**
* If true, at least one option must be selected
* When `true`, at least one option must be selected.
* @default false
*/
required?: boolean;
}

/**
* Integrated autocomplete multiselect - combines type-ahead filtering with multiselect in one UI
* The `autocompleteMultiselect` combines the search functionality of autocomplete
* with the ability to select multiple options.
*
* @see https://bomb.sh/docs/clack/packages/prompts/#autocomplete-multiselect
*
* @example
* ```ts
* import { autocompleteMultiselect } from '@clack/prompts';
*
* const frameworks = await autocompleteMultiselect({
* message: 'Select frameworks',
* options: [
* { value: 'next', label: 'Next.js', hint: 'React framework' },
* { value: 'astro', label: 'Astro', hint: 'Content-focused' },
* { value: 'svelte', label: 'SvelteKit', hint: 'Compile-time framework' },
* { value: 'remix', label: 'Remix', hint: 'Full stack framework' },
* { value: 'nuxt', label: 'Nuxt', hint: 'Vue framework' },
* ],
* placeholder: 'Type to search...',
* maxItems: 5,
* });
* ```
*/
export const autocompleteMultiselect = <Value>(opts: AutocompleteMultiSelectOptions<Value>) => {
const formatOption = (
Expand Down
76 changes: 66 additions & 10 deletions packages/prompts/src/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,66 @@ import {
S_CORNER_TOP_RIGHT,
} from './common.js';

/**
* Alignment for content or titles within the box.
*/
export type BoxAlignment = 'left' | 'center' | 'right';

type BoxSymbols = [topLeft: string, topRight: string, bottomLeft: string, bottomRight: string];

const roundedSymbols: BoxSymbols = [
S_CORNER_TOP_LEFT,
S_CORNER_TOP_RIGHT,
S_CORNER_BOTTOM_LEFT,
S_CORNER_BOTTOM_RIGHT,
];
const squareSymbols: BoxSymbols = [S_BAR_START, S_BAR_START_RIGHT, S_BAR_END, S_BAR_END_RIGHT];

/**
* Options for the {@link box} component
*/
export interface BoxOptions extends CommonOptions {
/**
* Alignment of the content (`'left'`, `'center'`, or `'right'`).
* @default 'left'
*/
contentAlign?: BoxAlignment;

/**
* Alignment of the title (`'left'`, `'center'`, or `'right'`).
* @default 'left'
*/
titleAlign?: BoxAlignment;

/**
* Box width. Use `'auto'` to fit content or a number for a fraction of the terminal width.
*/
width?: number | 'auto';

/**
* Padding around the title.
* @default 1
*/
titlePadding?: number;

/**
* Padding around the content.
* @default 2
*/
contentPadding?: number;

/**
* Use rounded corners when `true`, square corners when `false`.
* @default true
*/
rounded?: boolean;

/**
* Custom function to style the border characters.
*/
formatBorder?: (text: string) => string;
}

type BoxSymbols = [topLeft: string, topRight: string, bottomLeft: string, bottomRight: string];

const roundedSymbols: BoxSymbols = [
S_CORNER_TOP_LEFT,
S_CORNER_TOP_RIGHT,
S_CORNER_BOTTOM_LEFT,
S_CORNER_BOTTOM_RIGHT,
];
const squareSymbols: BoxSymbols = [S_BAR_START, S_BAR_START_RIGHT, S_BAR_END, S_BAR_END_RIGHT];

function getPaddingForLine(
lineLength: number,
innerWidth: number,
Expand All @@ -59,6 +97,24 @@ function getPaddingForLine(

const defaultFormatBorder = (text: string) => text;

/**
* Renders a customizable box around text content. It's similar to `note` but offers
* more styling options.
*
* @see https://bomb.sh/docs/clack/packages/prompts/#box
*
* @example
* ```ts
* import { box } from '@clack/prompts';
*
* box('This is the content of the box', 'Box Title', {
* contentAlign: 'center',
* titleAlign: 'center',
* width: 'auto',
* rounded: true,
* });
* ```
*/
export const box = (message = '', title = '', opts?: BoxOptions) => {
const output: Writable = opts?.output ?? process.stdout;
const columns = getColumns(output);
Expand Down
Loading
Loading