# Thought Line

> Reasoning trace header with a live clock that folds its steps into one line when done.

A one-line “Thinking…” header for AI answers. While working, the glyph breathes, a band of ink shimmers across the label and a clock counts up; steps appear beneath it, the last one pulsing. When `working` turns false the label crossfades to “Thought for 4.1s”, the clock glides into the sentence and the trace folds away. Click the line to reopen the trace.

<demo-thought-line>



</demo-thought-line>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/thought-line.json"
```

## Usage

```vue
<script setup lang="ts">
  import { ref } from 'vue';
  import ThoughtLine from '~/components/ui/thought-line/ThoughtLine.vue';

  const working = ref(true);
  const steps = ref(['Reading the question', 'Searching your notes']);

  function onSettle(seconds: number) {
    console.log('thought for', seconds);
  }
</script>

<template>
  <ThoughtLine
    label="Thinking…"
    :steps="steps"
    :working="working"
    :font-size="18"
    @settle="onSettle"
  />
</template>
```

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'Thinking…'
      </code>
    </td>
    
    <td>
      The working line. It breathes, and it is the spoken text
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        done-label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Settled line. Empty gives “Thought for”, or “Done thinking” no timer
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glyph
      </code>
    </td>
    
    <td>
      <code>
        'sparkle' | 'dot' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'sparkle'
      </code>
    </td>
    
    <td>
      The mark that breathes and dims (or use the <code>
        glyph
      </code>
      
       slot)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        steps
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      <code>
        []
      </code>
    </td>
    
    <td>
      Trace beneath the line. The last step is current, earlier ones tick
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        collapsible
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The line becomes a toggle for the trace, with a chevron
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        collapse-on-settle
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Fold the trace into the line when it settles
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'currentColor'
      </code>
    </td>
    
    <td>
      Ink of the line and the trace
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glyph-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      The glyph alone. Empty follows the ink
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        font-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        16
      </code>
    </td>
    
    <td>
      Type size in px. Everything scales in em
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        breath-period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1.6
      </code>
    </td>
    
    <td>
      One breath, up and down, in seconds
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        breath-depth
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.45
      </code>
    </td>
    
    <td>
      How far the glyph and label dim at the trough. <code>
        0
      </code>
      
       is no breath
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shimmer
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      A band of ink sweeps the working label
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shimmer-duration
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1.8
      </code>
    </td>
    
    <td>
      One sweep, in seconds
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        settle-duration
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        350
      </code>
    </td>
    
    <td>
      The settle chord in ms: crossfade, dim, glide, fold
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        settle-blur
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Blur through the crossfade seam, in px
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        working
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Working or settled. <code>
        true
      </code>
      
       again starts a new clock
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        settle-after
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Seconds after which it settles by itself. <code>
        0
      </code>
      
       waits for <code>
        working
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        elapsed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Controlled seconds. The internal clock never runs
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        show-timer
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The live clock that freezes into the sentence
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the root
    </td>
  </tr>
</tbody>
</table>

## Events

<table>
<thead>
  <tr>
    <th>
      Event
    </th>
    
    <th>
      Payload
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        settle
      </code>
    </td>
    
    <td>
      <code>
        seconds: number
      </code>
    </td>
    
    <td>
      Once per settle, with frozen time
    </td>
  </tr>
</tbody>
</table>

## Slots

<table>
<thead>
  <tr>
    <th>
      Slot
    </th>
    
    <th>
      Scope
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        glyph
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Custom glyph in place of the sparkle or dot
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        label
      </code>
    </td>
    
    <td>
      <code>
        { text: string; working: boolean }
      </code>
    </td>
    
    <td>
      Wraps either label string. Inline content only
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The visual label and timer are `aria-hidden`; a `role="status"` region announces the working label, then “Thought for 4.1 seconds” once.
- When there is a trace and `collapsible` is on, the line is a real `<button>` with `aria-expanded`.
- With `prefers-reduced-motion`, the shimmer is dropped, the breath is shallower and slower, and the crossfade loses its blur.
- Ported from [React Bits](https://reactbits.dev/micro/thought-line) by David Haz.
