Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/webfansplz/temir

Vue for interactive command-line apps
https://github.com/webfansplz/temir

cli command-line flexbox interactive reactivity vue

Last synced: about 2 months ago
JSON representation

Vue for interactive command-line apps

Awesome Lists containing this project

README

        

# This repository has been archived, please use [Vue TermUI](https://github.com/vue-terminal/vue-termui) instead.






Temir







English | 简体中文

> Vue for CLIs. Build your CLI output using components.

Temir provides the same component-based UI building experience that Vue offers in the browser, but for command-line apps.

It uses [Yoga](https://github.com/facebook/yoga) to build Flexbox layouts in the terminal, so most CSS-like props are available in Temir as well.
If you are already familiar with Vue, you already know Temir.

Since Temir is a Vue renderer, it means that most of the features of Vue are supported.
Head over to [Vue](https://vuejs.org/) website for documentation on how to use it.
Only Temir's methods will be documented in this readme.

---

## Install

```sh
npm install @temir/core
```

## Usage

```vue

import { ref } from '@vue/runtime-core'
import { TBox, TText } from '@temir/core'
const counter = ref(0)
setInterval(() => {
counter.value++
}, 100)



{{ counter }} tests passed

```

## HMR Support

## Contents

- [Getting Started](#getting-started)
- [Components](#components)
- [``](#text)
- [``](#box)
- [``](#newline)
- [``](#spacer)
- [``](https://github.com/webfansplz/temir/tree/main/packages/temir-link)
- [``](https://github.com/webfansplz/temir/tree/main/packages/temir-tab)
- [``](https://github.com/webfansplz/temir/tree/main/packages/temir-spinner)
- [``](https://github.com/webfansplz/temir/tree/main/packages/temir-select-input)
- 💻 Still working and welcome to contribute.

- [Examples](https://github.com/webfansplz/temir/tree/main/examples)
- [hi-temir](https://github.com/webfansplz/temir/tree/main/examples/hi-temir)
![](./media/hi-temir.png)
- [borders](https://github.com/webfansplz/temir/tree/main/examples/borders)
![](./media/temir-borders.png)
- [table](https://github.com/webfansplz/temir/tree/main/examples/table)
![](./media/temir-table.png)
- [temir-link](https://github.com/webfansplz/temir/tree/main/examples/temir-link)
![](./packages/temir-link/media/temir-link.png)
- [temir-spinner](https://github.com/webfansplz/temir/tree/main/examples/temir-spinner)
![](./packages/temir-spinner/media/temir-spinner.gif)
- [temir-tab](https://github.com/webfansplz/temir/tree/main/examples/temir-tab)
![](./packages/temir-tab/media/temir-tab.gif)
- [temir-select-input](https://github.com/webfansplz/temir/tree/main/examples/temir-select-input)
![](./packages/temir-select-input/media/temir-select-input.gif)
- [Vitest](https://github.com/webfansplz/temir/tree/main/examples/vitest)
![](./media/temir-vitest.gif)

## Getting Started

Use `@temir/cli` to quickly scaffold a new Temir-based CLI.

```sh

mkdir my-temir-cli

cd my-temir-cli

touch main.ts

npm install @temir/cli

# Dev

temir main.ts

# Build

temir build main.ts
```

You can also check it out this [example](https://github.com/webfansplz/temir/tree/main/examples/hi-temir) to get started.Feel free to play around with the example and fork this repl at [repl.it sandbox](https://replit.com/@webfansplz/hi-temir?v=1)

Temir uses Yoga - a Flexbox layout engine to build great user interfaces for your CLIs using familiar CSS-like props you've used when building apps for the browser. It's important to remember that each element is a Flexbox container. Think of it as if each

in the browser had display: flex. See built-in component below for documentation on how to use Flexbox layouts in Ink. Note that all text must be wrapped in a component.

## Components

### ``

This component can display text, and change its style to make it bold, underline, italic or strikethrough.

![temir-text-props](./media/temir-text-props.png)

```vue

I am green

I am black on white

I am white

I am bold

I am italic

I am underline

I am strikethrough

I am inversed

```

**Note:** `` allows only text nodes and nested `` components inside of it. For example, `` component can't be used inside ``.

#### color

Type: `string`

Change text color.
Temir uses [chalk](https://github.com/chalk/chalk) under the hood, so all its functionality is supported.

```vue


Green


Blue


Red

```

#### backgroundColor

Type: `string`

Same as `color` above, but for background.

```vue


Green


Blue


Red

```

#### dimColor

Type: `boolean`\
Default: `false`

Dim the color (emit a small amount of light).

```vue

Dimmed Red

```

#### bold

Type: `boolean`\
Default: `false`

Make the text bold.

#### italic

Type: `boolean`\
Default: `false`

Make the text italic.

#### underline

Type: `boolean`\
Default: `false`

Make the text underlined.

#### strikethrough

Type: `boolean`\
Default: `false`

Make the text crossed with a line.

#### inverse

Type: `boolean`\
Default: `false`

Inverse background and foreground colors.

```vue

Inversed Yellow

```

#### wrap

Type: `string`\
Allowed values: `wrap` `truncate` `truncate-start` `truncate-middle` `truncate-end`\
Default: `wrap`

This property tells Temir to wrap or truncate text if its width is larger than container.
If `wrap` is passed (by default), Temir will wrap text and split it into multiple lines.
If `truncate-*` is passed, Temir will truncate text instead, which will result in one line of text with the rest cut off.

```vue


Hello World

//=> 'Hello\nWorld'

// `truncate` is an alias to `truncate-end`


Hello World


//=> 'Hello…'



Hello World


//=> 'He…ld'



Hello World


//=> '…World'

```

### ``

`` is an essential Temir component to build your layout.
It's like `

` in the browser.

```vue

import { TBox, TText } from '@temir/core'


This is a box with margin

```

#### Dimensions

##### width

Type: `number` `string`

Width of the element in spaces.
You can also set it in percent, which will calculate the width based on the width of parent element.

```vue


X

//=> 'X '

```

```vue



X


Y

//=> 'X Y'

```

##### height

Type: `number` `string`

Height of the element in lines (rows).
You can also set it in percent, which will calculate the height based on the height of parent element.

```vue


X

//=> 'X\n\n\n'

```

```vue



X


Y


//=> 'X\n\n\nY\n\n'

```

##### minWidth

Type: `number`

Sets a minimum width of the element.
Percentages aren't supported yet, see https://github.com/facebook/yoga/issues/872.

##### minHeight

Type: `number`

Sets a minimum height of the element.
Percentages aren't supported yet, see https://github.com/facebook/yoga/issues/872.

#### Padding

##### paddingTop

Type: `number`\
Default: `0`

Top padding.

##### paddingBottom

Type: `number`\
Default: `0`

Bottom padding.

##### paddingLeft

Type: `number`\
Default: `0`

Left padding.

##### paddingRight

Type: `number`\
Default: `0`

Right padding.

##### paddingX

Type: `number`\
Default: `0`

Horizontal padding. Equivalent to setting `paddingLeft` and `paddingRight`.

##### paddingY

Type: `number`\
Default: `0`

Vertical padding. Equivalent to setting `paddingTop` and `paddingBottom`.

##### padding

Type: `number`\
Default: `0`

Padding on all sides. Equivalent to setting `paddingTop`, `paddingBottom`, `paddingLeft` and `paddingRight`.

```vue


Top


Bottom


Left


Right


Left and right


Top and bottom


Top, bottom, left and right

```

#### Margin

##### marginTop

Type: `number`\
Default: `0`

Top margin.

##### marginBottom

Type: `number`\
Default: `0`

Bottom margin.

##### marginLeft

Type: `number`\
Default: `0`

Left margin.

##### marginRight

Type: `number`\
Default: `0`

Right margin.

##### marginX

Type: `number`\
Default: `0`

Horizontal margin. Equivalent to setting `marginLeft` and `marginRight`.

##### marginY

Type: `number`\
Default: `0`

Vertical margin. Equivalent to setting `marginTop` and `marginBottom`.

##### margin

Type: `number`\
Default: `0`

Margin on all sides. Equivalent to setting `marginTop`, `marginBottom`, `marginLeft` and `marginRight`.

```vue


Top


Bottom


Left


Right


Left and right


Top and bottom


Top, bottom, left and right

```

#### Flex

##### flexGrow

Type: `number`\
Default: `0`

See [flex-grow](https://css-tricks.com/almanac/properties/f/flex-grow/).

```vue


Label:

Fills all remaining space

```

##### flexShrink

Type: `number`\
Default: `1`

See [flex-shrink](https://css-tricks.com/almanac/properties/f/flex-shrink/).

```vue



Will be 1/4


Will be 3/4

```

##### flexBasis

Type: `number` `string`

See [flex-basis](https://css-tricks.com/almanac/properties/f/flex-basis/).

```vue



X


Y


//=> 'X Y'

```

```vue



X


Y


//=> 'X Y'

```

##### flexDirection

Type: `string`\
Allowed values: `row` `row-reverse` `column` `column-reverse`

See [flex-direction](https://css-tricks.com/almanac/properties/f/flex-direction/).

```vue



X


Y


// X Y


X

Y


// Y X


X
Y

// X
// Y


X
Y

// Y
// X

```

##### alignItems

Type: `string`\
Allowed values: `flex-start` `center` `flex-end`

See [align-items](https://css-tricks.com/almanac/properties/a/align-items/).

```vue



X


A

B

C


// X A
// B
// C



X


A

B

C


// A
// X B
// C



X


A

B

C


// A
// B
// X C

```

##### alignSelf

Type: `string`\
Default: `auto`\
Allowed values: `auto` `flex-start` `center` `flex-end`

See [align-self](https://css-tricks.com/almanac/properties/a/align-self/).

```vue



X


// X
//
//



X


//
// X
//



X


//
//
// X

```

##### justifyContent

Type: `string`\
Allowed values: `flex-start` `center` `flex-end` `space-between` `space-around`

See [justify-content](https://css-tricks.com/almanac/properties/j/justify-content/).

```vue


X

// [X ]


X

// [ X ]


X

// [ X]


X
Y

// [X Y]


X
Y

// [ X Y ]

```

#### Visibility

##### display

Type: `string`\
Allowed values: `flex` `none`\
Default: `flex`

Set this property to `none` to hide the element.

#### Borders

##### borderStyle

Type: `string`\
Allowed values: `single` `double` `round` `bold` `singleDouble` `doubleSingle` `classic`

Add a border with a specified style.
If `borderStyle` is `undefined` (which it is by default), no border will be added.
Temir uses border styles from [`cli-boxes`](https://github.com/sindresorhus/cli-boxes) module.

```vue




single


double


round


bold



singleDouble


doubleSingle


classic


```

##### borderColor

Type: `string`

Change border color.
Accepts the same values as [`color`](#color) in `` component.

```vue


Green Rounded Box

```

### ``

Adds one or more newline (`\n`) characters.
Must be used within `` components.

#### count

Type: `number`\
Default: `1`

Number of newlines to insert.

```vue

import { TBox, TNewline, TText } from '@temir/core'




Hello



World


```

Output:

```
Hello
World
```

### ``

A flexible space that expands along the major axis of its containing layout.
It's useful as a shortcut for filling all the available spaces between elements.

For example, using `` in a `` with default flex direction (`row`) will position "Left" on the left side and will push "Right" to the right side.

```vue

import { TBox, TSpacer, TText } from '@temir/core'


Left

Right

```

In a vertical flex direction (`column`), it will position "Top" to the top of the container and push "Bottom" to the bottom of it.
Note, that container needs to be tall to enough to see this in effect.

```vue

import { TBox, TSpacer, TText } from '@temir/core'


Top

Bottom

```

## Credits

This project is highly inspired by [ink](https://github.com/vadimdemedes/ink)

[vite-node](https://github.com/antfu/vite-node) made the HMR support easily