mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-22 12:43:16 +00:00
docs(examples): Add examples readme with gifs (#303)
This commit adds a readme to the examples directory with gifs of each example. This should make it easier to see what each example does without having to run it. I modified the examples to fit better in the gifs. Mostly this was just removing the margins, but for the block example I cleaned up the code a bit to make it more readable and changed it so the background bug is not triggered. For the table example, the combination of Min, Length, and Percent constraints was causing the table to panic when the terminal was too small. I changed the example to use the Max constraint instead of the Length constraint. The layout example now shows information about how the layout is constrained on each block (which is now a paragraph with a block).
This commit is contained in:
parent
60a4131384
commit
add578a7d6
29 changed files with 545 additions and 74 deletions
209
examples/README.md
Normal file
209
examples/README.md
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
These gifs were created using [Charm VHS](https://github.com/charmbracelet/vhs).
|
||||||
|
|
||||||
|
VHS has a problem rendering some background color transitions, which shows up in several examples
|
||||||
|
below. See <https://github.com/charmbracelet/vhs/issues/344> for more info. These problems don't
|
||||||
|
occur in a terminal.
|
||||||
|
|
||||||
|
## Barchart ([barchart.rs](./barchart.rs)
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=barchart --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Barchart][barchart.gif]
|
||||||
|
|
||||||
|
## Block ([block.rs](./block.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=block --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Block][block.gif]
|
||||||
|
|
||||||
|
## Calendar ([calendar.rs](./calendar.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=calendar --features=crossterm widget-calendar
|
||||||
|
```
|
||||||
|
|
||||||
|
![Calendar][calendar.gif]
|
||||||
|
|
||||||
|
## Canvas ([canvas.rs](./canvas.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=canvas --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Canvas][canvas.gif]
|
||||||
|
|
||||||
|
## Chart ([chart.rs](./chart.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=chart --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Chart][chart.gif]
|
||||||
|
|
||||||
|
## Custom Widget ([custom_widget.rs](./custom_widget.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=custom_widget --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
This is not a particularly exciting example visually, but it demonstrates how to implement your own widget.
|
||||||
|
|
||||||
|
![Custom Widget][custom_widget.gif]
|
||||||
|
|
||||||
|
## Gauge ([gauge.rs](./gauge.rs))
|
||||||
|
|
||||||
|
Please note: the background renders poorly when we generate this example using VHS.
|
||||||
|
This problem doesn't generally happen during normal rendering in a terminal.
|
||||||
|
See <https://github.com/charmbracelet/vhs/issues/344> for more details
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=gauge --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Gauge][gauge.gif]
|
||||||
|
|
||||||
|
## Hello World ([hello_world.rs](./hello_world.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=hello_world --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a pretty boring example, but it contains some good comments of documentation on some of the
|
||||||
|
standard approaches to writing tui apps.
|
||||||
|
|
||||||
|
![Hello World][hello_world.gif]
|
||||||
|
|
||||||
|
## Inline ([inline.rs](./inline.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=inline --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Inline][inline.gif]
|
||||||
|
|
||||||
|
## Layout ([layout.rs](./layout.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=layout --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Layout][layout.gif]
|
||||||
|
|
||||||
|
## List ([list.rs](./list.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=list --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![List][list.gif]
|
||||||
|
|
||||||
|
## Panic ([panic.rs](./panic.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=panic --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Panic][panic.gif]
|
||||||
|
|
||||||
|
## Paragraph ([paragraph.rs](./paragraph.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=paragraph --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Paragraph][paragraph.gif]
|
||||||
|
|
||||||
|
## Popup ([popup.rs](./popup.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=popup --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note: the background renders poorly when we generate this example using VHS.
|
||||||
|
This problem doesn't generally happen during normal rendering in a terminal.
|
||||||
|
See <https://github.com/charmbracelet/vhs/issues/344> for more details
|
||||||
|
|
||||||
|
![Popup][popup.gif]
|
||||||
|
|
||||||
|
## Scrollbar ([scrollbar.rs](./scrollbar.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=scrollbar --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Scrollbar][scrollbar.gif]
|
||||||
|
|
||||||
|
## Sparkline ([sparkline.rs](./sparkline.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=sparkline --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Sparkline][sparkline.gif]
|
||||||
|
|
||||||
|
## Table ([table.rs](./table.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=table --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Table][table.gif]
|
||||||
|
|
||||||
|
## Tabs ([tabs.rs](./tabs.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=tabs --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![Tabs][tabs.gif]
|
||||||
|
|
||||||
|
## User Input ([user_input.rs](./user_input.rs))
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --example=user_input --features=crossterm
|
||||||
|
```
|
||||||
|
|
||||||
|
![User Input][user_input.gif]
|
||||||
|
|
||||||
|
<!--
|
||||||
|
links to images to make it easier to update in bulk
|
||||||
|
These are generated with `vhs publish examples/xxx.gif`
|
||||||
|
|
||||||
|
To update these examples in bulk:
|
||||||
|
```shell
|
||||||
|
# build to ensure that running the examples doesn't have to wait so long
|
||||||
|
cargo build --examples --features=crossterm,all-widgets
|
||||||
|
for i in examples/*.tape
|
||||||
|
do
|
||||||
|
echo -n "[${i:s:examples/:::s:.tape:.gif:}]: "
|
||||||
|
vhs $i --publish --quiet
|
||||||
|
# may need to adjust this depending on if you see rate limiting from VHS
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
```
|
||||||
|
-->
|
||||||
|
[barchart.gif]: https://vhs.charm.sh/vhs-6ioxdeRBVkVpyXcjIEVaJU.gif
|
||||||
|
[block.gif]: https://vhs.charm.sh/vhs-1sEo9vVkHRwFtu95MOXrTj.gif
|
||||||
|
[calendar.gif]: https://vhs.charm.sh/vhs-1dBcpMSSP80WkBgm4lBhNo.gif
|
||||||
|
[canvas.gif]: https://vhs.charm.sh/vhs-4zeWEPF6bLEFSHuJrvaHlN.gif
|
||||||
|
[chart.gif]: https://vhs.charm.sh/vhs-zRzsE2AwRixQhcWMTAeF1.gif
|
||||||
|
[custom_widget.gif]: https://vhs.charm.sh/vhs-32mW1TpkrovTcm79QXmBSu.gif
|
||||||
|
[gauge.gif]: https://vhs.charm.sh/vhs-2rvSeP5r4lRkGTzNCKpm9a.gif
|
||||||
|
[hello_world.gif]: https://vhs.charm.sh/vhs-3CKUwxFuQi8oKQMS5zkPfQ.gif
|
||||||
|
[inline.gif]: https://vhs.charm.sh/vhs-miRl1mosKFoJV7LjjvF4T.gif
|
||||||
|
[layout.gif]: https://vhs.charm.sh/vhs-5R8O3LQGQ5pQVWwlPVrdbQ.gif
|
||||||
|
[list.gif]: https://vhs.charm.sh/vhs-4goo9reeUM9r0nYb54R7SP.gif
|
||||||
|
[panic.gif]: https://vhs.charm.sh/vhs-HrvKCHV4yeN69fb1EadTH.gif
|
||||||
|
[paragraph.gif]: https://vhs.charm.sh/vhs-2qIPDi79DUmtmeNDEeHVEF.gif
|
||||||
|
[popup.gif]: https://vhs.charm.sh/vhs-2QnC682AUeNYNXcjNlKTyp.gif
|
||||||
|
[scrollbar.gif]: https://vhs.charm.sh/vhs-2p13MMFreW7Gwt1xIonIWu.gif
|
||||||
|
[sparkline.gif]: https://vhs.charm.sh/vhs-4t59Vxw5Za33Rtvt9QrftA.gif
|
||||||
|
[table.gif]: https://vhs.charm.sh/vhs-6IrGHgT385DqA6xnwGF9oD.gif
|
||||||
|
[tabs.gif]: https://vhs.charm.sh/vhs-61WkbfhyDk0kbkjncErdHT.gif
|
||||||
|
[user_input.gif]: https://vhs.charm.sh/vhs-4fxUgkpEWcVyBRXuyYKODY.gif
|
11
examples/barchart.tape
Normal file
11
examples/barchart.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/barchart.tape`
|
||||||
|
Output "target/barchart.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 800
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=barchart"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{error::Error, io};
|
use std::{error::Error, io, time::Duration};
|
||||||
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
|
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
|
||||||
|
@ -25,6 +25,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
LeaveAlternateScreen,
|
LeaveAlternateScreen,
|
||||||
DisableMouseCapture
|
DisableMouseCapture
|
||||||
)?;
|
)?;
|
||||||
|
terminal.clear()?;
|
||||||
terminal.show_cursor()?;
|
terminal.show_cursor()?;
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
|
@ -38,59 +39,60 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> io::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
terminal.draw(ui)?;
|
terminal.draw(ui)?;
|
||||||
|
|
||||||
|
if event::poll(Duration::from_millis(250))? {
|
||||||
if let Event::Key(key) = event::read()? {
|
if let Event::Key(key) = event::read()? {
|
||||||
if let KeyCode::Char('q') = key.code {
|
if let KeyCode::Char('q') = key.code {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui<B: Backend>(f: &mut Frame<B>) {
|
fn ui<B: Backend>(f: &mut Frame<B>) {
|
||||||
// Wrapping block for a group
|
// Wrapping block for a group
|
||||||
// Just draw the block and the group on the same area and build the group
|
// Just draw the block and the group on the same area and build the group
|
||||||
// with at least a margin of 1
|
let outer = f.size();
|
||||||
let size = f.size();
|
let outer_block = Block::default()
|
||||||
|
|
||||||
// Surrounding block
|
|
||||||
let block = Block::default()
|
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.title(block::Title::from("Main block with round corners").alignment(Alignment::Center))
|
.title(block::Title::from("Main block with round corners").alignment(Alignment::Center))
|
||||||
.border_type(BorderType::Rounded);
|
.border_type(BorderType::Rounded);
|
||||||
f.render_widget(block, size);
|
let inner = outer_block.inner(outer);
|
||||||
|
let [top, bottom] = *Layout::default()
|
||||||
let chunks = Layout::default()
|
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(4)
|
.margin(1)
|
||||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||||
.split(f.size());
|
.split(inner)
|
||||||
|
else {
|
||||||
// Top two inner blocks
|
return;
|
||||||
let top_chunks = Layout::default()
|
};
|
||||||
|
let [top_left, top_right] = *Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||||
.split(chunks[0]);
|
.split(top)
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let [bottom_left, bottom_right] = *Layout::default()
|
||||||
|
.direction(Direction::Horizontal)
|
||||||
|
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||||
|
.split(bottom)
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
// Top left inner block with green background
|
let top_left_block = Block::default()
|
||||||
let block = Block::default()
|
.title("With Green Background")
|
||||||
.title(vec!["With".yellow(), " background".into()])
|
.borders(Borders::all())
|
||||||
.on_green();
|
.on_green();
|
||||||
f.render_widget(block, top_chunks[0]);
|
let top_right_block = Block::default()
|
||||||
|
.title(
|
||||||
// Top right inner block with styled title aligned to the right
|
block::Title::from("With styled title".white().on_red().bold())
|
||||||
let block = Block::default().title(
|
.alignment(Alignment::Right),
|
||||||
block::Title::from("Styled title".white().on_red().bold()).alignment(Alignment::Right),
|
)
|
||||||
);
|
.borders(Borders::ALL);
|
||||||
f.render_widget(block, top_chunks[1]);
|
let bottom_left_block = Paragraph::new("Text inside padded block").block(
|
||||||
|
Block::default()
|
||||||
// Bottom two inner blocks
|
|
||||||
let bottom_chunks = Layout::default()
|
|
||||||
.direction(Direction::Horizontal)
|
|
||||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
|
||||||
.split(chunks[1]);
|
|
||||||
|
|
||||||
// Bottom left block with all default borders
|
|
||||||
let block = Block::default()
|
|
||||||
.title("With borders")
|
.title("With borders")
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.padding(Padding {
|
.padding(Padding {
|
||||||
|
@ -98,24 +100,24 @@ fn ui<B: Backend>(f: &mut Frame<B>) {
|
||||||
right: 4,
|
right: 4,
|
||||||
top: 2,
|
top: 2,
|
||||||
bottom: 2,
|
bottom: 2,
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
let text = Paragraph::new("text inside padded block").block(block);
|
let bottom_right_block = Block::default()
|
||||||
f.render_widget(text, bottom_chunks[0]);
|
|
||||||
|
|
||||||
// Bottom right block with styled left and right border
|
|
||||||
let block = Block::default()
|
|
||||||
.title("With styled borders and doubled borders")
|
.title("With styled borders and doubled borders")
|
||||||
.border_style(Style::default().fg(Color::Cyan))
|
.border_style(Style::default().fg(Color::Cyan))
|
||||||
.borders(Borders::LEFT | Borders::RIGHT)
|
.borders(Borders::LEFT | Borders::RIGHT)
|
||||||
.border_type(BorderType::Double)
|
.border_type(BorderType::Double)
|
||||||
.padding(Padding::uniform(1));
|
.padding(Padding::uniform(1));
|
||||||
|
let bottom_inner_block = Block::default()
|
||||||
let inner_block = Block::default()
|
|
||||||
.title("Block inside padded block")
|
.title("Block inside padded block")
|
||||||
.borders(Borders::ALL);
|
.borders(Borders::ALL);
|
||||||
|
|
||||||
let inner_area = block.inner(bottom_chunks[1]);
|
f.render_widget(outer_block, outer);
|
||||||
f.render_widget(block, bottom_chunks[1]);
|
f.render_widget(Clear, top_left);
|
||||||
f.render_widget(inner_block, inner_area);
|
f.render_widget(top_left_block, top_left);
|
||||||
|
f.render_widget(top_right_block, top_right);
|
||||||
|
f.render_widget(bottom_left_block, bottom_left);
|
||||||
|
let bottom_right_inner = bottom_right_block.inner(bottom_right);
|
||||||
|
f.render_widget(bottom_right_block, bottom_right);
|
||||||
|
f.render_widget(bottom_inner_block, bottom_right_inner);
|
||||||
}
|
}
|
||||||
|
|
11
examples/block.tape
Normal file
11
examples/block.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/block.tape`
|
||||||
|
Output "target/block.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 800
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=block"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
11
examples/calendar.tape
Normal file
11
examples/calendar.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/calendar.tape`
|
||||||
|
Output "target/calendar.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 800
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=calendar --features=crossterm,widget-calendar"
|
||||||
|
Enter
|
||||||
|
Sleep 3s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
11
examples/canvas.tape
Normal file
11
examples/canvas.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/canvas.tape`
|
||||||
|
Output "target/canvas.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 800
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=canvas --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
11
examples/chart.tape
Normal file
11
examples/chart.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/chart.tape`
|
||||||
|
Output "target/chart.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 800
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=chart --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
11
examples/custom_widget.tape
Normal file
11
examples/custom_widget.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/custom_widget.tape`
|
||||||
|
Output "target/custom_widget.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 200
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=custom_widget --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
|
@ -106,7 +106,6 @@ fn run_app<B: Backend>(
|
||||||
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(2)
|
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Percentage(25),
|
Constraint::Percentage(25),
|
||||||
|
@ -148,7 +147,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
||||||
|
|
||||||
let label = format!("{}/100", app.progress4);
|
let label = format!("{}/100", app.progress4);
|
||||||
let gauge = Gauge::default()
|
let gauge = Gauge::default()
|
||||||
.block(Block::default().title("Gauge4"))
|
.block(Block::default().title("Gauge4").borders(Borders::ALL))
|
||||||
.gauge_style(
|
.gauge_style(
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(Color::Cyan)
|
.fg(Color::Cyan)
|
||||||
|
|
11
examples/gauge.tape
Normal file
11
examples/gauge.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/gauge.tape`
|
||||||
|
Output "target/gauge.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=gauge --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 20s
|
11
examples/hello_world.tape
Normal file
11
examples/hello_world.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/hello_world.tape`
|
||||||
|
Output "target/hello_world.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 200
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=hello_world --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
8
examples/inline.tape
Normal file
8
examples/inline.tape
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/inline.tape`
|
||||||
|
Output "target/inline.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Type "cargo run --example=inline --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 20s
|
|
@ -46,21 +46,51 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui<B: Backend>(f: &mut Frame<B>) {
|
fn ui<B: Backend>(frame: &mut Frame<B>) {
|
||||||
let chunks = Layout::default()
|
let [top, mid, bottom] = *Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Percentage(10),
|
Constraint::Length(4),
|
||||||
Constraint::Percentage(80),
|
Constraint::Percentage(50),
|
||||||
Constraint::Percentage(10),
|
Constraint::Min(4),
|
||||||
]
|
]
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
)
|
)
|
||||||
.split(f.size());
|
.split(frame.size())
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let [left, right] = *Layout::default()
|
||||||
|
.direction(Direction::Horizontal)
|
||||||
|
.horizontal_margin(5)
|
||||||
|
.vertical_margin(2)
|
||||||
|
.constraints([Constraint::Ratio(2, 5), Constraint::Ratio(3, 5)].as_ref())
|
||||||
|
.split(mid)
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
frame.render_widget(
|
||||||
|
Paragraph::new("Constraint::Length(4)").block(Block::default().borders(Borders::ALL)),
|
||||||
|
top,
|
||||||
|
);
|
||||||
|
|
||||||
let block = Block::default().title("Block").borders(Borders::ALL);
|
frame.render_widget(
|
||||||
f.render_widget(block, chunks[0]);
|
Paragraph::new("Constraint::Percentage(50)").block(Block::default().borders(Borders::ALL)),
|
||||||
let block = Block::default().title("Block 2").borders(Borders::ALL);
|
mid,
|
||||||
f.render_widget(block, chunks[2]);
|
);
|
||||||
|
|
||||||
|
frame.render_widget(
|
||||||
|
Paragraph::new("Constraint::Ratio(2, 5)\nhorizontal_margin(5)\nvertical_margin(2)")
|
||||||
|
.block(Block::default().borders(Borders::ALL)),
|
||||||
|
left,
|
||||||
|
);
|
||||||
|
frame.render_widget(
|
||||||
|
Paragraph::new("Constraint::Ratio(3, 5)").block(Block::default().borders(Borders::ALL)),
|
||||||
|
right,
|
||||||
|
);
|
||||||
|
frame.render_widget(
|
||||||
|
Paragraph::new("Constraint::Min(4)").block(Block::default().borders(Borders::ALL)),
|
||||||
|
bottom,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
11
examples/layout.tape
Normal file
11
examples/layout.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/layout.tape`
|
||||||
|
Output "target/layout.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=layout --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
14
examples/list.tape
Normal file
14
examples/list.tape
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/list.tape`
|
||||||
|
Output "target/list.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=list --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Down@1s 4
|
||||||
|
Up@1s 2
|
||||||
|
Left@1s 1
|
||||||
|
Sleep 5s
|
19
examples/panic.tape
Normal file
19
examples/panic.tape
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/panic.tape`
|
||||||
|
Output "target/panic.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Type "cargo run --example=panic --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 5s
|
||||||
|
Type p
|
||||||
|
Sleep 2s
|
||||||
|
Type reset
|
||||||
|
Enter
|
||||||
|
Type "cargo run --example=panic --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 2s
|
||||||
|
Type e
|
||||||
|
Sleep 2s
|
||||||
|
Type p
|
||||||
|
Sleep 5s
|
|
@ -94,7 +94,6 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
||||||
|
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(2)
|
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Percentage(25),
|
Constraint::Percentage(25),
|
||||||
|
|
11
examples/paragraph.tape
Normal file
11
examples/paragraph.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/paragraph.tape`
|
||||||
|
Output "target/paragraph.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 1800
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=paragraph --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
15
examples/popup.tape
Normal file
15
examples/popup.tape
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/popup.tape`
|
||||||
|
Output "target/popup.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=popup --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 2s
|
||||||
|
Type p
|
||||||
|
Sleep 2s
|
||||||
|
Type p
|
||||||
|
Sleep 5s
|
|
@ -111,7 +111,6 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
||||||
|
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(2)
|
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Min(1),
|
Constraint::Min(1),
|
||||||
|
|
11
examples/scrollbar.tape
Normal file
11
examples/scrollbar.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/scrollbar.tape`
|
||||||
|
Output "target/scrollbar.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 1200
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=scrollbar --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
|
@ -129,7 +129,6 @@ fn run_app<B: Backend>(
|
||||||
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(2)
|
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
|
|
11
examples/sparkline.tape
Normal file
11
examples/sparkline.tape
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/sparkline.tape`
|
||||||
|
Output "target/sparkline.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=sparkline --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 5s
|
|
@ -116,7 +116,6 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<(
|
||||||
fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
||||||
let rects = Layout::default()
|
let rects = Layout::default()
|
||||||
.constraints([Constraint::Percentage(100)].as_ref())
|
.constraints([Constraint::Percentage(100)].as_ref())
|
||||||
.margin(5)
|
|
||||||
.split(f.size());
|
.split(f.size());
|
||||||
|
|
||||||
let selected_style = Style::default().add_modifier(Modifier::REVERSED);
|
let selected_style = Style::default().add_modifier(Modifier::REVERSED);
|
||||||
|
@ -145,7 +144,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
||||||
.highlight_symbol(">> ")
|
.highlight_symbol(">> ")
|
||||||
.widths(&[
|
.widths(&[
|
||||||
Constraint::Percentage(50),
|
Constraint::Percentage(50),
|
||||||
Constraint::Length(30),
|
Constraint::Max(30),
|
||||||
Constraint::Min(10),
|
Constraint::Min(10),
|
||||||
]);
|
]);
|
||||||
f.render_stateful_widget(t, rects[0], &mut app.state);
|
f.render_stateful_widget(t, rects[0], &mut app.state);
|
||||||
|
|
15
examples/table.tape
Normal file
15
examples/table.tape
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/table.tape`
|
||||||
|
Output "target/table.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=table --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Down@1s 4
|
||||||
|
Up@1s 2
|
||||||
|
Down@1s 8
|
||||||
|
Up@1s 12
|
||||||
|
Sleep 5s
|
|
@ -82,7 +82,6 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(5)
|
|
||||||
.constraints([Constraint::Length(3), Constraint::Min(0)].as_ref())
|
.constraints([Constraint::Length(3), Constraint::Min(0)].as_ref())
|
||||||
.split(size);
|
.split(size);
|
||||||
|
|
||||||
|
|
13
examples/tabs.tape
Normal file
13
examples/tabs.tape
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/tabs.tape`
|
||||||
|
Output "target/tabs.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 300
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=tabs --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Right@1s 4
|
||||||
|
Left@1s 2
|
||||||
|
Sleep 5s
|
|
@ -174,7 +174,6 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<(
|
||||||
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.margin(2)
|
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Length(1),
|
Constraint::Length(1),
|
||||||
|
|
21
examples/user_input.tape
Normal file
21
examples/user_input.tape
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
|
||||||
|
# To run this script, install vhs and run `vhs ./examples/user_input.tape`
|
||||||
|
Output "target/user_input.gif"
|
||||||
|
Set Width 1200
|
||||||
|
Set Height 600
|
||||||
|
Hide
|
||||||
|
Type "cargo run --example=user_input --features=crossterm"
|
||||||
|
Enter
|
||||||
|
Sleep 1s
|
||||||
|
Show
|
||||||
|
Sleep 2s
|
||||||
|
Type e
|
||||||
|
Sleep 1s
|
||||||
|
Type "Hello, world!"
|
||||||
|
Enter
|
||||||
|
Sleep 2s
|
||||||
|
Backspace 13
|
||||||
|
Sleep 1s
|
||||||
|
Type "Goodbye, world!"
|
||||||
|
Enter
|
||||||
|
Sleep 5s
|
Loading…
Reference in a new issue