or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcore-usage.mddata-management.mdevents.mdindex.mdtemplates.mdtypes.md
tile.json

types.mddocs/

Types

Complete TypeScript interface and type definitions for Choices.js, covering all data structures, configuration options, and utility types.

Core Data Interfaces

Choice Interface

{ .api }
interface Choice {
  id: number;
  label: string;
  value: string;
  selected: boolean;
  disabled: boolean;
  customProperties?: Record<string, any>;
}

Usage:

const choice: Choice = {
  id: 1,
  label: 'Option 1',
  value: 'option1',
  selected: false,
  disabled: false,
  customProperties: {
    category: 'premium',
    price: 29.99,
    description: 'Advanced features included'
  }
};

Item Interface

{ .api }
interface Item extends Choice {
  choiceId: number;
  highlighted: boolean;
}

Usage:

const item: Item = {
  id: 123,
  choiceId: 1,
  label: 'Selected Option',
  value: 'selected',
  selected: true,
  disabled: false,
  highlighted: false,
  customProperties: {
    addedAt: Date.now()
  }
};

Group Interface

{ .api }
interface Group {
  id: number;
  value: string;
  active: boolean;
  disabled: boolean;
  choices?: Choice[];
}

Usage:

const group: Group = {
  id: 1,
  value: 'Fruits',
  active: true,
  disabled: false,
  choices: [
    { id: 1, label: 'Apple', value: 'apple', selected: false, disabled: false },
    { id: 2, label: 'Banana', value: 'banana', selected: false, disabled: false }
  ]
};

Configuration Interfaces

Options Interface

{ .api }
interface Options {
  // Core behavior
  silent: boolean;
  items: (string | Item)[];
  choices: (Choice | Group)[];
  renderSelectedChoices: 'always' | 'auto';
  maxItemCount: number;
  addItems: boolean;
  addItemFilter: string | RegExp | FilterFunction | null;
  removeItems: boolean;
  removeItemButton: boolean;
  editItems: boolean;
  allowHTML: boolean;
  duplicateItemsAllowed: boolean;
  delimiter: string;
  paste: boolean;
  
  // Search configuration  
  searchEnabled: boolean;
  searchChoices: boolean;
  searchFloor: number;
  searchResultLimit: number;
  searchFields: string[] | string;
  
  // Display options
  position: PositionOptionsType;
  resetScrollPosition: boolean;
  shouldSort: boolean;
  shouldSortItems: boolean;
  sorter: (a: Choice | Item, b: Choice | Item) => number;
  placeholder: boolean;
  placeholderValue: string | null;
  searchPlaceholderValue: string | null;
  prependValue: string | null;
  appendValue: string | null;
  renderChoiceLimit: number;
  
  // Text content
  loadingText: string;
  noResultsText: string | StringFunction;
  noChoicesText: string | StringFunction;
  itemSelectText: string;
  uniqueItemText: string | StringFunction;
  customAddItemText: string | StringFunction;
  addItemText: string | StringFunction;
  maxItemText: string | StringFunction;
  
  // Advanced options
  valueComparer: ValueCompareFunction;
  fuseOptions: object;
  labelId: string;
  callbackOnInit: Function | null;
  callbackOnCreateTemplates: Function | null;
  classNames: ClassNames;
}

ClassNames Interface

{ .api }
interface ClassNames {
  containerOuter: string;
  containerInner: string;
  input: string;
  inputCloned: string;
  list: string;
  listItems: string;
  listSingle: string;
  listDropdown: string;
  item: string;
  itemSelectable: string;
  itemDisabled: string;
  itemChoice: string;
  placeholder: string;
  group: string;
  groupHeading: string;
  button: string;
  activeState: string;
  focusState: string;
  openState: string;
  disabledState: string;
  highlightedState: string;
  selectedState: string;
  flippedState: string;
  loadingState: string;
  notice: string;
  addChoice: string;
  noResults: string;
  noChoices: string;
}

Usage:

const customClassNames: Partial<ClassNames> = {
  containerOuter: 'custom-choices',
  input: 'custom-input',
  item: 'custom-item',
  button: 'custom-remove-btn'
};

const choices = new Choices('#select', {
  classNames: {
    ...DEFAULT_CLASSNAMES,
    ...customClassNames
  }
});

Event Type Definitions

EventType Union

{ .api }
type EventType = 
  | 'addItem' 
  | 'removeItem' 
  | 'highlightItem' 
  | 'unhighlightItem'
  | 'choice' 
  | 'change' 
  | 'search' 
  | 'showDropdown' 
  | 'hideDropdown'
  | 'highlightChoice';

Event Detail Interfaces

{ .api }
interface ChangeEventDetail {
  value: string | string[];
}

interface AddItemEventDetail {
  id: number;
  value: string;
  label: string;
  customProperties?: Record<string, any>;
  keyCode?: number;
}

interface RemoveItemEventDetail {
  id: number;
  value: string;
  label: string;
  customProperties?: Record<string, any>;
}

interface ChoiceEventDetail {
  choice: {
    id: number;
    value: string;
    label: string;
    customProperties?: Record<string, any>;
  };
}

interface SearchEventDetail {
  value: string;
  resultCount: number;
}

interface HighlightItemEventDetail {
  id: number;
  value: string;
  label: string;
}

interface UnhighlightItemEventDetail {
  id: number;
  value: string;
  label: string;
}

interface HighlightChoiceEventDetail {
  choice: {
    id: number;
    value: string;
    label: string;
  };
}

Utility Types

Position Options

{ .api }
type PositionOptionsType = 'auto' | 'top' | 'bottom';

Element Type

{ .api }
type PassedElementType = 'text' | 'select-one' | 'select-multiple';

Action Types

{ .api }
type ActionType = 
  | 'ADD_CHOICE'
  | 'FILTER_CHOICES'
  | 'ACTIVATE_CHOICES'
  | 'CLEAR_CHOICES'
  | 'ADD_GROUP'
  | 'ADD_ITEM'
  | 'REMOVE_ITEM'
  | 'HIGHLIGHT_ITEM'
  | 'CLEAR_ALL';

Function Types

{ .api }
type StringFunction = (value?: string) => string;
type NoticeStringFunction = (value: string) => string;
type NoticeLimitFunction = (maxItemCount: number) => string;
type FilterFunction = (value: string) => boolean;
type ValueCompareFunction = (value1: string, value2: string) => boolean;

Usage Examples:

// String function for dynamic text
const addItemText: StringFunction = (value = '') => 
  `Press Enter to add "${value}"`;

// Filter function for validation
const emailFilter: FilterFunction = (value: string) => 
  /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);

// Value comparison function
const caseInsensitiveComparer: ValueCompareFunction = (value1, value2) => 
  value1.toLowerCase() === value2.toLowerCase();

Template Function Types

{ .api }
type TemplateFunction = (...args: any[]) => HTMLElement | string;

interface Templates {
  containerOuter: TemplateFunction;
  containerInner: TemplateFunction;
  itemList: TemplateFunction;
  placeholder: TemplateFunction;
  item: TemplateFunction;
  choiceList: TemplateFunction;
  choiceGroup: TemplateFunction;
  choice: TemplateFunction;
  input: TemplateFunction;
  dropdown: TemplateFunction;
  notice: TemplateFunction;
  option: TemplateFunction;
}

Utility Interfaces

KeyCode Mapping

{ .api }
interface KeyCodeMap {
  BACK_KEY: number;
  DELETE_KEY: number;
  ENTER_KEY: number;
  A_KEY: number;
  ESC_KEY: number;
  UP_KEY: number;
  DOWN_KEY: number;
  PAGE_UP_KEY: number;
  PAGE_DOWN_KEY: number;
}

Usage:

import { KEY_CODES } from 'choices.js';

document.addEventListener('keydown', (event) => {
  switch (event.keyCode) {
    case KEY_CODES.ENTER_KEY:
      // Handle Enter
      break;
    case KEY_CODES.ESC_KEY:
      // Handle Escape
      break;
  }
});

Notice Interface

{ .api }
interface Notice {
  response: boolean;
  notice: string;
}

Usage:

function validateInput(value: string): Notice {
  if (value.length < 3) {
    return {
      response: false,
      notice: 'Input must be at least 3 characters'
    };
  }
  
  return {
    response: true,
    notice: 'Valid input'
  };
}

Generic Types and Utility Types

String to Element Type

{ .api }
type StrToEl = (str: string) => Element;

Partial Configuration Type

{ .api }
type PartialOptions = Partial<Options>;

Usage:

// Only specify options you want to override
const config: PartialOptions = {
  searchEnabled: true,
  maxItemCount: 5,
  removeItemButton: true
};

Choice Creation Types

{ .api }
interface ChoiceInput {
  value: string;
  label: string;
  selected?: boolean;
  disabled?: boolean;
  customProperties?: Record<string, any>;
}

interface GroupInput {
  label: string;
  id?: number;
  disabled?: boolean;
  choices: ChoiceInput[];
}

type ChoicesInput = (ChoiceInput | GroupInput)[];

Usage:

const choicesData: ChoicesInput = [
  {
    value: 'option1',
    label: 'Option 1',
    selected: true
  },
  {
    label: 'Group 1',
    choices: [
      { value: 'grouped1', label: 'Grouped Option 1' },
      { value: 'grouped2', label: 'Grouped Option 2' }
    ]
  }
];

Constants Types

{ .api }
interface Constants {
  EVENTS: Record<EventType, string>;
  ACTION_TYPES: Record<ActionType, string>;
  KEY_CODES: KeyCodeMap;
  TEXT_TYPE: 'text';
  SELECT_ONE_TYPE: 'select-one';
  SELECT_MULTIPLE_TYPE: 'select-multiple';
  SCROLLING_SPEED: number;
}

Advanced Type Usage

Type Guards

function isChoice(item: Choice | Group): item is Choice {
  return 'label' in item && 'value' in item;
}

function isGroup(item: Choice | Group): item is Group {
  return 'choices' in item;
}

function isItem(obj: Choice | Item): obj is Item {
  return 'choiceId' in obj && 'highlighted' in obj;
}

// Usage
choices.forEach(choice => {
  if (isChoice(choice)) {
    console.log('Choice:', choice.label);
  } else if (isGroup(choice)) {
    console.log('Group:', choice.value);
  }
});

Custom Property Types

{ .api }
interface ProductChoice extends Choice {
  customProperties: {
    price: number;
    category: string;
    inStock: boolean;
    rating?: number;
  };
}

interface UserItem extends Item {
  customProperties: {
    userId: number;
    addedAt: number;
    source: 'manual' | 'import' | 'api';
  };
}

Usage:

const productChoices: ProductChoice[] = [
  {
    id: 1,
    label: 'Premium Plan',
    value: 'premium',
    selected: false,
    disabled: false,
    customProperties: {
      price: 29.99,
      category: 'subscription',
      inStock: true,
      rating: 4.8
    }
  }
];

Event Handler Types

type ChoicesEventHandler<T = any> = (event: CustomEvent<T>) => void;

// Specific event handlers
type ChangeEventHandler = ChoicesEventHandler<ChangeEventDetail>;
type AddItemEventHandler = ChoicesEventHandler<AddItemEventDetail>;
type SearchEventHandler = ChoicesEventHandler<SearchEventDetail>;

// Usage
const handleChange: ChangeEventHandler = (event) => {
  const { value } = event.detail;
  console.log('Selection changed to:', value);
};

const handleAddItem: AddItemEventHandler = (event) => {
  const { id, value, label, customProperties } = event.detail;
  console.log(`Added item: ${label} (${value})`);
};

element.addEventListener('change', handleChange);
element.addEventListener('addItem', handleAddItem);

Configuration Builder Type

interface ChoicesConfigBuilder {
  setSearchEnabled(enabled: boolean): ChoicesConfigBuilder;
  setMaxItems(count: number): ChoicesConfigBuilder;
  setPlaceholder(text: string): ChoicesConfigBuilder;
  build(): Options;
}

class ChoicesConfig implements ChoicesConfigBuilder {
  private config: Partial<Options> = {};
  
  setSearchEnabled(enabled: boolean) {
    this.config.searchEnabled = enabled;
    return this;
  }
  
  setMaxItems(count: number) {
    this.config.maxItemCount = count;
    return this;
  }
  
  setPlaceholder(text: string) {
    this.config.placeholderValue = text;
    return this;
  }
  
  build(): Options {
    return { ...DEFAULT_CONFIG, ...this.config };
  }
}

// Usage
const config = new ChoicesConfig()
  .setSearchEnabled(true)
  .setMaxItems(5)
  .setPlaceholder('Choose options...')
  .build();

This comprehensive type system ensures type safety and IntelliSense support when working with Choices.js in TypeScript projects.