/ components / design-system / Divider.tsx
Divider.tsx
  1  import { c as _c } from "react/compiler-runtime";
  2  import React from 'react';
  3  import { useTerminalSize } from '../../hooks/useTerminalSize.js';
  4  import { stringWidth } from '../../ink/stringWidth.js';
  5  import { Ansi, Text } from '../../ink.js';
  6  import type { Theme } from '../../utils/theme.js';
  7  type DividerProps = {
  8    /**
  9     * Width of the divider in characters.
 10     * Defaults to terminal width.
 11     */
 12    width?: number;
 13  
 14    /**
 15     * Theme color for the divider.
 16     * If not provided, dimColor is used.
 17     */
 18    color?: keyof Theme;
 19  
 20    /**
 21     * Character to use for the divider line.
 22     * @default '─'
 23     */
 24    char?: string;
 25  
 26    /**
 27     * Padding to subtract from the width (e.g., for indentation).
 28     * @default 0
 29     */
 30    padding?: number;
 31  
 32    /**
 33     * Title shown in the middle of the divider.
 34     * May contain ANSI codes (e.g., chalk-styled text).
 35     *
 36     * @example
 37     * // ─────────── Title ───────────
 38     * <Divider title="Title" />
 39     */
 40    title?: string;
 41  };
 42  
 43  /**
 44   * A horizontal divider line.
 45   *
 46   * @example
 47   * // Full-width dimmed divider
 48   * <Divider />
 49   *
 50   * @example
 51   * // Colored divider
 52   * <Divider color="suggestion" />
 53   *
 54   * @example
 55   * // Fixed width
 56   * <Divider width={40} />
 57   *
 58   * @example
 59   * // Full width minus padding (for indented content)
 60   * <Divider padding={4} />
 61   *
 62   * @example
 63   * // With centered title
 64   * <Divider title="3 new messages" />
 65   */
 66  export function Divider(t0) {
 67    const $ = _c(21);
 68    const {
 69      width,
 70      color,
 71      char: t1,
 72      padding: t2,
 73      title
 74    } = t0;
 75    const char = t1 === undefined ? "\u2500" : t1;
 76    const padding = t2 === undefined ? 0 : t2;
 77    const {
 78      columns: terminalWidth
 79    } = useTerminalSize();
 80    const effectiveWidth = Math.max(0, (width ?? terminalWidth) - padding);
 81    if (title) {
 82      const titleWidth = stringWidth(title) + 2;
 83      const sideWidth = Math.max(0, effectiveWidth - titleWidth);
 84      const leftWidth = Math.floor(sideWidth / 2);
 85      const rightWidth = sideWidth - leftWidth;
 86      const t3 = !color;
 87      let t4;
 88      if ($[0] !== char || $[1] !== leftWidth) {
 89        t4 = char.repeat(leftWidth);
 90        $[0] = char;
 91        $[1] = leftWidth;
 92        $[2] = t4;
 93      } else {
 94        t4 = $[2];
 95      }
 96      let t5;
 97      if ($[3] !== title) {
 98        t5 = <Text dimColor={true}><Ansi>{title}</Ansi></Text>;
 99        $[3] = title;
100        $[4] = t5;
101      } else {
102        t5 = $[4];
103      }
104      let t6;
105      if ($[5] !== char || $[6] !== rightWidth) {
106        t6 = char.repeat(rightWidth);
107        $[5] = char;
108        $[6] = rightWidth;
109        $[7] = t6;
110      } else {
111        t6 = $[7];
112      }
113      let t7;
114      if ($[8] !== color || $[9] !== t3 || $[10] !== t4 || $[11] !== t5 || $[12] !== t6) {
115        t7 = <Text color={color} dimColor={t3}>{t4}{" "}{t5}{" "}{t6}</Text>;
116        $[8] = color;
117        $[9] = t3;
118        $[10] = t4;
119        $[11] = t5;
120        $[12] = t6;
121        $[13] = t7;
122      } else {
123        t7 = $[13];
124      }
125      return t7;
126    }
127    const t3 = !color;
128    let t4;
129    if ($[14] !== char || $[15] !== effectiveWidth) {
130      t4 = char.repeat(effectiveWidth);
131      $[14] = char;
132      $[15] = effectiveWidth;
133      $[16] = t4;
134    } else {
135      t4 = $[16];
136    }
137    let t5;
138    if ($[17] !== color || $[18] !== t3 || $[19] !== t4) {
139      t5 = <Text color={color} dimColor={t3}>{t4}</Text>;
140      $[17] = color;
141      $[18] = t3;
142      $[19] = t4;
143      $[20] = t5;
144    } else {
145      t5 = $[20];
146    }
147    return t5;
148  }
149  //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZVRlcm1pbmFsU2l6ZSIsInN0cmluZ1dpZHRoIiwiQW5zaSIsIlRleHQiLCJUaGVtZSIsIkRpdmlkZXJQcm9wcyIsIndpZHRoIiwiY29sb3IiLCJjaGFyIiwicGFkZGluZyIsInRpdGxlIiwiRGl2aWRlciIsInQwIiwiJCIsIl9jIiwidDEiLCJ0MiIsInVuZGVmaW5lZCIsImNvbHVtbnMiLCJ0ZXJtaW5hbFdpZHRoIiwiZWZmZWN0aXZlV2lkdGgiLCJNYXRoIiwibWF4IiwidGl0bGVXaWR0aCIsInNpZGVXaWR0aCIsImxlZnRXaWR0aCIsImZsb29yIiwicmlnaHRXaWR0aCIsInQzIiwidDQiLCJyZXBlYXQiLCJ0NSIsInQ2IiwidDciXSwic291cmNlcyI6WyJEaXZpZGVyLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgeyB1c2VUZXJtaW5hbFNpemUgfSBmcm9tICcuLi8uLi9ob29rcy91c2VUZXJtaW5hbFNpemUuanMnXG5pbXBvcnQgeyBzdHJpbmdXaWR0aCB9IGZyb20gJy4uLy4uL2luay9zdHJpbmdXaWR0aC5qcydcbmltcG9ydCB7IEFuc2ksIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgdHlwZSB7IFRoZW1lIH0gZnJvbSAnLi4vLi4vdXRpbHMvdGhlbWUuanMnXG5cbnR5cGUgRGl2aWRlclByb3BzID0ge1xuICAvKipcbiAgICogV2lkdGggb2YgdGhlIGRpdmlkZXIgaW4gY2hhcmFjdGVycy5cbiAgICogRGVmYXVsdHMgdG8gdGVybWluYWwgd2lkdGguXG4gICAqL1xuICB3aWR0aD86IG51bWJlclxuXG4gIC8qKlxuICAgKiBUaGVtZSBjb2xvciBmb3IgdGhlIGRpdmlkZXIuXG4gICAqIElmIG5vdCBwcm92aWRlZCwgZGltQ29sb3IgaXMgdXNlZC5cbiAgICovXG4gIGNvbG9yPzoga2V5b2YgVGhlbWVcblxuICAvKipcbiAgICogQ2hhcmFjdGVyIHRvIHVzZSBmb3IgdGhlIGRpdmlkZXIgbGluZS5cbiAgICogQGRlZmF1bHQgJ+KUgCdcbiAgICovXG4gIGNoYXI/OiBzdHJpbmdcblxuICAvKipcbiAgICogUGFkZGluZyB0byBzdWJ0cmFjdCBmcm9tIHRoZSB3aWR0aCAoZS5nLiwgZm9yIGluZGVudGF0aW9uKS5cbiAgICogQGRlZmF1bHQgMFxuICAgKi9cbiAgcGFkZGluZz86IG51bWJlclxuXG4gIC8qKlxuICAgKiBUaXRsZSBzaG93biBpbiB0aGUgbWlkZGxlIG9mIHRoZSBkaXZpZGVyLlxuICAgKiBNYXkgY29udGFpbiBBTlNJIGNvZGVzIChlLmcuLCBjaGFsay1zdHlsZWQgdGV4dCkuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgCBUaXRsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogPERpdmlkZXIgdGl0bGU9XCJUaXRsZVwiIC8+XG4gICAqL1xuICB0aXRsZT86IHN0cmluZ1xufVxuXG4vKipcbiAqIEEgaG9yaXpvbnRhbCBkaXZpZGVyIGxpbmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEZ1bGwtd2lkdGggZGltbWVkIGRpdmlkZXJcbiAqIDxEaXZpZGVyIC8+XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENvbG9yZWQgZGl2aWRlclxuICogPERpdmlkZXIgY29sb3I9XCJzdWdnZXN0aW9uXCIgLz5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gRml4ZWQgd2lkdGhcbiAqIDxEaXZpZGVyIHdpZHRoPXs0MH0gLz5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gRnVsbCB3aWR0aCBtaW51cyBwYWRkaW5nIChmb3IgaW5kZW50ZWQgY29udGVudClcbiAqIDxEaXZpZGVyIHBhZGRpbmc9ezR9IC8+XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFdpdGggY2VudGVyZWQgdGl0bGVcbiAqIDxEaXZpZGVyIHRpdGxlPVwiMyBuZXcgbWVzc2FnZXNcIiAvPlxuICovXG5leHBvcnQgZnVuY3Rpb24gRGl2aWRlcih7XG4gIHdpZHRoLFxuICBjb2xvcixcbiAgY2hhciA9ICfilIAnLFxuICBwYWRkaW5nID0gMCxcbiAgdGl0bGUsXG59OiBEaXZpZGVyUHJvcHMpOiBSZWFjdC5SZWFjdE5vZGUge1xuICBjb25zdCB7IGNvbHVtbnM6IHRlcm1pbmFsV2lkdGggfSA9IHVzZVRlcm1pbmFsU2l6ZSgpXG4gIGNvbnN0IGVmZmVjdGl2ZVdpZHRoID0gTWF0aC5tYXgoMCwgKHdpZHRoID8/IHRlcm1pbmFsV2lkdGgpIC0gcGFkZGluZylcblxuICBpZiAodGl0bGUpIHtcbiAgICBjb25zdCB0aXRsZVdpZHRoID0gc3RyaW5nV2lkdGgodGl0bGUpICsgMiAvLyArMiBmb3Igc3BhY2VzIGFyb3VuZCB0aXRsZVxuICAgIGNvbnN0IHNpZGVXaWR0aCA9IE1hdGgubWF4KDAsIGVmZmVjdGl2ZVdpZHRoIC0gdGl0bGVXaWR0aClcbiAgICBjb25zdCBsZWZ0V2lkdGggPSBNYXRoLmZsb29yKHNpZGVXaWR0aCAvIDIpXG4gICAgY29uc3QgcmlnaHRXaWR0aCA9IHNpZGVXaWR0aCAtIGxlZnRXaWR0aFxuICAgIHJldHVybiAoXG4gICAgICA8VGV4dCBjb2xvcj17Y29sb3J9IGRpbUNvbG9yPXshY29sb3J9PlxuICAgICAgICB7Y2hhci5yZXBlYXQobGVmdFdpZHRoKX17JyAnfVxuICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICA8QW5zaT57dGl0bGV9PC9BbnNpPlxuICAgICAgICA8L1RleHQ+eycgJ31cbiAgICAgICAge2NoYXIucmVwZWF0KHJpZ2h0V2lkdGgpfVxuICAgICAgPC9UZXh0PlxuICAgIClcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPFRleHQgY29sb3I9e2NvbG9yfSBkaW1Db2xvcj17IWNvbG9yfT5cbiAgICAgIHtjaGFyLnJlcGVhdChlZmZlY3RpdmVXaWR0aCl9XG4gICAgPC9UZXh0PlxuICApXG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPQSxLQUFLLE1BQU0sT0FBTztBQUN6QixTQUFTQyxlQUFlLFFBQVEsZ0NBQWdDO0FBQ2hFLFNBQVNDLFdBQVcsUUFBUSwwQkFBMEI7QUFDdEQsU0FBU0MsSUFBSSxFQUFFQyxJQUFJLFFBQVEsY0FBYztBQUN6QyxjQUFjQyxLQUFLLFFBQVEsc0JBQXNCO0FBRWpELEtBQUtDLFlBQVksR0FBRztFQUNsQjtBQUNGO0FBQ0E7QUFDQTtFQUNFQyxLQUFLLENBQUMsRUFBRSxNQUFNOztFQUVkO0FBQ0Y7QUFDQTtBQUNBO0VBQ0VDLEtBQUssQ0FBQyxFQUFFLE1BQU1ILEtBQUs7O0VBRW5CO0FBQ0Y7QUFDQTtBQUNBO0VBQ0VJLElBQUksQ0FBQyxFQUFFLE1BQU07O0VBRWI7QUFDRjtBQUNBO0FBQ0E7RUFDRUMsT0FBTyxDQUFDLEVBQUUsTUFBTTs7RUFFaEI7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNFQyxLQUFLLENBQUMsRUFBRSxNQUFNO0FBQ2hCLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBQUMsUUFBQUMsRUFBQTtFQUFBLE1BQUFDLENBQUEsR0FBQUMsRUFBQTtFQUFpQjtJQUFBUixLQUFBO0lBQUFDLEtBQUE7SUFBQUMsSUFBQSxFQUFBTyxFQUFBO0lBQUFOLE9BQUEsRUFBQU8sRUFBQTtJQUFBTjtFQUFBLElBQUFFLEVBTVQ7RUFIYixNQUFBSixJQUFBLEdBQUFPLEVBQVUsS0FBVkUsU0FBVSxHQUFWLFFBQVUsR0FBVkYsRUFBVTtFQUNWLE1BQUFOLE9BQUEsR0FBQU8sRUFBVyxLQUFYQyxTQUFXLEdBQVgsQ0FBVyxHQUFYRCxFQUFXO0VBR1g7SUFBQUUsT0FBQSxFQUFBQztFQUFBLElBQW1DbkIsZUFBZSxDQUFDLENBQUM7RUFDcEQsTUFBQW9CLGNBQUEsR0FBdUJDLElBQUksQ0FBQUMsR0FBSSxDQUFDLENBQUMsRUFBRSxDQUFDaEIsS0FBc0IsSUFBdEJhLGFBQXNCLElBQUlWLE9BQU8sQ0FBQztFQUV0RSxJQUFJQyxLQUFLO0lBQ1AsTUFBQWEsVUFBQSxHQUFtQnRCLFdBQVcsQ0FBQ1MsS0FBSyxDQUFDLEdBQUcsQ0FBQztJQUN6QyxNQUFBYyxTQUFBLEdBQWtCSCxJQUFJLENBQUFDLEdBQUksQ0FBQyxDQUFDLEVBQUVGLGNBQWMsR0FBR0csVUFBVSxDQUFDO0lBQzFELE1BQUFFLFNBQUEsR0FBa0JKLElBQUksQ0FBQUssS0FBTSxDQUFDRixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQzNDLE1BQUFHLFVBQUEsR0FBbUJILFNBQVMsR0FBR0MsU0FBUztJQUVSLE1BQUFHLEVBQUEsSUFBQ3JCLEtBQUs7SUFBQSxJQUFBc0IsRUFBQTtJQUFBLElBQUFoQixDQUFBLFFBQUFMLElBQUEsSUFBQUssQ0FBQSxRQUFBWSxTQUFBO01BQ2pDSSxFQUFBLEdBQUFyQixJQUFJLENBQUFzQixNQUFPLENBQUNMLFNBQVMsQ0FBQztNQUFBWixDQUFBLE1BQUFMLElBQUE7TUFBQUssQ0FBQSxNQUFBWSxTQUFBO01BQUFaLENBQUEsTUFBQWdCLEVBQUE7SUFBQTtNQUFBQSxFQUFBLEdBQUFoQixDQUFBO0lBQUE7SUFBQSxJQUFBa0IsRUFBQTtJQUFBLElBQUFsQixDQUFBLFFBQUFILEtBQUE7TUFDdkJxQixFQUFBLElBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBUixLQUFPLENBQUMsQ0FDWixDQUFDLElBQUksQ0FBRXJCLE1BQUksQ0FBRSxFQUFaLElBQUksQ0FDUCxFQUZDLElBQUksQ0FFRTtNQUFBRyxDQUFBLE1BQUFILEtBQUE7TUFBQUcsQ0FBQSxNQUFBa0IsRUFBQTtJQUFBO01BQUFBLEVBQUEsR0FBQWxCLENBQUE7SUFBQTtJQUFBLElBQUFtQixFQUFBO0lBQUEsSUFBQW5CLENBQUEsUUFBQUwsSUFBQSxJQUFBSyxDQUFBLFFBQUFjLFVBQUE7TUFDTkssRUFBQSxHQUFBeEIsSUFBSSxDQUFBc0IsTUFBTyxDQUFDSCxVQUFVLENBQUM7TUFBQWQsQ0FBQSxNQUFBTCxJQUFBO01BQUFLLENBQUEsTUFBQWMsVUFBQTtNQUFBZCxDQUFBLE1BQUFtQixFQUFBO0lBQUE7TUFBQUEsRUFBQSxHQUFBbkIsQ0FBQTtJQUFBO0lBQUEsSUFBQW9CLEVBQUE7SUFBQSxJQUFBcEIsQ0FBQSxRQUFBTixLQUFBLElBQUFNLENBQUEsUUFBQWUsRUFBQSxJQUFBZixDQUFBLFNBQUFnQixFQUFBLElBQUFoQixDQUFBLFNBQUFrQixFQUFBLElBQUFsQixDQUFBLFNBQUFtQixFQUFBO01BTDFCQyxFQUFBLElBQUMsSUFBSSxDQUFRMUIsS0FBSyxDQUFMQSxNQUFJLENBQUMsQ0FBWSxRQUFNLENBQU4sQ0FBQXFCLEVBQUssQ0FBQyxDQUNqQyxDQUFBQyxFQUFxQixDQUFHLElBQUUsQ0FDM0IsQ0FBQUUsRUFFTSxDQUFFLElBQUUsQ0FDVCxDQUFBQyxFQUFzQixDQUN6QixFQU5DLElBQUksQ0FNRTtNQUFBbkIsQ0FBQSxNQUFBTixLQUFBO01BQUFNLENBQUEsTUFBQWUsRUFBQTtNQUFBZixDQUFBLE9BQUFnQixFQUFBO01BQUFoQixDQUFBLE9BQUFrQixFQUFBO01BQUFsQixDQUFBLE9BQUFtQixFQUFBO01BQUFuQixDQUFBLE9BQUFvQixFQUFBO0lBQUE7TUFBQUEsRUFBQSxHQUFBcEIsQ0FBQTtJQUFBO0lBQUEsT0FOUG9CLEVBTU87RUFBQTtFQUtxQixNQUFBTCxFQUFBLElBQUNyQixLQUFLO0VBQUEsSUFBQXNCLEVBQUE7RUFBQSxJQUFBaEIsQ0FBQSxTQUFBTCxJQUFBLElBQUFLLENBQUEsU0FBQU8sY0FBQTtJQUNqQ1MsRUFBQSxHQUFBckIsSUFBSSxDQUFBc0IsTUFBTyxDQUFDVixjQUFjLENBQUM7SUFBQVAsQ0FBQSxPQUFBTCxJQUFBO0lBQUFLLENBQUEsT0FBQU8sY0FBQTtJQUFBUCxDQUFBLE9BQUFnQixFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBaEIsQ0FBQTtFQUFBO0VBQUEsSUFBQWtCLEVBQUE7RUFBQSxJQUFBbEIsQ0FBQSxTQUFBTixLQUFBLElBQUFNLENBQUEsU0FBQWUsRUFBQSxJQUFBZixDQUFBLFNBQUFnQixFQUFBO0lBRDlCRSxFQUFBLElBQUMsSUFBSSxDQUFReEIsS0FBSyxDQUFMQSxNQUFJLENBQUMsQ0FBWSxRQUFNLENBQU4sQ0FBQXFCLEVBQUssQ0FBQyxDQUNqQyxDQUFBQyxFQUEwQixDQUM3QixFQUZDLElBQUksQ0FFRTtJQUFBaEIsQ0FBQSxPQUFBTixLQUFBO0lBQUFNLENBQUEsT0FBQWUsRUFBQTtJQUFBZixDQUFBLE9BQUFnQixFQUFBO0lBQUFoQixDQUFBLE9BQUFrQixFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBbEIsQ0FBQTtFQUFBO0VBQUEsT0FGUGtCLEVBRU87QUFBQSIsImlnbm9yZUxpc3QiOltdfQ==