Debriefer
React

StyleKit

Override the markup of any Cell — inputs and conversational chrome alike — with your own components.

Blocks are headless: by default they render minimal, unstyled markup. StyleKit is how you make them yours. It's a map from each primitive to a component you provide — antd, shadcn, Mantine, plain DOM, anything. Set it once; it applies everywhere.

It is not a theme. It replaces the rendered markup of each primitive, so you keep total control of structure, classes, and behaviour — while the agent keeps total control of the conversation.

Usage

import type { StyleKit } from '@debriefer/blocks-react';
import { Input as AntInput, Button as AntButton } from 'antd';

const styleKit: StyleKit = {
  Textarea: ({ value, onChange, placeholder, rows, disabled, a11y }) => (
    <AntInput.TextArea
      value={value}
      onChange={onChange}
      placeholder={placeholder}
      autoSize={{ minRows: rows ?? 2 }}
      disabled={disabled}
      {...a11y}
    />
  ),
  Button: ({ onClick, children }) => (
    <AntButton onClick={onClick}>{children}</AntButton>
  ),
};

<DebrieferProvider config={{ formId, sessionToken, styleKit }}>
  <App />
</DebrieferProvider>;

What slots carry — and what they don't

Slots get state, never decisions

A slot receives the control's current value, its change/commit handlers, and the accessibility attributes to spread. It calls a handler; the agent decides what happens. A slot can never appraise, advance, or judge sufficiency — that keeps the one rule intact no matter how you style.

Slots

Input slots

Input · Textarea · Select · Combobox · Radio · Checkbox · Slider · Rating · Ranking · CardSort

Display slots

Media · Prose

Structure slots

Field · Label · Description · Button

Intelligence slots

The conversational chrome renders too — and it must match your design, so it's styleable just like the inputs. These are presentational: they render the agent's decisions and the modality state, and never configure behaviour.

Trail · Chips · FollowUp · VoiceBar

See Intelligence for what each one shows.

Resolution order

For any primitive, the most specific renderer wins:

  1. A per-instance render prop on that Cell (local override for one spot).
  2. The matching StyleKit slot (your global look).
  3. The built-in headless default (data-attributes only, zero styles).

On this page