vadimdemedes/ink

RFE: expose index of output line in Transform

isaacs opened this issue · 1 comments

isaacs commented

I need to add a hanging indent to some text. I'm able to do it, albeit with a few contortions:

import { Text, TextProps } from 'ink'
const sigil = '\x01\x02\x03\x03\x02\x01'
const HangingIndent: FC<{ indent?: number } & TextProps> = ({
  indent = 4,
  children,
  ...props
}) => (
  <Transform
    transform={o =>
      o.includes(sigil) ? o.replace(sigil, '') : ' '.repeat(indent) + o
    }>
    <Text {...props}>
      {sigil}
      {children}
    </Text>
  </Transform>
)

// usage: <HangingIndent dimColor bold color="red">Some long string of text blah blah blah</HangingIndent>

Of course, this will break if the string contains the sigil, but I'm reasonably sure no one is going to have that string of control characters in this situation. But it does feel like a weird hack.

If the <Transform> method knew what line it was working on, then this could be much cleaner. I'm thinking of it somewhat like Array.map:

import React, { FC } from 'react'
import { Text, TextProps } from 'ink'
const HangingIndent: FC<{ indent?: number } & TextProps> = ({
  indent = 4,
  children,
  ...props
}) => (
  <Transform
    transform={(o, line) => line === 0 ? o : ' '.repeat(indent) + o
    }>
    <Text {...props}>
      {children}
    </Text>
  </Transform>
)

Transforms are applied line by line, if I remember correctly, so this change makes sense to me. Feel free to open a PR.