npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nlxai/touchpoint-ui

v1.2.5

Published

Web UI for Touchpoint

Readme

Touchpoint

Touchpoint UI provides a customizable chat interface that you can embed in your web applications. Touchpoint UI allows users to interact with your application and provides a seamless conversational experience.

npm i --save @nlxai/touchpoint-ui
import { create } from "@nlxai/touchpoint-ui";

const touchpoint = await create({
  config: {
    host: "REPLACE_WITH_HOST",
    deploymentKey: "REPLACE_WITH_DEPLOYMENT_KEY",
    channelKey: "REPLACE_WITH_CHANNEL_KEY",
    headers: {
      "nlx-api-key": "REPLACE_WITH_API_KEY",
    },
    languageCode: "en-US",
    userId: "REPLACE_WITH_USER_ID",
  },
  colorMode: "light",
  input: "voice",
  theme: { fontFamily: '"Neue Haas Grotesk", sans-serif', accent: "#AECAFF" },
});

Basics

create()

function create(props): Promise<TouchpointInstance>;

Creates a new Touchpoint UI instance and appends it to the document body

Parameters

props

TouchpointConfiguration

Configuration props for Touchpoint

Returns

Promise<TouchpointInstance>

A promise that resolves to a TouchpointInstance


TouchpointConfiguration

Main Touchpoint creation properties object

Properties

config
config: Config;

Connection information for the @nlxai/core conversation handler

windowSize?
optional windowSize: "full" | "half";

Optional window size for the chat window, defaults to half

colorMode?
optional colorMode: "dark" | "light" | "light dark";

Optional color mode for the chat window, defaults to dark. Setting light dark enables automatic switching based on system settings.

brandIcon?
optional brandIcon: string;

URL of icon used to display the brand in the chat header

animate?
optional animate: boolean;

Include border animation. Currently only supported in Voice Mini.

launchIcon?
optional launchIcon:
  | string
  | boolean
  |
  | ComponentClass<{
  className?: string;
  onClick?: () => void;
}, any>
  | FunctionComponent<{
  className?: string;
  onClick?: () => void;
}>;

URL of icon used on the launch icon in the bottom right when the experience is collapsed.

When set to false, no launch button is shown at all. When not set or set to true, the default launch icon is rendered.

userMessageBubble?
optional userMessageBubble: boolean;

Specifies whether the user message has bubbles or not

agentMessageBubble?
optional agentMessageBubble: boolean;

Specifies whether the agent message has bubbles or not

chatMode?
optional chatMode: boolean;

Enables chat mode, a classic chat experience with inline loaders and the chat history visible at all times.

theme?
optional theme: Partial<Theme>;

Optional theme object to override default theme values

modalityComponents?
optional modalityComponents: Record<string, CustomModalityComponent<unknown>>;

Optional custom modality components to render in Touchpoint

initializeConversation()?
optional initializeConversation: (handler, context?) => void;

Custom conversation init method. Defaults to sending the welcome flow.

Parameters
handler

ConversationHandler

the conversation handler.

context?

Context

the context object

Returns

void

input?
optional input: "text" | "external" | "voice" | "voiceMini";

Controls the ways in which the user can communicate with the application. Defaults to "text"

showVoiceTranscript?
optional showVoiceTranscript: boolean;

Sets whether the transcript is shown in voice and voiceMini inputs.

initialContext?
optional initialContext: Context;

Context sent with the initial request.

bidirectional?
optional bidirectional: BidirectionalConfig;

Enables bidirectional mode of voice+. Will automatically set the bidirectional flag in the config.

copy?
optional copy: Partial<Copy>;

Copy


TouchpointInstance

Instance of a Touchpoint UI component

Properties

expanded
expanded: boolean;

Controls whether the Touchpoint UI is expanded or collapsed

conversationHandler
conversationHandler: ConversationHandler;

The conversation handler instance for interacting with the application

teardown()
teardown: () => void;

Method to remove the Touchpoint UI from the DOM

Returns

void

setCustomBidirectionalCommands()
setCustomBidirectionalCommands: (commands) => void;

Sets currently available custom bidirectional commands. This allows you to define custom commands that can be used in the voice bot. The commands will be available in the voice bot and can be used to trigger actions.

Example:

client.setCustomBidirectionalCommands([
  {
    action: "Meal",
    description: "add a meal to your flight",
    schema: {
      enum: ["standard", "vegetarian", "vegan", "gluten-free"],
    },
    handler: (value) => {
      console.log("Meal option:", value);
    },
  },
]);

This will allow the voice bot to use the command Meal with the value standard, vegetarian, vegan, or gluten-free.

When using more complex arguments, a library such as Zod can be useful:

import * as z from "zod/v4";

const schema = z.object({
  name: z.string().describe("The customer's name, such as John Doe"),
  email: z.string().email().describe("The customer's email address"),
});

client.setCustomBidirectionalCommands([
  {
    action: "Meal",
    description: "add a meal to your flight",
    schema: z.toJSONSchema(schema, { io: "input" }),
    handler: (value) => {
      const result = z.safeParse(schema, value);
      if (result.success) {
        // result.data is now type safe and TypeScript can reason about it
        console.log("Meal option:", result.data);
      } else {
        console.error("Failed to parse Meal option:", result.error);
      }
    },
  },
]);
Parameters
commands

BidirectionalCustomCommand[]

A list containing the custom commands to set.

Returns

void

Theming

Theme

The full theme expressed as CSS custom properties. This means that for instance colors can be made to switch automatically based on the system color mode by using the light-dark() CSS function. Note also that not all colors need to be provided manually. For instance if only primary is provided, the rest of the primary colors will be computed automatically based on it. Therefore, for a fully custom but minimal theme, you only need to provide accent, primary, secondary, background, overlay, and potentially the warning and error colors.

Example

const theme: Partial<Theme> = {
  primary: "light-dark(rgb(0, 2, 9), rgb(255, 255, 255))",
  secondary: "light-dark(rgb(255, 255, 255), rgb(0, 2, 9))",
  accent: "light-dark(rgb(28, 99, 218), rgb(174, 202, 255))",
  background: "light-dark(rgba(220, 220, 220, 0.9), rgba(0, 2, 9, 0.9))",
};

Properties

fontFamily
fontFamily: string;

Font family

primary
primary: string;

Primary color

primary90
primary90: string;

Primary color with 90% opacity

primary80
primary80: string;

Primary color with 80% opacity

primary60
primary60: string;

Primary color with 60% opacity

primary40
primary40: string;

Primary color with 40% opacity

primary20
primary20: string;

Primary color with 20% opacity

primary10
primary10: string;

Primary color with 10% opacity

primary5
primary5: string;

Primary color with 5% opacity

primary1
primary1: string;

Primary color with 1% opacity

secondary
secondary: string;

Secondary color

secondary90
secondary90: string;

Secondary color with 90% opacity

secondary80
secondary80: string;

Secondary color with 80% opacity

secondary60
secondary60: string;

Secondary color with 60% opacity

secondary40
secondary40: string;

Secondary color with 40% opacity

secondary20
secondary20: string;

Secondary color with 20% opacity

secondary10
secondary10: string;

Secondary color with 10% opacity

secondary5
secondary5: string;

Secondary color with 5% opacity

secondary1
secondary1: string;

Secondary color with 1% opacity

accent
accent: string;

Accent color used e.g. for prominent buttons, the loader animation as well as selected card outlines

accent20
accent20: string;

Accent color with 20% opacity

background
background: string;

The background color of the main Touchpoint interface

overlay
overlay: string;

The color of the overlay covering the visible portion of the website when the Touchpoint interface does not cover the full screen

warningPrimary
warningPrimary: string;

Primary warning color

warningSecondary
warningSecondary: string;

Secondary warning color

errorPrimary
errorPrimary: string;

Primary error color

errorSecondary
errorSecondary: string;

Secondary error color

innerBorderRadius
innerBorderRadius: string;

Inner border radius: used for most buttons

outerBorderRadius
outerBorderRadius: string;

Outer border radius: generally used for elements that contain buttons that have inner border radius. Also used by the launch button.

Modality components

Ripple

const Ripple: FC<{
  className?: string;
  style?: CSSProperties;
}>;

A ripple effect composed of expanding circles.


Carousel

const Carousel: FC<{
  className?: string;
  children?: ReactNode;
}>;

Renders a carousel of cards.

Example

import {
  Carousel,
  CustomCard,
  CustomCardImageRow,
  React,
} from "@nlx/touchpoint-ui";

const MyCarousel = ({ data }) => (
  <Carousel>
    {data.map((item) => (
      <CustomCard key={item.id}>
        <CustomCardImageRow src={item.image} alt={item.description} />
      </CustomCard>
    ))}
  </Carousel>
);

CustomCard

const CustomCard: FC<{
  className?: string;
  children: ReactNode;
  selected?: boolean;
  onClick?: () => void;
  href?: string;
  newTab?: boolean;
}>;

A customizable card component that can function as a button or link.

Example

import {
  CustomCard,
  CustomCardImageRow,
  CustomCardRow,
  React,
} from "@nlx/touchpoint-ui";

const MyCard = ({ data }) => (
  <CustomCard selected={data.active} onClick={() => alert("Card clicked!")}>
    <CustomCardImageRow
      src="https://example.com/image.jpg"
      alt="Example Image"
    />
    <CustomCardRow
      left={<div>Left Content</div>}
      right={<div>Right Content</div>}
      icon={MyIcon}
    />
  </CustomCard>
);

CustomCardImageRow

const CustomCardImageRow: FC<{
  src: string;
  alt?: string;
}>;

A row within a CustomCard that displays an image.


CustomCardRow

const CustomCardRow: FC<{
  left: ReactNode;
  right: ReactNode;
  icon?: Icon;
  className?: string;
}>;

A row within a CustomCard that displays left and right content, with an optional centered icon.

Example

import { CustomCardRow, Icons, BaseText, React } from "@nlx/touchpoint-ui";

const MyCardRow = () => (
  <CustomCardRow
    left={<BaseText>Left Content</BaseText>}
    right={<BaseText>Right Content</BaseText>}
    icon={Icons.ArrowRight}
  />
);

DateInput

const DateInput: FC<{
  onSubmit?: (date) => void;
  className?: string;
}>;

A date input

Example

import { DateInput, React } from "@nlx/touchpoint-ui";

const MyDateInput = ({ conversationHandler }) => (
  <DateInput
    onSubmit={(date) => conversationHandler.sendContext({ myDate: date })}
  />
);

IconButtonType

type IconButtonType =
  | "main"
  | "ghost"
  | "activated"
  | "coverup"
  | "error"
  | "overlay";

Represents the different types of icon buttons available in the application.

  • main: The primary icon button.
  • ghost: A transparent or less prominent icon button.
  • activated: An icon button that indicates an active state.
  • coverup: An icon button used to cover up or mask something.
  • overlay: An icon button that appears over other content.

IconButton

const IconButton: FC<{
  onClick?: MouseEventHandler<HTMLButtonElement>;
  label: string;
  className?: string;
  type: IconButtonType;
  Icon: FC<IconProps>;
}>;

A button showing only an icon (textual label is provided for accessibility)

Example

import { IconButton, Icons, React } from "@nlx/touchpoint-ui";

const MyIconButton = () => (
  <IconButton
    label="Send message"
    onClick={() => alert("Icon button clicked!")}
    type="main"
    Icon={Icons.ArrowForward}
  />
);

TextButton

const TextButton: FC<{
  onClick?: () => void;
  label: string;
  className?: string;
  type?: "main" | "ghost";
  Icon: FC<IconProps>;
}>;

A button with a visible textual label

Example

import { TextButton, ArrowForward, React } from "@nlx/touchpoint-ui";

const MyTextButton = ({ onClickHandler }) => (
  <TextButton onClick={onClickHandler} label="Continue" />
);

BaseText

const BaseText: FC<{
  children: ReactNode;
  faded?: boolean;
  className?: string;
}>;

Standard text component with base typography styles applied.

Example

import { BaseText, React } from "@nlx/touchpoint-ui";

const MyText = () => <BaseText faded>This is some standard text.</BaseText>;

SmallText

const SmallText: FC<{
  children: ReactNode;
  className?: string;
}>;

Small text component with smaller typography styles applied.


html()

const html: (strings, ...values) => unknown;

A tagged literal for creating reactive elements for custom modalities. It already knows about all Touchpoint UI components, so you can use them directly without the need to import them. Also very useful when using Touchpoint directly from CDN or in projects without a build step.

Parameters

strings

TemplateStringsArray

values

...any[]

Returns

unknown

Example

import { html, Icons } from "@nlx/touchpoint-ui";

const MyCustomModality = ({ data, conversationHandler }) =>
  html`<div style="display: flex; gap: 8px;">
    <IconButton
      label="Cancel"
      Icon=${Icons.Close}
      type="ghost"
      onClick=${cancel()}
    />
    <TextButton
      label="Submit"
      Icon=${Icons.ArrowForward}
      type="main"
      onClick=${() => conversationHandler.sendText("Button clicked!")}
    />
  </div>`;

CustomModalityComponent

type CustomModalityComponent<Data> = ComponentType<{
  data: Data;
  conversationHandler: ConversationHandler;
  className?: string;
  renderedAsOverlay?: boolean;
}>;

Custom Modalities allow rendering of rich user interfaces directly inside a conversation. A custom modality component is a React component. It will receive the modality data as a data prop, along with the conversation handler instance to interact with the conversation as conversationHandler prop.

Type Parameters

Data

Data

The type of the modality being rendered by this component.

Bidirectional Voice+

InteractiveElementInfo

Accessibility information with ID

Indexable

[key: string]: any

Properties

id
id: string;

Form element ID (assigned by the analysis logic, not necessarily equal to the DOM ID)


PageForms

Page forms with elements

Properties

context
context: InteractiveElementInfo[];

Page context

formElements
formElements: Record<string, Element>;

Form element references


analyzePageForms()

function analyzePageForms(): PageForms;

Analyze page forms

Returns

PageForms

Context and state about all the form elements detected on the page using accessibility APIs.


PageState

Internal state that the automatic context maintains.

Properties

formElements
formElements: Record<string, Element>;

Mapping from form element IDs to their DOM elements

links
links: Record<string, string>;

Mapping from link element names to their URLs

customCommands
customCommands: Map<string, (arg) => void>;

Mapping from custom commands to their handlers


BidirectionalContext

Bidirectional context information that is sent to the LLM.

Properties

uri?
optional uri: string;

Identifier for which page you are currently on. This can be used to filter the relevant KB pages.

fields?
optional fields: InteractiveElementInfo[];

The active form fields that can be filled in.

destinations?
optional destinations: string[];

Human readable location names that can be navigated to.

actions?
optional actions: object[];

Custom actions that can be performed.

action
action: string;

The name of the command, used to invoke it.

description?
optional description: string;

A short description of the command

schema?
optional schema: any;

A schema for validating the command's input. Should follow the JSON Schema specification.


BidirectionalConfig

type BidirectionalConfig =
  | {
      automaticContext?: true;
      navigation?: (action, destination, destinations) => void;
      input?: (fields, pageFields) => void;
      custom?: (action, payload) => void;
      customizeAutomaticContext?: (arg) => object;
    }
  | {
      automaticContext: false;
      navigation?: (action, destination?) => void;
      input?: (fields) => void;
      custom?: (action, payload) => void;
    };

Configuration for bidirectional mode of voice+.

Type Declaration

{
  automaticContext?: true;
  navigation?: (action, destination, destinations) => void;
  input?: (fields, pageFields) => void;
  custom?: (action, payload) => void;
  customizeAutomaticContext?: (arg) => object;
}
automaticContext?
optional automaticContext: true;

Attempt to gather and send page context automatically. This will work well on semantically coded pages without too many custom form controls. This enables a number of automatic features.

Defaults to true.

navigation()?
optional navigation: (action, destination, destinations) => void;

Navigation handler for bidirectional mode.

The default implementation will navigate to those pages using standard window.location APIs.

Parameters
action

The navigation action to perform.

"page_next" | "page_previous" | "page_custom" | "page_unknown"

destination

The name of the destination to navigate to if action is "page_custom".

string | undefined

destinations

Record<string, string>

A map of destination names to URLs for custom navigation.

Returns

void

input()?
optional input: (fields, pageFields) => void;

A callback for filling out form fields in bidirectional mode.

The default implementation will fill out the form fields using standard DOM APIs.

Parameters
fields

object[]

An array of field objects with id and value properties.

pageFields

Record<string, Element>

A map of field IDs to DOM elements for custom form filling.

Returns

void

~~custom()?~~
optional custom: (action, payload) => void;

A callback for custom actions in bidirectional mode.

Parameters
action

string

The custom name of your action.

payload

unknown

The payload defined for the custom action.

Returns

void

Deprecated

Use TouchpointInstance.setCustomBidirectionalCommands instead.

customizeAutomaticContext()?
optional customizeAutomaticContext: (arg) => object;

A callback for customizing the automatic context gathering.

This allows you to modify the context and state before they are sent to the LLM.

Parameters
arg
context

BidirectionalContext

state

PageState

Returns

The modified context and state. If the state is identical to the previous state, the call to the server will be skipped.

context
context: BidirectionalContext;

The current context being sent to the LLM

state
state: PageState;

The current state of the page - this is stuff not sent to the LLM, but needed to connect the results back to actions to take on the page.

{
  automaticContext: false;
  navigation?: (action, destination?) => void;
  input?: (fields) => void;
  custom?: (action, payload) => void;
}
automaticContext
automaticContext: false;

Disable gathering page context automatically.

navigation()?
optional navigation: (action, destination?) => void;

Navigation handler for bidirectional mode. Without automatic context there is no default implementation.

Parameters
action

The navigation action to perform.

"page_next" | "page_previous" | "page_custom" | "page_unknown"

destination?

string

The name of the destination to navigate to if action is "page_custom".

Returns

void

input()?
optional input: (fields) => void;

A callback for filling out form fields in bidirectional mode. Without automatic context there is no default implementation.

Parameters
fields

object[]

An array of field objects with id and value properties.

Returns

void

custom()?
optional custom: (action, payload) => void;

A callback for custom actions in bidirectional mode.

Parameters
action

string

The custom name of your action.

payload

unknown

The payload defined for the custom action.

Returns

void


BidirectionalCustomCommand

During a Voice+ bidirectional conversation, you can indicate to the application the availability of custom commands that the user can invoke.

Properties

action
action: string;

The name of the command, used to invoke it. Should be unique and descriptive in the context of the LLM.

description?
optional description: string;

A short description of the command, used to help the LLM understand its purpose.

If omitted, then the command will not be sent to the application and must be triggered from the application side.

schema?
optional schema: any;

A JSON Schema that defines the structure of the command's input.

Use descriptive names and description fields to give the underlying LLM plenty of context for it to generate reasonable parameters. Note that the LLM output will be validated (and transformed) with this schema, so you are guaranteed type safe inputs to your handler.

Should follow the JSONSchema specification.

handler()
handler: (value) => void;

A handler that will be called with an argument matching the schema when the command is invoked.

Parameters
value

any

Returns

void

Utilities

version

const version: string = packageJson.version;

Package version

Embedded mode

Touchpoint UI also registers a custom element called <nlx-touchpoint>, which you can include in your UI. This element has a writeable property touchpointConfiguration that accepts the same input as create.

This start touchpoint in embedded mode, in which there is no open button and touchpoint will follow whatever layout you give it, making it easier to integrate into various awkward situations.

Since it is a custom element, it by default isn't a block element, so you may want to give it:

nlx-touchpoint {
  display: block;
  height: 100%;
}

or similar styling.