effect-tree - v1.0.36
    Preparing search index...

    Draw Module

    A simple compositional terminal drawing library that is just good enough to show some recursive structures in diagrams. You use it to build parts, combine them in various ways to build bigger parts, then render them to the terminal.

    1. Overview
    2. Parts
      1. Creating
      2. Sizing Parts
    3. Struts
      1. Drawing Struts
      2. Overflow
    4. Trees
    5. Modules

    Parts can be placed next to each other with a direction and an alignment so that the smaller parts will be stretched and the resulting part will always remain a rectangular area. The library is used for drawing trees here because this placement of parts next to each other can be done with no measuring or computing of sizes.

    This is also the main limitation of the library- there is no way to measure part sizes until they are rendered. You cannot render parts while you are computing their content so we use block alignment and the struts feature described below to get around this limitation.

    You will find here functions to build parts, which are rectangular blocks of glyphs. They are rectangular because they will render to a rectangle of text on a terminal. A part never has any holes or jagged edges: every area of the rectangle is filled.

    There are four types of the parts, two are atomic and two composite. All other parts are composed from these four:

    1. Atomic
      1. Empty. The empty type.
      2. Text. A part that shows some text.
    2. Composite
      1. Row. Children are distributed horizontally according to alignment.
      2. Column. Children are distributed vertically according to alignment.

    The functions text, row, and column are the basic ways to create the four part types, with the empty part exported as the constant empty.

    import {Draw} from 'effect-tree'

    const {box, column, drawPart, empty, row, text} = Draw

    // Two lists of text.
    const leftCells = [text('↑'), text('left|'), text('↓')]
    const rightCells = [text('↑'), text('|right'), text('↓')]

    // A pair of columns.
    const leftColumn = column.left(leftCells)
    const rightColumn = column.right(rightCells)

    // A row with the column pair and the empty part.
    const bottomRow = row('middle')('center')([leftColumn, empty, rightColumn])

    console.log(drawPart.unlines(box(bottomRow)))
    // ┌───────────┐
    // │↑ ↑│
    // │left||right│
    // │↓ ↓│
    // └───────────┘

    Part sizes are defined entirely by their content and padding. When they are aligned, they grow to match the widest or tallest in their row or column, depending on the axis.

    The area created when aligning is, together with any explicit padding, the available space that is left for filling with non-content. You can set how this empty area created by the alignment is rendered by setting struts on each of the four directions. Struts have a fixed prefix and suffix but their bodies stretch out to fill available space.

    The struts are set by default to empty space, as that is what you usually expect as padding, however we set specific glyphs to draw borders, separators, connectors and other elements where size depends on content.

    When your parts are ready, the drawPart function will recursively fold the part into a list of string rows for display.

    The glyphs used to fill available space between and around shapes are determined by the Strut.

    By default it is set to the space character, which is usually what you want surrounding your text when it is being aligned.

    The strut can be a character, like the space configured by default, and it will be repeated to fill available space.

    However the type for Strut also has a prefix and a suffix, and its body can be any length, which simplifies some types of drawings described below. For example a horizontal strut is defined as a triplet of:

    1. A prefix string.
    2. A body string.
    3. A suffix string.

    the prefix and suffix are optional, and by default they are set to the empty string so that available space fills uniformly with spaces.

    A strut is drawn by shapes to fill some available space when aligning and padding. A horizontal strut is N glyphs wide and one glyph high. A vertical strut is N glyphs high and zero glyphs wide.

    A horizontal strut, for example, is drawn so:

    1. First we draw the prefix.
    2. Next we repeat the body to fill available space leaving space for the prefix and suffix.
    3. Finally we draw the suffix.

    This makes it easy to build parts that stretch to adapt to neighboring parts without measuring or doing any math. For example, leaving a top row of your shape empty, will fill it with a single character of the vertical struct. This will not take any space, so a horizontal strut will be used to fill the top line. If it is created so:

    const topHorizontalLineStrut = strut.horizontal(
    '├╴╼┅┉┄┈ ', // prefix 9 glyphs wide
    ['1', '2', '3', '4', '5'], // body 5 glyphs wide
    ' ┈┄┉┅╾╌╶┤', // suffix 9 glyphs wide
    )
    ↑ ↑ ↑ ↑
    ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ruler
    0123456789012345

    Note the body (the second argument) must be given as a non-empty string array to ensure we always have at least a single glyph with which to fill available space.

    Then a line 30 glyphs wide part configured with the topHorizontalLineStrut above will be filled so:

     ├╴╼┅┉┄┈ 1234512345123 ┈┄┉┅╾╌╶┤
    
    ↑    ↑    ↑    ↑    ↑    ↑    ↑    ↑
    0    5   10   15   20   25   30   35
    ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ruler
    012345678901234567890123456789012345
    

    A 20 glyphs wide part will be draw so:

     ├╴╼┅┉┄┈ 123 ┈┄┉┅╾╌╶┤
    
    ↑    ↑    ↑    ↑    ↑    ↑    ↑    ↑
    0    5   10   15   20   25   30   35
    ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ruler
    012345678901234567890123456789012345
    

    This is useful, for example when drawing responsive borders, separators, and connectors.

    When available space is less than prefix width + a single body width + suffix width, the strut overflows. Overflow is cropped by priority.

    First we try to remove from the right edge of the body of the strut.

    If the entire body was removed but we still overflow, remove in equal measure from the prefix and the suffix, removing from the tail of the prefix and the head of the suffix, so that the last two glyphs remaining are the head glyph of the prefix and the last glyph of the suffix.

    If there is only a single space left, the final character of the suffix is clipped so that only the 1st character of the prefix is left.

    A 5 glyph wide part will be draw so:

     ├╴╼┅ ┅╾╌╶┤
    
    ↑    ↑    ↑
    0    5   10
    ┈┈┈┈┈┈┈┈┈┈┈ruler
    01234567890
    

    At a width of 2 glyphs:

     ├┤
    
    ↑    ↑    ↑
    0    5   10
    ┈┈┈┈┈┈┈┈┈┈┈ruler
    01234567890
    

    And when there is only a single space to fill:

     ├
    
    ↑    ↑    ↑
    0    5   10
    ┈┈┈┈┈┈┈┈┈┈┈ruler
    01234567890
    

    Trees can be themed, which just means that they get a theme as an argument and they can use it to theme how they draw. For example a part could depend not on individual glyphs, E.g.: but instead on glyph roles, for example the role elbow, and then a theme could set the glyph for the role to to get rounded corners.

    Useful functions are mostly found in the packages part and above. These are all the internal modules of Draw:

    1. tree: Parts for drawing trees and the drawTree function.
    2. parts: Various useful parts, for example the box part.
    3. glyph: Sugar for accessing glyphs that are helpful when line drawing on the terminal.
    4. part: A basic abstraction for working with rectangular blocks of text.
    5. partF: The non-recursive version of Part.
    6. align: Aligning text and filling available space created with struts.
    7. struts: Functions to fill empty parts of rectangular blocks of text.
    Draw modules and their interdependencies