Overview

Triggers actions and commands with keyboard and mouse support.

Installation

npm i nikcli-tui

Import

import { Button } from 'nikcli-tui';

Quick Start

new Button({ parent: screen, text: 'Primary', variant: 'primary', onClick: () => console.log('clicked') });

Live Preview

Run Locally

npm run tsx:core-gallery

Production Examples

import blessed from 'blessed';
import { Button } from 'nikcli-tui';
const screen = blessed.screen({ smartCSR: true, title: 'Button Demo' });
screen.key(['q','C-c'], () => process.exit(0));

new Button({ parent: screen, top: 1, left: 2, text: 'Default' });
new Button({ parent: screen, top: 1, left: 14, text: 'Primary', variant: 'primary' });
new Button({ parent: screen, top: 1, left: 28, text: 'Danger', variant: 'destructive' });
new Button({ parent: screen, top: 3, left: 2, text: 'XS', size: 'xs' });
new Button({ parent: screen, top: 3, left: 12, text: 'SM', size: 'sm' });
new Button({ parent: screen, top: 3, left: 22, text: 'LG', size: 'lg' });
screen.render();

Props

Button-specific Props

PropertyTypeRequiredDefaultDescription
childrenstring | anyNo-Button content text or child components (shadcn-style)
textstringNo-Button text (from component-schemas.ts)
type"button" | "submit" | "reset"No"button"Button type for form handling
onClick() => voidNo-Click event handler
loadingbooleanNofalseShow loading state
loadingTextstringNo"Loading..."Text displayed during loading
iconstringNo-Icon or glyph to display with text
iconPosition"left" | "right"No"left"Icon placement relative to text
fullWidthbooleanNofalseExpand to 100% parent width
pressedbooleanNo-Pressed state (from component-schemas)
hoverbooleanNo-Hover state (from component-schemas)

Inherited Base Props

The Button component extends BasePropsSchema and includes all standard TUI component properties:
PropertyTypeDefaultDescription
parentblessed.Widgets.Node-Parent blessed element
classNamestring-CSS-like class name for styling
idstring-Unique identifier
variantComponentVariant"default"Component variant (primary, secondary, destructive, outline, ghost, link, success, warning, error, info)
sizeComponentSize-Component size (xs, sm, md, lg, xl)
disabledbooleanfalseWhether component is disabled
hiddenbooleanfalseWhether component is hidden
focusablebooleantrueWhether component can receive focus
keysbooleantrueEnable keyboard input
mousebooleantrueEnable mouse input

Layout & Positioning Props

PropertyTypeDescription
topTerminalUnitTop position
leftTerminalUnitLeft position
rightTerminalUnitRight position
bottomTerminalUnitBottom position
widthTerminalUnitComponent width (or 100% if fullWidth=true)
heightTerminalUnitComponent height
paddingPaddingConfigInternal spacing
marginPaddingConfigExternal spacing

Style Props

PropertyTypeDescription
bgColorValueBackground color
fgColorValueForeground color
borderBorderStyleBorder configuration
borderColorColorValueBorder color
borderStyle"line" | "double" | "round" | "bold" | "classic" | "none"Border style helper
styleTextStyleText styling (bold, underline, etc.)
animationAnimationTypeAnimation type

Zod Schema Validation

The Button component uses Zod for runtime type validation:
import { ButtonSchema } from 'nikcli-tui';

const ButtonSchema = BasePropsSchema.extend({
  // Content (shadcn-style: can be string or children)
  children: z.union([z.string(), z.any()]).optional(),
  
  // Button behavior
  type: z.enum(["button", "submit", "reset"]).optional(),
  onClick: z.function().returns(z.void()).optional(),
  
  // Loading state
  loading: z.boolean().optional(),
  loadingText: z.string().optional(),
  
  // Icon support
  icon: z.string().optional(),
  iconPosition: z.enum(["left", "right"]).optional(),
  
  // Layout
  fullWidth: z.boolean().optional(),
  
  // Button-specific blessed props
  blessedProps: z.object({}).passthrough().optional(),
}).strict();

Methods

Instance Methods

MethodParametersReturn TypeDescription
setTexttext: stringvoidUpdates the button label content
setLoadingloading: boolean, loadingText?: stringvoidToggle loading state with optional custom text
setDisableddisabled: booleanvoidEnable or disable the button
setIconicon: string, position?: "left" | "right"voidSet button icon and optional position
destroy-voidCleanup method from base component

Inherited Methods (from BaseComponent)

MethodParametersReturn TypeDescription
setVariantvariant: ComponentVariantvoidUpdates component variant
setSizesize: ComponentSizevoidUpdates component size
setStatestate: ComponentStatevoidUpdates component state (default, hover, focus, active, disabled, loading)
getConfig-ComponentConfigReturns current configuration
updateprops: Partial<ButtonProps>voidUpdates component properties with re-render

Static Methods

MethodParametersReturn TypeDescription
Button.createprops: ButtonPropsButtonFactory method to create new button instance
Button.createGroupbuttons: ButtonProps[], options?: GroupOptionsButton[]Create multiple buttons with automatic positioning

GroupOptions Interface

interface GroupOptions {
  direction?: "horizontal" | "vertical"; // Default: "horizontal"
  spacing?: number; // Default: 1
}

Keyboard

  • press: triggered by Enter/Space when focused (blessed default).
  • Focus navigation via Tab/Shift+Tab if focusable.

Theming

  • Supports BaseProps variant, size, tone and theme overrides.
  • Honors borderStyle and style overrides via blessedProps.style.

Variants & Sizes Reference

  • Variants: default, destructive, outline, secondary, ghost, link, success, warning, info, primary.
  • Sizes: xs, sm, md, lg, xl.
  • States: default, hover, focus, active, disabled, loading.

Testing

const btn = new Button({ parent: screen, text: 'Save' });
btn.setDisabled(true);
expect(btn.getConfig().variant).toBeDefined();
btn.setText('Save All');

Best Practices

  • Keep labels concise; prefer icons only when universally understood.
  • Use fullWidth for forms and primary actions on narrow layouts.