feat: confirm component customization

This commit is contained in:
greg 2024-10-16 08:07:27 +02:00 committed by sxyazi
parent a6c9c93d58
commit a7b0e56b67
No known key found for this signature in database
6 changed files with 112 additions and 24 deletions

View file

@ -98,6 +98,22 @@ selected = { reversed = true }
# : }}} # : }}}
# : Confirm {{{
[confirm]
show_separators = true
show_scrollbar = true
button_yes = " [Y]es "
button_no = " (N)o "
border = { fg = "blue" }
title = { fg = "blue" }
content = { }
list = { }
buttons = { reversed = true }
# : }}}
# : Completion {{{ # : Completion {{{
[completion] [completion]

View file

@ -12,6 +12,7 @@ pub struct Theme {
pub manager: Manager, pub manager: Manager,
status: Status, status: Status,
pub input: Input, pub input: Input,
pub confirm: Confirm,
pub pick: Pick, pub pick: Pick,
pub completion: Completion, pub completion: Completion,
pub tasks: Tasks, pub tasks: Tasks,
@ -114,6 +115,19 @@ pub struct Input {
pub selected: Style, pub selected: Style,
} }
#[derive(Deserialize, Serialize)]
pub struct Confirm {
pub show_separators: bool,
pub show_scrollbar: bool,
pub button_yes: String,
pub button_no: String,
pub border: Style,
pub title: Style,
pub content: Style,
pub list: Style,
pub buttons: Style,
}
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct Pick { pub struct Pick {
pub border: Style, pub border: Style,

View file

@ -1,4 +1,11 @@
use ratatui::{buffer::Buffer, layout::{Constraint, Rect}, style::Stylize, text::Span, widgets::{Paragraph, Widget}}; use ratatui::{
buffer::Buffer,
layout::{Constraint, Rect},
text::Span,
widgets::{Paragraph, Widget},
};
use yazi_config::THEME;
pub(crate) struct Buttons; pub(crate) struct Buttons;
@ -7,7 +14,11 @@ impl Widget for Buttons {
let chunks = let chunks =
ratatui::layout::Layout::horizontal([Constraint::Fill(1), Constraint::Fill(1)]).split(area); ratatui::layout::Layout::horizontal([Constraint::Fill(1), Constraint::Fill(1)]).split(area);
Paragraph::new(Span::raw(" [Y]es ").reversed()).centered().render(chunks[0], buf); Paragraph::new(Span::raw(&THEME.confirm.button_yes).style(THEME.confirm.buttons))
Paragraph::new(Span::raw(" (N)o ")).centered().render(chunks[1], buf); .centered()
.render(chunks[0], buf);
Paragraph::new(Span::raw(&THEME.confirm.button_no).style(THEME.confirm.buttons))
.centered()
.render(chunks[1], buf);
} }
} }

View file

@ -1,4 +1,11 @@
use ratatui::{buffer::Buffer, layout::{Alignment, Constraint, Layout, Margin, Rect}, style::{Style, Stylize}, text::Line, widgets::{Block, BorderType, Widget}}; use ratatui::{
buffer::Buffer,
layout::{Alignment, Constraint, Layout, Margin, Rect},
text::Line,
widgets::{Block, BorderType, Widget},
};
use yazi_config::THEME;
use crate::Ctx; use crate::Ctx;
@ -7,7 +14,9 @@ pub(crate) struct Confirm<'a> {
} }
impl<'a> Confirm<'a> { impl<'a> Confirm<'a> {
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } } pub(crate) fn new(cx: &'a Ctx) -> Self {
Self { cx }
}
} }
impl<'a> Widget for Confirm<'a> { impl<'a> Widget for Confirm<'a> {
@ -19,16 +28,20 @@ impl<'a> Widget for Confirm<'a> {
Block::bordered() Block::bordered()
.border_type(BorderType::Rounded) .border_type(BorderType::Rounded)
.border_style(Style::new().blue()) .border_style(THEME.confirm.border)
.title(Line::styled(&confirm.title, Style::new().blue())) .title(Line::styled(&confirm.title, THEME.confirm.title))
.title_alignment(Alignment::Center) .title_alignment(Alignment::Center)
.render(area, buf); .render(area, buf);
let content = confirm.content.clone(); let content = confirm.content.clone();
let content_height = content.line_count(area.width).saturating_add(1) as u16; let mut content_height = content.line_count(area.width) as u16;
if THEME.confirm.show_separators && content_height > 0 {
content_height = content_height.saturating_add(1);
}
let chunks = Layout::vertical([ let chunks = Layout::vertical([
Constraint::Length(if content_height == 1 { 0 } else { content_height }), Constraint::Length(content_height),
Constraint::Fill(1), Constraint::Fill(1),
Constraint::Length(1), Constraint::Length(1),
]) ])

View file

@ -1,11 +1,19 @@
use ratatui::{buffer::Buffer, layout::{Margin, Rect}, style::{Style, Stylize}, widgets::{Block, Borders, Paragraph, Widget}}; use ratatui::{
buffer::Buffer,
layout::{Margin, Rect},
widgets::{Block, Borders, Paragraph, Widget},
};
use yazi_config::THEME;
pub(crate) struct Content<'a> { pub(crate) struct Content<'a> {
p: Paragraph<'a>, p: Paragraph<'a>,
} }
impl<'a> Content<'a> { impl<'a> Content<'a> {
pub(crate) fn new(p: Paragraph<'a>) -> Self { Self { p } } pub(crate) fn new(p: Paragraph<'a>) -> Self {
Self { p }
}
} }
impl<'a> Widget for Content<'a> { impl<'a> Widget for Content<'a> {
@ -14,9 +22,17 @@ impl<'a> Widget for Content<'a> {
let inner = area.inner(Margin::new(1, 0)); let inner = area.inner(Margin::new(1, 0));
// Bottom border // Bottom border
let block = Block::new().borders(Borders::BOTTOM).border_style(Style::new().blue()); let mut block = Block::new();
if THEME.confirm.show_separators {
block = block.borders(Borders::BOTTOM).border_style(THEME.confirm.border);
}
block.clone().render(area.inner(Margin::new(1, 0)), buf); block.clone().render(area.inner(Margin::new(1, 0)), buf);
self.p.alignment(ratatui::layout::Alignment::Center).block(block).render(inner, buf); self
.p
.alignment(ratatui::layout::Alignment::Center)
.block(block)
.style(THEME.confirm.content)
.render(inner, buf);
} }
} }

View file

@ -1,4 +1,12 @@
use ratatui::{buffer::Buffer, layout::{Margin, Rect}, style::{Style, Stylize}, widgets::{Block, Borders, Scrollbar, ScrollbarOrientation, ScrollbarState, StatefulWidget, Widget, Wrap}}; use ratatui::{
buffer::Buffer,
layout::{Margin, Rect},
widgets::{
Block, Borders, Scrollbar, ScrollbarOrientation, ScrollbarState, StatefulWidget, Widget, Wrap,
},
};
use yazi_config::THEME;
use crate::Ctx; use crate::Ctx;
@ -7,7 +15,9 @@ pub(crate) struct List<'a> {
} }
impl<'a> List<'a> { impl<'a> List<'a> {
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } } pub(crate) fn new(cx: &'a Ctx) -> Self {
Self { cx }
}
} }
impl<'a> Widget for List<'a> { impl<'a> Widget for List<'a> {
@ -16,7 +26,10 @@ impl<'a> Widget for List<'a> {
let inner = area.inner(Margin::new(2, 0)); let inner = area.inner(Margin::new(2, 0));
// Bottom border // Bottom border
let block = Block::new().borders(Borders::BOTTOM).border_style(Style::new().blue()); let mut block = Block::new();
if THEME.confirm.show_separators {
block = block.borders(Borders::BOTTOM).border_style(THEME.confirm.border);
}
block.clone().render(area.inner(Margin::new(1, 0)), buf); block.clone().render(area.inner(Margin::new(1, 0)), buf);
let list = self let list = self
@ -26,17 +39,22 @@ impl<'a> Widget for List<'a> {
.clone() .clone()
.scroll((self.cx.confirm.offset as u16, 0)) .scroll((self.cx.confirm.offset as u16, 0))
.block(block) .block(block)
.style(THEME.confirm.list)
.wrap(Wrap { trim: false }); .wrap(Wrap { trim: false });
// Vertical scrollbar // Vertical scrollbar
let lines = list.line_count(inner.width); if THEME.confirm.show_scrollbar {
if lines >= inner.height as usize { let lines = list.line_count(inner.width);
area.height = area.height.saturating_sub(1); if lines >= inner.height as usize {
Scrollbar::new(ScrollbarOrientation::VerticalRight).render( if THEME.confirm.show_separators {
area, area.height = area.height.saturating_sub(1);
buf, }
&mut ScrollbarState::new(lines).position(self.cx.confirm.offset), Scrollbar::new(ScrollbarOrientation::VerticalRight).render(
); area,
buf,
&mut ScrollbarState::new(lines).position(self.cx.confirm.offset),
);
}
} }
list.render(inner, buf); list.render(inner, buf);