mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: confirm component customization
This commit is contained in:
parent
a6c9c93d58
commit
a7b0e56b67
6 changed files with 112 additions and 24 deletions
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue