LocalMode /ui
Input Controls

Mask Token Input

A fill-mask / cloze textarea that detects a configurable mask token, highlights the mask span inline, validates, randomizes a sample, and submits on Cmd+Enter.

Mask Token Input

The Mask Token Input is a textarea for fill-mask / cloze input. It detects a configurable mask token (default [MASK]), renders an inline highlighted preview with the mask span accented, shows a validation hint (Mask detected vs Add [MASK]), offers a randomize button that inserts a valid sample, and surfaces a Cmd+Enter badge for one-key submit.

It is presentational and portable — pair its value / onSubmit with any fill-mask backend to run predictions and render the returned fills. With LocalMode you can (optionally) wire it to useFillMask() from @localmode/react.

When to use it: any masked-language task — "The capital of France is [MASK]." → top predictions.

Preview

Installation

pnpm dlx shadcn@latest add @localmode/ui/input-controls/mask-token-input
npx shadcn@latest add @localmode/ui/input-controls/mask-token-input
yarn dlx shadcn@latest add @localmode/ui/input-controls/mask-token-input
bunx --bun shadcn@latest add @localmode/ui/input-controls/mask-token-input

Dependencies

  • Data source: renders the value you pass and emits onChange / onSubmit callbacks — works with any backend. Recommended LocalMode producer: useFillMask (optional).
  • No npm dependencies (only the shared cn() util via @localmode/ui/lib/utils).

Files installed

  • mask-token-input.tsx — the component
  • lib/utils.ts — the cn() helper (if not already present)

Props

MaskTokenInput

Prop

Type

Examples

Wired to useFillMask

import { useState } from 'react';
import { useFillMask } from '@localmode/react';
import { transformers } from '@localmode/transformers';
import { MaskTokenInput } from '@/components/mask-token-input';

export function ClozeBox() {
  const [text, setText] = useState('The capital of France is [MASK].');
  const { data, isLoading, execute } = useFillMask({
    model: transformers.fillMask('Xenova/bert-base-uncased'),
    topK: 5,
  });

  return (
    <div className="flex flex-col gap-3">
      <MaskTokenInput value={text} onChange={setText} onSubmit={execute} disabled={isLoading} />
      {data?.predictions.map((p) => (
        <div key={p.token}>{p.token} — {(p.score * 100).toFixed(1)}%</div>
      ))}
    </div>
  );
}

Custom mask token

<MaskTokenInput value={text} onChange={setText} maskToken="<mask>" />

Accessible name

The textarea has no visible <label>, so it ships with an aria-label (default "Fill-mask sentence"). Override ariaLabel to match a nearby heading in your layout.

<MaskTokenInput value={text} onChange={setText} ariaLabel="Sentence to complete" />

Customization

The mask span is highlighted with bg-primary/15 text-primary; the validation hint uses Tailwind's emerald / amber palettes. Pass your own samples (each containing the mask token) to control what Randomize inserts. Set ariaLabel to give the textarea a programmatic name. The component is theme-driven via shadcn/ui CSS variables — edit the copied mask-token-input.tsx to change the preview styling or add multi-mask support.

On this page