Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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: 3 months ago
JSON representation
Vue for interactive command-line apps
- Host: GitHub
- URL: https://github.com/webfansplz/temir
- Owner: webfansplz
- License: mit
- Archived: true
- Created: 2022-07-28T13:32:51.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-11-07T13:19:19.000Z (about 1 year ago)
- Last Synced: 2024-09-22T04:32:41.037Z (3 months ago)
- Topics: cli, command-line, flexbox, interactive, reactivity, vue
- Language: TypeScript
- Homepage:
- Size: 6.47 MB
- Stars: 1,008
- Watchers: 7
- Forks: 36
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# This repository has been archived, please use [Vue TermUI](https://github.com/vue-terminal/vue-termui) instead.
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