# box-logger

A simple utility for creating formatted text boxes, headers, and lines in the terminal.

## Installation

```bash
npm install @davidwells/box-logger
```

## Usage

### Box

Create a box around text with customizable borders, padding, and styling.

```javascript
const { makeBox, logBox } = require('@davidwells/box-logger')

// Simple usage with a string
console.log(makeBox('Hello World'))

// With options
console.log(makeBox({
  content: 'Hello World',
  textAlign: 'center',
  paddingLeft: 4,
  paddingRight: 4,
  borderColor: 'green',
  borderStyle: 'bold'
}))

// With title and content
console.log(makeBox({
  title: 'My Title',
  content: 'Box content here',
  borderStyle: 'rounded'
}))

// Hex colors are supported
console.log(makeBox({
  content: 'Custom colors',
  borderColor: '#4287f5',
  backgroundColor: '#1a1a2e'
}))

// Dynamic content - function receives { innerWidth } for sizing
console.log(makeBox({
  title: 'Dynamic Width',
  content: ({ innerWidth }) => generateContent({ width: innerWidth }),
  paddingLeft: 1,
  paddingRight: 0
}))

// Async content - use makeBoxAsync for async functions
const box = await makeBoxAsync({
  title: 'Async Content',
  content: async ({ innerWidth }) => await fetchData({ width: innerWidth })
})
console.log(box)

// Call logger directly
logBox('Log the box directly')
```

#### Box Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `content` | string \| Section \| function | - | Content (or function receiving `{ innerWidth }`) |
| `title` | string \| Section | - | Title section at top of box |
| `fontStyle` | 'normal' \| 'bold' | 'normal' | Font style |
| `textAlign` | 'left' \| 'center' \| 'right' | 'left' | Text alignment |
| `color` | string | - | Text color (chalk color or hex like '#ff0000') |
| `backgroundColor` | string | - | Background color (chalk color or hex) |
| `paddingTop` | number | 0 | Newlines before content |
| `paddingBottom` | number | 0 | Newlines after content |
| `paddingLeft` | number | 2 | Spaces for left padding |
| `paddingRight` | number | 2 | Spaces for right padding |
| `borderColor` | string | - | Border color (chalk color or hex) |
| `borderStyle` | string | 'normal' | Border style (see below) |
| `borderTop` | boolean | true | Show top border |
| `borderBottom` | boolean | true | Show bottom border |
| `borderLeft` | boolean | true | Show left border |
| `borderRight` | boolean | true | Show right border |
| `borderText` | string | - | Text embedded in top border |
| `borderTextColor` | string | - | Color for border text |
| `borderTextAlign` | 'left' \| 'center' \| 'right' | 'left' | Border text alignment |
| `width` | number \| string | - | Fixed width |
| `minWidth` | number \| string | - | Minimum width ('100%' for full width) |
| `maxWidth` | number \| string | terminal width | Maximum width |
| `marginTop` | number | 0 | Newlines before box |
| `marginBottom` | number | 0 | Newlines after box |
| `marginLeft` | number | 0 | Spaces before each line |
| `wrapText` | boolean | true | Wrap text to fit inside box |
| `type` | string | - | Box type: 'success', 'error', 'warning', 'info' |
| `icon` | string | - | Custom icon |
| `header` | boolean | false | Header mode (no left border) |
| `edges` | object | - | Custom border symbols |

#### Border Styles

- `normal` - Standard box drawing characters (─│┌┐└┘)
- `rounded` - Rounded corners (╭╮╰╯)
- `bold` - Heavy weight borders (━┃┏┓┗┛)
- `double` - Double line borders (═║╔╗╚╝)
- `dashed` - Dashed horizontal lines (╌)
- `dotted` - Dotted horizontal lines (┈)
- `thick` - Block characters (█▀▄)
- `half-thick` - Half block borders (▐▌▔▂)
- `ultra-thick` - Full block borders (█)
- `ascii` - ASCII fallback (-|+)
- `dots` - Bullet dots (•)
- `circles` - Hollow circles (○)
- `stars` - Sparkle stars (✨)
- `triple` - Triple lines (≡)
- `transparent` - Invisible borders (spaces)
- `none` - No borders at all
- `filled` - For use with backgroundColor

#### Section Object

Title and content can be strings or Section objects for more control:

```javascript
makeBox({
  title: {
    left: 'Title',
    right: 'v1.0.0',
    fontStyle: 'bold',
    color: 'cyan'
  },
  content: {
    left: 'Description',
    right: 'Status: OK',
    color: 'green'
  }
})
```

Section properties: `left`, `right`, `center`, `color`, `fontStyle`, `paddingLeft`, `paddingRight`, `paddingTop`, `paddingBottom`, `truncate`

### Stacked Boxes

Stack multiple boxes vertically with shared borders:

```javascript
const { makeStackedBoxes } = require('@davidwells/box-logger')

console.log(makeStackedBoxes([
  { title: 'Box 1', content: 'First box content' },
  { title: 'Box 2', content: 'Second box content' },
  { title: 'Box 3', content: 'Third box content' }
], {
  borderStyle: 'rounded',
  borderColor: 'cyan'
}))
```

### Horizontal Boxes

Render boxes side by side:

```javascript
const { makeHorizontalBoxes } = require('@davidwells/box-logger')

console.log(makeHorizontalBoxes([
  { content: 'Left box' },
  { content: 'Middle box' },
  { content: 'Right box' }
], {
  gap: 2,
  mergeBoxes: true  // Merge adjacent borders
}))
```

Options: `gap`, `marginLeft`, `connectRows`, `justifyContent` ('flex-start', 'flex-end', 'space-between'), `wrap`, `mergeBoxes`

### Header

Create a header (box with no left border):

```javascript
const { makeHeader, logHeader } = require('@davidwells/box-logger')

// Simple usage
console.log(makeHeader('Hello World'))

// With options
console.log(makeHeader({
  content: 'Hello World',
  borderColor: 'blue'
}))

// Typed variants
logHeader.success('Operation completed')
logHeader.error('An error occurred')
logHeader.warning('Please be careful')
logHeader.info('Information')
```

Header uses the same options as Box (it's just `header: true` under the hood).

### Line

Create horizontal lines with optional text:

```javascript
const { makeLine, logLine } = require('@davidwells/box-logger')

// Simple line
console.log(makeLine())

// Line with centered text
console.log(makeLine('Section Title'))

// Line with options
console.log(makeLine({
  text: 'Styled text',
  fontStyle: 'bold',
  borderColor: 'green'
}))

// Left and right text
console.log(makeLine({
  left: 'Section',
  right: 'v1.2.3',
  borderColor: 'cyan'
}))

// All three positions
console.log(makeLine({
  left: 'Left',
  center: 'Center',
  right: 'Right'
}))
```

#### Line Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `text` | string | - | Text to display (use with textAlign) |
| `left` | string | - | Left-aligned text |
| `right` | string | - | Right-aligned text |
| `center` | string | - | Center-aligned text |
| `color` | string | - | Text color |
| `backgroundColor` | string | - | Background color for text |
| `lineBackgroundColor` | string | - | Background for entire line |
| `fontStyle` | 'normal' \| 'bold' | 'normal' | Font style |
| `borderColor` | string | - | Line color |
| `borderStyle` | string | 'normal' | Line style |
| `textAlign` | 'left' \| 'center' \| 'right' | 'center' | Text alignment |
| `paddingLeft` | number | 4 | Left padding |
| `paddingRight` | number | 4 | Right padding |
| `minWidth` | number \| string | - | Minimum width |
| `maxWidth` | number \| string | terminal width | Maximum width |
| `lines` | number | - | Generate multiple blank lines |

### Typed Variants

All log functions have typed variants with automatic icons and colors:

```javascript
const { logBox, logHeader, logLine } = require('@davidwells/box-logger')

// Box variants
logBox.success('Operation completed successfully')
logBox.error('An error occurred')
logBox.warning('Please be careful')
logBox.info('Here is some information')

// Header variants
logHeader.success('Success!')
logHeader.error('Error!')

// Line variants
logLine.success('Success line')
logLine.error('Error line')
```

### Error Handling

Pass an Error object to logBox for formatted error display:

```javascript
try {
  throw new Error('Something went wrong')
} catch (err) {
  logBox.error(err)  // Shows error name, message, and cleaned stack trace
}
```

## Examples

### Basic Box

```
┌─────────────┐
│  Hello World  │
└─────────────┘
```

### Rounded Box with Title

```
╭──────────────────────╮
│  My Title            │
├──────────────────────┤
│  Content goes here   │
╰──────────────────────╯
```

### Bold Box

```
┏━━━━━━━━━━━━━━━━━━━━━━┓
┃  Hello World         ┃
┗━━━━━━━━━━━━━━━━━━━━━━┛
```

### Header (No Left Border)

```
──────────────────────────────┐
  Hello World                 │
──────────────────────────────┘
```

### Line with Text

```
────────── Section Title ──────────
```

### Line with Left and Right

```
──── Section ──────────── v1.2.3 ────
```

## Utilities

### terminalSize

Get the current terminal dimensions:

```javascript
const { terminalSize } = require('@davidwells/box-logger')

const { columns, rows } = terminalSize()
console.log(`Terminal is ${columns}x${rows}`)
```

### getInnerWidth

Calculate the inner content width for a box configuration:

```javascript
const { getInnerWidth } = require('@davidwells/box-logger')

const innerWidth = getInnerWidth({
  paddingLeft: 1,
  paddingRight: 0,
  marginLeft: 5
})
// Use innerWidth to pre-size content before calling makeBox
```

## License

MIT

## Other rendering libs

- https://github.com/tecfu/tty-table
- https://www.npmjs.com/package/boxen
