npm package: @flex-development/string-wrap
Description: Wrap a string to a specified column width
Author: Lexus Drumgold
Latest version: 2.1.2

# string-wrap

[![ci](https://github.com/flex-development/string-wrap/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/flex-development/string-wrap/actions/workflows/ci.yml)
[![github release](https://img.shields.io/github/v/release/flex-development/string-wrap.svg?include_prereleases\&sort=semver)](https://github.com/flex-development/string-wrap/releases/latest)
[![npm](https://img.shields.io/npm/v/@flex-development/string-wrap.svg)](https://npmjs.com/package/@flex-development/string-wrap)
[![npm downloads](https://img.shields.io/npm/dm/@flex-development/string-wrap.svg)](https://www.npmcharts.com/compare/@flex-development/string-wrap?interval=30)
[![install size](https://packagephobia.now.sh/badge?p=@flex-development/string-wrap)](https://packagephobia.now.sh/result?p=@flex-development/string-wrap)
[![codecov](https://codecov.io/gh/flex-development/string-wrap/graph/badge.svg?token=WnG7sE7HVw)](https://codecov.io/gh/flex-development/string-wrap)
[![module type: esm](https://img.shields.io/badge/module%20type-esm-brightgreen)](https://github.com/voxpelli/badges-cjs-esm)
[![license](https://img.shields.io/github/license/flex-development/string-wrap.svg)](LICENSE.md)
[![conventional commits](https://img.shields.io/badge/-conventional%20commits-fe5196?logo=conventional-commits\&logoColor=ffffff)](https://conventionalcommits.org)
[![typescript](https://img.shields.io/badge/-typescript-3178c6?logo=typescript\&logoColor=ffffff)](https://typescriptlang.org)
[![vitest](https://img.shields.io/badge/-vitest-6e9f18?style=flat\&logo=vitest\&logoColor=ffffff)](https://vitest.dev)
[![yarn](https://img.shields.io/badge/-yarn-2c8ebb?style=flat\&logo=yarn\&logoColor=ffffff)](https://yarnpkg.com)

Wrap a string

## Contents

- [What is this?](#what-is-this)
  - [Features](#features)
- [Install](#install)
- [Use](#use)
- [API](#api)
  - [`lines(thing, config[, options])`](#linesthing-config-options)
  - [`wrap(thing, config[, options])`](#wrapthing-config-options)
- [Types](#types)
  - [`ColumnsFunction<[T]>`](#columnsfunctiont)
  - [`Columns`](#columns)
  - [`Config`](#config)
  - [`LinesInfo`](#linesinfo)
  - [`Options`](#options)
  - [`SpacerFunction<[T]>`](#spacerfunctiont)
  - [`Spacer`](#spacer)
  - [`StripAnsi`](#stripansi)
  - [`ToString<[T]>`](#tostringt)
- [Contribute](#contribute)

## What is this?

This is a small, but useful package for word-wrapping a string to a specified column width.

### Features

\:rainbow: [ansi][] support\
\:triangular\_ruler: configure columns dynamically\
\:unicorn: emoji and fullwidth character support\
\:arrow\_right: indent and pad lines

## Install

This package is [ESM only][esm].

In Node.js with [yarn][]:

```sh
yarn add @flex-development/string-wrap
```

<blockquote>
  <small>
    See <a href='https://yarnpkg.com/protocol/git'>Git - Protocols | Yarn</a>
    &nbsp;for details regarding installing from Git.
  </small>
</blockquote>

In Deno with [`esm.sh`][esmsh]:

```ts
import { wrap } from 'https://esm.sh/@flex-development/string-wrap'
```

In browsers with [`esm.sh`][esmsh]:

```html
<script type="module">
  import { wrap } from 'https://esm.sh/@flex-development/string-wrap'
</script>
```

With [bun][]:

```sh
bun add @flex-development/string-wrap
```

<blockquote>
  <small>
    See <a href='https://bun.com/docs/cli/add'><code>bun add</code></a> for more details.
  </small>
</blockquote>

## Use

```js
import c from '@flex-development/colors'
import wrap from '@flex-development/string-wrap'

/**
 * The string to wrap.
 *
 * @type {string}
 * @const string
 */
const string = `The ${c.bold(c.italic('quick'))} brown ` +
  c.red('🦊 jumped over ') +
  'the ' +
  c.bold('lazy ') +
  c.green('🐶 and then ran away with the 🦄.')

/**
 * The number of columns to wrap the string to.
 *
 * @type {number}
 * @const columns
 */
const columns = 8

console.log(wrap(string, columns, { indent: 2 }))
```

<img alt="preview" src="./preview.png" width="100" />

## API

This package exports the following identifiers:

- [`lines`](#linesthing-config-options)
- [`wrap`](#wrapthing-config-options)

The default export is [`wrap`](#wrapthing-config-options).

### `lines(thing, config[, options])`

Get info about the lines of a wrapped string.

#### Overloads

- `lines(thing: unknown, config: Columns, options?: Options | null | undefined): LinesInfo`
- `lines(thing: unknown, config: Columns | Config): LinesInfo`

##### Parameters

- `thing` (`unknown`)
  — the thing to wrap. non-string values will be converted to strings
- `config` ([`Columns`](#columns) | [`Config`](#config))
  — the wrap configuration, the number of columns to wrap the string to,
  or a function that returns the maximum number of columns per line
- `options` ([`Options`](#options) | `null` | `undefined`, `optional`)
  — options for wrapping

##### Returns

([`LinesInfo`](#linesinfo)) Info about the lines forming the wrapped string

### `wrap(thing, config[, options])`

Wrap a string to the specified column width.

#### Overloads

- `wrap(thing: unknown, config: Columns, options?: Options | null | undefined): string`
- `wrap(thing: unknown, config: Columns | Config): string`

##### Parameters

- `thing` (`unknown`)
  — the thing to wrap. non-string values will be converted to strings
- `config` ([`Columns`](#columns) | [`Config`](#config))
  — the wrap configuration, the number of columns to wrap the string to,
  or a function that returns the maximum number of columns per line
- `options` ([`Options`](#options) | `null` | `undefined`, `optional`)
  — options for wrapping

##### Returns

(`string`) The wrapped string

## Types

This package is fully typed with [TypeScript][].

### `ColumnsFunction<[T]>`

Get the maximum number of columns for the line at `index` (`type`).

> 👉 **Note**: The total number of available columns is calculated from the
> maximum number of columns, indentation, and padding.

```ts
type ColumnsFunction<T extends number | string = number | string> = (
  this: void,
  index: number,
  lines?: readonly string[] | null | undefined
) => T
```

#### Type Parameters

- `T` (`number` | `string`, optional)
  — the maximum number of columns

#### Parameters

- `index` (`number`)
  — the index of the current line, or `-1` on init
- `lines` (`readonly string[]` | `null` | `undefined`, optional)
  — the current list of lines

#### Returns

(`T`) The maximum number of columns

### `Columns`

Union of column configurations (`type`).

```ts
type Columns = ColumnsFunction | number | string
```

### `Config`

String wrapping configuration (`interface`).

### Extends

- [`Options`](#options)

#### Properties

- `columns` ([`Columns`](#columns))
  — the number of columns to wrap the string to, or a function that returns the maximum number of columns per line

### `LinesInfo`

Info about the lines of a wrapped string (`interface`).

#### Properties

- `columns` ([`ColumnsFunction<number>`](#columnsfunctiont))
  — get the maximum number of columns per line
- `eol` (`string`)
  — the character, or characters, used to mark the end of a line
- `indent` ([`SpacerFunction<string>`](#spacerfunctiont))
  — get the string used to indent each line
- `lines` (`readonly string[]`)
  — the list of lines forming the wrapped string
- `padLeft` ([`SpacerFunction<string>`](#spacerfunctiont))
  — get the string used to pad the left side of each line
- `padRight` ([`SpacerFunction<string>`](#spacerfunctiont))
  — get the string used to pad the right side of each line

### `Options`

Options for wrapping a string (`interface`).

#### Properties

- `eol?` (`string` | `null` | `undefined`, optional)
  — the character, or characters, used to mark the end of a line
  - default: `'\n'`
- `fill?` (`boolean` | `null` | `undefined`, optional)
  — whether to completely fill each column, splitting words as necessary.\
  by default, splits are made at spaces, ensuring that words aren't broken
  and don't extend past the configured number of `columns`
  > 👉 **note**: setting this to `true` will break words.
- `hard?` (`boolean` | `null` | `undefined`, optional)
  — whether to hard wrap words at the specified number of `columns`.\
  by default, long words remain unbroken and push onto the next line if they don't fit on the current line.\
  setting this to `true` will break long words.
  > 👉 **note**: setting this to `true` will break words.
- `indent?` ([`SpacerFunction`](#spacerfunctiont) | `number` | `string` | `null` | `undefined`, optional)
  — the size of the string to use for indenting each line (as a number or numeric), or the string itself
- `padLeft?` ([`SpacerFunction`](#spacerfunctiont) | `number` | `string` | `null` | `undefined`, optional)
  — the size of the string to use for padding the left side of each line (as a number or numeric), or the string itself
- `padRight?` ([`SpacerFunction`](#spacerfunctiont) | `number` | `string` | `null` | `undefined`, optional)
  — the size of the string to use for padding the right side of each line (as a number or numeric), or the string itself
- `stringify?` ([`ToString`](#tostringt) | `null` | `undefined`, optional)
  — convert a value to a string
- `stripAnsi?` ([`StripAnsi`](#stripansi) | `boolean` | `null` | `undefined`, optional)
  — whether to remove ANSI escape codes before wrapping, or a function to remove ANSI escape codes
- `tabSize?` (`number` | `string` | `undefined`, optional)
  — the number of spaces a tab is equivalent to
  - default: `2`
- `trim?` (`boolean` | `null` | `undefined`, optional)
  — whether to remove whitespace from the end of each line
  > 👉 **note**: lines are trimmed before applying indents or padding.
  - default: `true`

### `SpacerFunction<[T]>`

Get a spacer configuration for the line at `index` (`type`).

Spacers can be used to indent a line, and/or pad either side of it.

```ts
type SpacerFunction<
  T extends number | string | null | undefined =
    | number
    | string
    | null
    | undefined
> = (
  this: void,
  index: number,
  lines?: readonly string[] | null | undefined
) => T
```

#### Type Parameters

- `T` (`number` | `string` | `null` | `undefined`, optional)
  — the spacer configuration

#### Parameters

- `index` (`number`)
  — the index of the current line, or `-1` on init
- `lines` (`readonly string[]` | `null` | `undefined`, optional)
  — the current list of lines

#### Returns

(`T`) The spacer configuration

### `Spacer`

Union of spacer configurations (`type`).

Spacers can be used to indent a line, and/or pad either side of it.

Valid spacer configurations are functions, sizes (as a number or numeric), or the spacer itself.

```ts
type Spacer = SpacerFunction | number | string
```

### `StripAnsi`

Remove ANSI escape codes from a string (`type`).

```ts
type StripAnsi = (this: void, string: string) => string
```

#### Parameters

- `string` (`string`)
  — the string containing ANSI escape codes

#### Returns

(`string`) The string with ANSI escape codes removed

### `ToString<[T]>`

Convert `value` to a string (`type`).

```ts
type ToString<T = any> = (this: void, value: T) => string
```

#### Type Parameters

- `T` (`any`, optional)
  — the thing to stringify

#### Parameters

- `value` (`T`)
  — the thing to stringify

#### Returns

(`string`) The stringified `value`

## Contribute

See [`CONTRIBUTING.md`](CONTRIBUTING.md).

This project has a [code of conduct](./CODE_OF_CONDUCT.md). By interacting with this repository, organization, or
community you agree to abide by its terms.

[ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code

[bun]: https://bun.sh

[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c

[esmsh]: https://esm.sh

[typescript]: https://www.typescriptlang.org

[yarn]: https://yarnpkg.com