docs: update heading image for Ratatui 0.30.0 release 🎉 (#2000)

Co-authored-by: Orhun Parmaksız <orhun@archlinux.org>
Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
This commit is contained in:
Jagoda Estera Ślązak 2025-07-25 23:30:36 +02:00 committed by GitHub
parent c01b7d43ea
commit cba5cca2bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 226 additions and 2 deletions

8
Cargo.lock generated
View File

@ -2692,6 +2692,14 @@ version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2"
[[package]]
name = "release-header"
version = "0.0.0"
dependencies = [
"color-eyre",
"ratatui",
]
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.14" version = "0.17.14"

View File

@ -12,7 +12,7 @@
</details> </details>
![Demo](https://github.com/ratatui/ratatui/blob/87ae72dbc756067c97f6400d3e2a58eeb383776e/examples/demo2-destroy.gif?raw=true) ![Release header](https://github.com/ratatui/ratatui/blob/b23480adfa9430697071c906c7ba4d4f9bd37a73/assets/release-header.png?raw=true)
<div align="center"> <div align="center">

View File

@ -0,0 +1,13 @@
[package]
name = "release-header"
publish = false
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
color-eyre.workspace = true
ratatui.workspace = true
[lints]
workspace = true

View File

@ -0,0 +1,13 @@
# Release Header
Generates a banner for Ratatui releases featuring a Ratatui logo, version info, and a list of crates.
Used for README.md, documentation, and release materials. Updated for every release starting with v0.30.0 "Bryndza".
## Usage
```bash
cargo run --p release-header
```
Press any key to exit. Creates a fixed 68x16 terminal viewport.

View File

@ -0,0 +1,171 @@
//! Generates a terminal banner for Ratatui releases featuring a Ratatui logo, version info, and
//! a list of crates.
//!
//! Used for README.md, documentation, and release materials. Updated for every release starting
//! with v0.30.0 "Bryndza".
//!
//! This example runs with the Ratatui library code in the branch that you are currently
//! reading. See the [`latest`] branch for the code which works with the most recent Ratatui
//! release.
//!
//! [`latest`]: https://github.com/ratatui/ratatui/tree/latest
use std::io::stdout;
use std::iter::zip;
use ratatui::crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen};
use ratatui::crossterm::{event, execute};
use ratatui::layout::{Constraint, Flex, Layout, Margin, Rect, Spacing};
use ratatui::style::{Color, Stylize};
use ratatui::symbols::merge::MergeStrategy;
use ratatui::text::Line;
use ratatui::widgets::{Block, BorderType, Padding, Paragraph, RatatuiLogo};
use ratatui::{DefaultTerminal, Frame, TerminalOptions, Viewport};
const SEMVER: &str = "0.30.0";
const RELEASE_NAME: &str = "Bryndza";
const MAIN_DISHES: [&str; 4] = [
"> ratatui",
"> ratatui-core",
"> ratatui-widgets",
"> ratatui-macros",
];
const BACKENDS: [&str; 3] = [
"> ratatui-crossterm",
"> ratatui-termion",
"> ratatui-termwiz",
];
const FG_COLOR: Color = Color::Rgb(246, 214, 187); // #F6D6BB
const BG_COLOR: Color = Color::Rgb(20, 20, 50); // #141432
const MENU_BORDER_COLOR: Color = Color::Rgb(255, 255, 160); // #FFFFA0
enum Rainbow {
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet,
}
fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
let viewport = Viewport::Fixed(Rect::new(0, 0, 68, 16));
let terminal = ratatui::init_with_options(TerminalOptions { viewport });
execute!(stdout(), EnterAlternateScreen).expect("failed to enter alternate screen");
let result = run(terminal);
execute!(stdout(), LeaveAlternateScreen).expect("failed to leave alternate screen");
ratatui::restore();
result
}
fn run(mut terminal: DefaultTerminal) -> color_eyre::Result<()> {
loop {
terminal.draw(render)?;
if event::read()?.is_key_press() {
break Ok(());
}
}
}
fn render(frame: &mut Frame) {
let area = frame.area();
frame.buffer_mut().set_style(area, (FG_COLOR, BG_COLOR));
let logo_width = 29;
let menu_width = 23;
let padding = 2; // Padding between logo and menu
let menu_borders = 3;
let height = MAIN_DISHES.len() as u16 + BACKENDS.len() as u16 + menu_borders;
let width = logo_width + menu_width + padding;
let center_area = area.centered(Constraint::Length(width), Constraint::Length(height));
let layout = Layout::horizontal(Constraint::from_lengths([logo_width, padding, menu_width]));
let [logo_area, _, menu_area] = center_area.layout(&layout);
render_logo(frame, logo_area);
render_menu(frame, menu_area);
}
fn render_logo(frame: &mut Frame, area: Rect) {
let area = area.inner(Margin::new(1, 0));
let layout = Layout::vertical(Constraint::from_lengths([6, 2, 1])).flex(Flex::End);
let [shadow_area, logo_area, version_area] = area.layout(&layout);
// Divide the logo into letter sections for individual coloring, then render a block for each
// letter with a color based on the row index.
let letter_layout = Layout::horizontal(Constraint::from_lengths([5, 4, 4, 4, 4, 5, 1]));
for (row_index, row) in shadow_area.rows().enumerate() {
for (rainbow, letter_area) in zip(Rainbow::ROYGBIV, row.layout_vec(&letter_layout)) {
let color = rainbow.gradient_color(row_index);
frame.render_widget(Block::new().style(color), letter_area);
}
// Render the Ratatui logo truncated.
frame.render_widget(RatatuiLogo::small(), row);
}
frame.render_widget(Block::new().style(FG_COLOR), logo_area);
frame.render_widget(RatatuiLogo::small(), logo_area);
frame.render_widget(format!("v{SEMVER} \"{RELEASE_NAME}\"").dim(), version_area);
}
impl Rainbow {
const RED_GRADIENT: [u8; 6] = [41, 43, 50, 68, 104, 156];
const GREEN_GRADIENT: [u8; 6] = [24, 30, 41, 65, 105, 168];
const BLUE_GRADIENT: [u8; 6] = [55, 57, 62, 78, 113, 166];
const AMBIENT_GRADIENT: [u8; 6] = [17, 18, 20, 25, 40, 60];
const ROYGBIV: [Self; 7] = [
Self::Red,
Self::Orange,
Self::Yellow,
Self::Green,
Self::Blue,
Self::Indigo,
Self::Violet,
];
fn gradient_color(&self, row: usize) -> Color {
let ambient = Self::AMBIENT_GRADIENT[row];
let red = Self::RED_GRADIENT[row];
let green = Self::GREEN_GRADIENT[row];
let blue = Self::BLUE_GRADIENT[row];
let blue_sat = Self::AMBIENT_GRADIENT[row].saturating_mul(6 - row as u8);
let (r, g, b) = match self {
Self::Red => (red, ambient, blue_sat),
Self::Orange => (red, green / 2, blue_sat),
Self::Yellow => (red, green, blue_sat),
Self::Green => (ambient, green, blue_sat),
Self::Blue => (ambient, ambient, blue.max(blue_sat)),
Self::Indigo => (blue, ambient, blue.max(blue_sat)),
Self::Violet => (red, ambient, blue.max(blue_sat)),
};
Color::Rgb(r, g, b)
}
}
fn render_menu(frame: &mut Frame, area: Rect) {
let layout = Layout::vertical(Constraint::from_lengths([
MAIN_DISHES.len() as u16 + 2,
BACKENDS.len() as u16 + 2,
]))
.spacing(Spacing::Overlap(1)); // Overlap to merge borders
let [main_dishes_area, backends_area] = area.layout(&layout);
render_menu_block(frame, main_dishes_area, "Main Courses", &MAIN_DISHES);
render_menu_block(frame, backends_area, "Pairings", &BACKENDS);
}
fn render_menu_block(frame: &mut Frame, area: Rect, title: &str, menu_items: &[&str]) {
let menu_block = Block::bordered()
.border_type(BorderType::Rounded)
.border_style(MENU_BORDER_COLOR)
.padding(Padding::horizontal(1))
.merge_borders(MergeStrategy::Fuzzy)
.title(title);
let menu_lines: Vec<Line> = menu_items.iter().map(|&item| Line::from(item)).collect();
frame.render_widget(Paragraph::new(menu_lines).block(menu_block), area);
}

View 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/vhs/release-header.tape`
# NOTE: Requires VHS 0.6.1 or later for Screenshot support
# The reason for this strange size is that the social preview image for this
# demo is 1280x64 with 80 pixels of padding on each side. We want a version
# without the padding for README.md, etc.
Set Theme {"background": "#141432"}
Set FontSize 25
Set Width 1120
Set Height 480
Set Padding 0
Hide
Type "cargo run -p release-header"
Enter
Sleep 1s
Show
Sleep 1s
Screenshot assets/release-header.png
Sleep 1s

View File

@ -7,7 +7,7 @@
html_favicon_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/favicon.ico" html_favicon_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/favicon.ico"
)] )]
#![warn(missing_docs)] #![warn(missing_docs)]
//! ![Demo](https://github.com/ratatui/ratatui/blob/87ae72dbc756067c97f6400d3e2a58eeb383776e/examples/demo2-destroy.gif?raw=true) //! ![Release header](https://github.com/ratatui/ratatui/blob/b23480adfa9430697071c906c7ba4d4f9bd37a73/assets/release-header.png?raw=true)
//! //!
//! <div align="center"> //! <div align="center">
//! //!