mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-26 06:30:29 +00:00
fix(table)!: Add widths parameter to new() (#664)
This prevents creating a table that doesn't actually render anything. Fixes: https://github.com/ratatui-org/ratatui/issues/537 BREAKING CHANGE: Table::new() now takes an additional widths parameter.
This commit is contained in:
parent
91c67eb100
commit
37c70dbb8e
7 changed files with 306 additions and 226 deletions
|
@ -11,7 +11,8 @@ github with a [breaking change] label.
|
||||||
This is a quick summary of the sections below:
|
This is a quick summary of the sections below:
|
||||||
|
|
||||||
- Unreleased (0.24.1)
|
- Unreleased (0.24.1)
|
||||||
- `Table::widths()` now accepts `AsRef<[Constraint]>`
|
- `Table::new()` now requires specifying the widths
|
||||||
|
-`Table::widths()` now accepts `IntoIterator<Item = AsRef<Constraint>>`
|
||||||
- Layout::new() now accepts direction and constraint parameters
|
- Layout::new() now accepts direction and constraint parameters
|
||||||
- The default `Tabs::highlight_style` is now `Style::new().reversed()`
|
- The default `Tabs::highlight_style` is now `Style::new().reversed()`
|
||||||
|
|
||||||
|
@ -46,9 +47,39 @@ widget in the default configuration would not show any indication of the selecte
|
||||||
|
|
||||||
[#635]: https://github.com/ratatui-org/ratatui/pull/635
|
[#635]: https://github.com/ratatui-org/ratatui/pull/635
|
||||||
|
|
||||||
### `Table::widths()` now accepts `AsRef<[Constraint]>` ([#628])
|
### The default `Tabs::highlight_style` is now `Style::new().reversed()` ([#635])
|
||||||
|
|
||||||
[#628]: https://github.com/ratatui-org/ratatui/pull/628
|
Previously the default highlight style for tabs was `Style::default()`, which meant that a `Tabs`
|
||||||
|
widget in the default configuration would not show any indication of the selected tab.
|
||||||
|
|
||||||
|
|
||||||
|
### `Table::new()` now requires specifying the widths of the columrs (#664)
|
||||||
|
|
||||||
|
Previously `Table`s could be constructed without widths. In almost all cases this is an error.
|
||||||
|
A new widths parameter is now manadatory on `Table::new()`. Existing code of the form:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
Table::new(rows).widths(widths)
|
||||||
|
```
|
||||||
|
|
||||||
|
Should be updated to:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
Table::new(rows, widths)
|
||||||
|
```
|
||||||
|
|
||||||
|
For ease of automated replacement in cases where the amount of code broken by this change is large
|
||||||
|
or complex, it may be convenient to replace `Table::new` with `Table::default().rows`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
Table::new(rows).block(block).widths(widths);
|
||||||
|
// becomes
|
||||||
|
Table::default().rows(rows).widths(widths)
|
||||||
|
```
|
||||||
|
|
||||||
|
### `Table::widths()` now accepts `IntoIterator<Item = AsRef<Constraint>>` ([#663])
|
||||||
|
|
||||||
|
[#663]: https://github.com/ratatui-org/ratatui/pull/663
|
||||||
|
|
||||||
Previously `Table::widths()` took a slice (`&'a [Constraint]`). This change will introduce clippy
|
Previously `Table::widths()` took a slice (`&'a [Constraint]`). This change will introduce clippy
|
||||||
`needless_borrow` warnings for places where slices are passed to this method. To fix these, remove
|
`needless_borrow` warnings for places where slices are passed to this method. To fix these, remove
|
||||||
|
|
|
@ -289,18 +289,20 @@ fn draw_second_tab(f: &mut Frame, app: &mut App, area: Rect) {
|
||||||
};
|
};
|
||||||
Row::new(vec![s.name, s.location, s.status]).style(style)
|
Row::new(vec![s.name, s.location, s.status]).style(style)
|
||||||
});
|
});
|
||||||
let table = Table::new(rows)
|
let table = Table::new(
|
||||||
|
rows,
|
||||||
|
[
|
||||||
|
Constraint::Length(15),
|
||||||
|
Constraint::Length(15),
|
||||||
|
Constraint::Length(10),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(
|
.header(
|
||||||
Row::new(vec!["Server", "Location", "Status"])
|
Row::new(vec!["Server", "Location", "Status"])
|
||||||
.style(Style::default().fg(Color::Yellow))
|
.style(Style::default().fg(Color::Yellow))
|
||||||
.bottom_margin(1),
|
.bottom_margin(1),
|
||||||
)
|
)
|
||||||
.block(Block::default().title("Servers").borders(Borders::ALL))
|
.block(Block::default().title("Servers").borders(Borders::ALL));
|
||||||
.widths([
|
|
||||||
Constraint::Length(15),
|
|
||||||
Constraint::Length(15),
|
|
||||||
Constraint::Length(10),
|
|
||||||
]);
|
|
||||||
f.render_widget(table, chunks[0]);
|
f.render_widget(table, chunks[0]);
|
||||||
|
|
||||||
let map = Canvas::default()
|
let map = Canvas::default()
|
||||||
|
@ -393,12 +395,14 @@ fn draw_third_tab(f: &mut Frame, _app: &mut App, area: Rect) {
|
||||||
Row::new(cells)
|
Row::new(cells)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let table = Table::new(items)
|
let table = Table::new(
|
||||||
.block(Block::default().title("Colors").borders(Borders::ALL))
|
items,
|
||||||
.widths([
|
[
|
||||||
Constraint::Ratio(1, 3),
|
Constraint::Ratio(1, 3),
|
||||||
Constraint::Ratio(1, 3),
|
Constraint::Ratio(1, 3),
|
||||||
Constraint::Ratio(1, 3),
|
Constraint::Ratio(1, 3),
|
||||||
]);
|
],
|
||||||
|
)
|
||||||
|
.block(Block::default().title("Colors").borders(Borders::ALL));
|
||||||
f.render_widget(table, chunks[0]);
|
f.render_widget(table, chunks[0]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,10 +146,9 @@ fn render_ingredients(selected_row: usize, area: Rect, buf: &mut Buffer) {
|
||||||
let rows = INGREDIENTS.iter().map(|&i| i.into()).collect_vec();
|
let rows = INGREDIENTS.iter().map(|&i| i.into()).collect_vec();
|
||||||
let theme = THEME.recipe;
|
let theme = THEME.recipe;
|
||||||
StatefulWidget::render(
|
StatefulWidget::render(
|
||||||
Table::new(rows)
|
Table::new(rows, [Constraint::Length(7), Constraint::Length(30)])
|
||||||
.block(Block::new().style(theme.ingredients))
|
.block(Block::new().style(theme.ingredients))
|
||||||
.header(Row::new(vec!["Qty", "Ingredient"]).style(theme.ingredients_header))
|
.header(Row::new(vec!["Qty", "Ingredient"]).style(theme.ingredients_header))
|
||||||
.widths([Constraint::Length(7), Constraint::Length(30)])
|
|
||||||
.highlight_style(Style::new().light_yellow()),
|
.highlight_style(Style::new().light_yellow()),
|
||||||
area,
|
area,
|
||||||
buf,
|
buf,
|
||||||
|
|
|
@ -50,9 +50,8 @@ fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
|
||||||
.title_alignment(Alignment::Center)
|
.title_alignment(Alignment::Center)
|
||||||
.padding(Padding::new(1, 1, 1, 1));
|
.padding(Padding::new(1, 1, 1, 1));
|
||||||
StatefulWidget::render(
|
StatefulWidget::render(
|
||||||
Table::new(rows)
|
Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
|
||||||
.header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
|
.header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
|
||||||
.widths([Constraint::Max(100), Constraint::Length(15)])
|
|
||||||
.highlight_style(THEME.traceroute.selected)
|
.highlight_style(THEME.traceroute.selected)
|
||||||
.block(block),
|
.block(block),
|
||||||
area,
|
area,
|
||||||
|
|
|
@ -137,15 +137,17 @@ fn ui(f: &mut Frame, app: &mut App) {
|
||||||
let cells = item.iter().map(|c| Cell::from(*c));
|
let cells = item.iter().map(|c| Cell::from(*c));
|
||||||
Row::new(cells).height(height as u16).bottom_margin(1)
|
Row::new(cells).height(height as u16).bottom_margin(1)
|
||||||
});
|
});
|
||||||
let t = Table::new(rows)
|
let t = Table::new(
|
||||||
.header(header)
|
rows,
|
||||||
.block(Block::default().borders(Borders::ALL).title("Table"))
|
[
|
||||||
.highlight_style(selected_style)
|
|
||||||
.highlight_symbol(">> ")
|
|
||||||
.widths([
|
|
||||||
Constraint::Percentage(50),
|
Constraint::Percentage(50),
|
||||||
Constraint::Max(30),
|
Constraint::Max(30),
|
||||||
Constraint::Min(10),
|
Constraint::Min(10),
|
||||||
]);
|
],
|
||||||
|
)
|
||||||
|
.header(header)
|
||||||
|
.block(Block::default().borders(Borders::ALL).title("Table"))
|
||||||
|
.highlight_style(selected_style)
|
||||||
|
.highlight_symbol(">> ");
|
||||||
f.render_stateful_widget(t, rects[0], &mut app.state);
|
f.render_stateful_widget(t, rects[0], &mut app.state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,8 @@ impl HighlightSpacing {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use ratatui::{prelude::*, widgets::*};
|
/// use ratatui::{prelude::*, widgets::*};
|
||||||
///
|
///
|
||||||
/// Table::new(vec![
|
/// Table::new(
|
||||||
|
/// vec![
|
||||||
/// // Row can be created from simple strings.
|
/// // Row can be created from simple strings.
|
||||||
/// Row::new(vec!["Row11", "Row12", "Row13"]),
|
/// Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
/// // You can style the entire row.
|
/// // You can style the entire row.
|
||||||
|
@ -225,7 +226,11 @@ impl HighlightSpacing {
|
||||||
/// Cell::from("Row\n42"),
|
/// Cell::from("Row\n42"),
|
||||||
/// Cell::from("Row\n43"),
|
/// Cell::from("Row\n43"),
|
||||||
/// ]).height(2),
|
/// ]).height(2),
|
||||||
/// ])
|
/// ],
|
||||||
|
/// // Columns widths are constrained in the same way as Layout...
|
||||||
|
/// [Constraint::Length(5), Constraint::Length(5), Constraint::Length(10)])
|
||||||
|
/// // ...and they can be separated by a fixed spacing.
|
||||||
|
/// .column_spacing(1)
|
||||||
/// // You can set the style of the entire Table.
|
/// // You can set the style of the entire Table.
|
||||||
/// .style(Style::default().fg(Color::White))
|
/// .style(Style::default().fg(Color::White))
|
||||||
/// // It has an optional header, which is simply a Row always visible at the top.
|
/// // It has an optional header, which is simply a Row always visible at the top.
|
||||||
|
@ -238,10 +243,6 @@ impl HighlightSpacing {
|
||||||
/// )
|
/// )
|
||||||
/// // As any other widget, a Table can be wrapped in a Block.
|
/// // As any other widget, a Table can be wrapped in a Block.
|
||||||
/// .block(Block::default().title("Table"))
|
/// .block(Block::default().title("Table"))
|
||||||
/// // Columns widths are constrained in the same way as Layout...
|
|
||||||
/// .widths(&[Constraint::Length(5), Constraint::Length(5), Constraint::Length(10)])
|
|
||||||
/// // ...and they can be separated by a fixed spacing.
|
|
||||||
/// .column_spacing(1)
|
|
||||||
/// // If you wish to highlight a row in any specific way when it is selected...
|
/// // If you wish to highlight a row in any specific way when it is selected...
|
||||||
/// .highlight_style(Style::default().add_modifier(Modifier::BOLD))
|
/// .highlight_style(Style::default().add_modifier(Modifier::BOLD))
|
||||||
/// // ...and potentially show a symbol in front of the selection.
|
/// // ...and potentially show a symbol in front of the selection.
|
||||||
|
@ -275,13 +276,17 @@ impl<'a> Table<'a> {
|
||||||
/// Creates a new [`Table`] widget with the given rows.
|
/// Creates a new [`Table`] widget with the given rows.
|
||||||
///
|
///
|
||||||
/// The `rows` parameter is a Vector of [`Row`], this holds the data to be displayed by the
|
/// The `rows` parameter is a Vector of [`Row`], this holds the data to be displayed by the
|
||||||
/// table
|
/// table.
|
||||||
|
///
|
||||||
|
/// The `widths` parameter is an array (or any other type that implements IntoIterator) of
|
||||||
|
/// [`Constraint`]s, this holds the widths of each column. This parameter was added in 0.25.0.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use ratatui::{prelude::*, widgets::*};
|
/// # use ratatui::{prelude::*, widgets::*};
|
||||||
/// let table = Table::new(vec![
|
/// let table = Table::new(
|
||||||
|
/// vec![
|
||||||
/// Row::new(vec![
|
/// Row::new(vec![
|
||||||
/// Cell::from("Cell1"),
|
/// Cell::from("Cell1"),
|
||||||
/// Cell::from("Cell2")
|
/// Cell::from("Cell2")
|
||||||
|
@ -290,16 +295,22 @@ impl<'a> Table<'a> {
|
||||||
/// Cell::from("Cell3"),
|
/// Cell::from("Cell3"),
|
||||||
/// Cell::from("Cell4")
|
/// Cell::from("Cell4")
|
||||||
/// ]),
|
/// ]),
|
||||||
/// ]);
|
/// ],
|
||||||
|
/// [Constraint::Length(5), Constraint::Length(5)]
|
||||||
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new<T>(rows: T) -> Self
|
pub fn new<R, C>(rows: R, widths: C) -> Self
|
||||||
where
|
where
|
||||||
T: IntoIterator<Item = Row<'a>>,
|
R: IntoIterator<Item = Row<'a>>,
|
||||||
|
C: IntoIterator,
|
||||||
|
C::Item: AsRef<Constraint>,
|
||||||
{
|
{
|
||||||
|
let widths = widths.into_iter().map(|c| *c.as_ref()).collect_vec();
|
||||||
|
ensure_percentages_less_than_100(&widths);
|
||||||
Self {
|
Self {
|
||||||
block: None,
|
block: None,
|
||||||
style: Style::default(),
|
style: Style::default(),
|
||||||
widths: vec![],
|
widths,
|
||||||
column_spacing: 1,
|
column_spacing: 1,
|
||||||
highlight_style: Style::default(),
|
highlight_style: Style::default(),
|
||||||
highlight_symbol: None,
|
highlight_symbol: None,
|
||||||
|
@ -319,7 +330,8 @@ impl<'a> Table<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use ratatui::{prelude::*, widgets::*};
|
/// # use ratatui::{prelude::*, widgets::*};
|
||||||
/// let table = Table::new(vec![
|
/// let table = Table::new(
|
||||||
|
/// vec![
|
||||||
/// Row::new(vec![
|
/// Row::new(vec![
|
||||||
/// Cell::from("Cell1"),
|
/// Cell::from("Cell1"),
|
||||||
/// Cell::from("Cell2")
|
/// Cell::from("Cell2")
|
||||||
|
@ -328,7 +340,10 @@ impl<'a> Table<'a> {
|
||||||
/// Cell::from("Cell3"),
|
/// Cell::from("Cell3"),
|
||||||
/// Cell::from("Cell4")
|
/// Cell::from("Cell4")
|
||||||
/// ]),
|
/// ]),
|
||||||
/// ]).block(Block::default().title("Table"));
|
/// ],
|
||||||
|
/// [Constraint::Length(5), Constraint::Length(5)]
|
||||||
|
/// )
|
||||||
|
/// .block(Block::default().title("Table"));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn block(mut self, block: Block<'a>) -> Self {
|
pub fn block(mut self, block: Block<'a>) -> Self {
|
||||||
self.block = Some(block);
|
self.block = Some(block);
|
||||||
|
@ -344,12 +359,13 @@ impl<'a> Table<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use ratatui::{prelude::*, widgets::*};
|
/// # use ratatui::{prelude::*, widgets::*};
|
||||||
/// let table = Table::new(vec![
|
/// let table = Table::new(
|
||||||
/// Row::new(vec![
|
/// vec![
|
||||||
/// Cell::from("Cell1"),
|
/// Row::new(vec![Cell::from("Cell1"), Cell::from("Cell2")])
|
||||||
/// Cell::from("Cell2")
|
/// ],
|
||||||
/// ])
|
/// [Constraint::Length(20), Constraint::Length(20)]
|
||||||
/// ]).header(
|
/// )
|
||||||
|
/// .header(
|
||||||
/// Row::new(vec![
|
/// Row::new(vec![
|
||||||
/// Cell::from("Header Cell 1"),
|
/// Cell::from("Header Cell 1"),
|
||||||
/// Cell::from("Header Cell 2")
|
/// Cell::from("Header Cell 2")
|
||||||
|
@ -370,13 +386,13 @@ impl<'a> Table<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use ratatui::{prelude::*, widgets::*};
|
/// # use ratatui::{prelude::*, widgets::*};
|
||||||
/// let table = Table::new(vec![]).widths([Constraint::Length(5), Constraint::Length(5)]);
|
/// let table = Table::default().widths([Constraint::Length(5), Constraint::Length(5)]);
|
||||||
/// let table = Table::new(vec![]).widths(&[Constraint::Length(5), Constraint::Length(5)]);
|
/// let table = Table::default().widths(&[Constraint::Length(5), Constraint::Length(5)]);
|
||||||
///
|
///
|
||||||
/// // widths could also be computed at runtime
|
/// // widths could also be computed at runtime
|
||||||
/// let widths = vec![Constraint::Length(5), Constraint::Length(5)];
|
/// let widths = vec![Constraint::Length(5), Constraint::Length(5)];
|
||||||
/// let table = Table::new(vec![]).widths(widths.clone());
|
/// let table = Table::default().widths(widths.clone());
|
||||||
/// let table = Table::new(vec![]).widths(&widths);
|
/// let table = Table::default().widths(&widths);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn widths<I, C>(mut self, widths: I) -> Self
|
pub fn widths<I, C>(mut self, widths: I) -> Self
|
||||||
where
|
where
|
||||||
|
@ -384,14 +400,7 @@ impl<'a> Table<'a> {
|
||||||
C: AsRef<Constraint>,
|
C: AsRef<Constraint>,
|
||||||
{
|
{
|
||||||
let widths = widths.into_iter().map(|c| *c.as_ref()).collect_vec();
|
let widths = widths.into_iter().map(|c| *c.as_ref()).collect_vec();
|
||||||
let between_0_and_100 = |&w| match w {
|
ensure_percentages_less_than_100(&widths);
|
||||||
Constraint::Percentage(p) => p <= 100,
|
|
||||||
_ => true,
|
|
||||||
};
|
|
||||||
assert!(
|
|
||||||
widths.iter().all(between_0_and_100),
|
|
||||||
"Percentages should be between 0 and 100 inclusively."
|
|
||||||
);
|
|
||||||
self.widths = widths;
|
self.widths = widths;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -491,6 +500,7 @@ impl<'a> Table<'a> {
|
||||||
/// space to the last column or to distribute it equally.
|
/// space to the last column or to distribute it equally.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
///
|
||||||
/// Create a table that needs at least 30 columns to display. Any extra space will be assigned
|
/// Create a table that needs at least 30 columns to display. Any extra space will be assigned
|
||||||
/// to the last column.
|
/// to the last column.
|
||||||
#[cfg_attr(feature = "unstable", doc = " ```")]
|
#[cfg_attr(feature = "unstable", doc = " ```")]
|
||||||
|
@ -499,8 +509,7 @@ impl<'a> Table<'a> {
|
||||||
/// # use ratatui::layout::SegmentSize;
|
/// # use ratatui::layout::SegmentSize;
|
||||||
/// # use ratatui::widgets::Table;
|
/// # use ratatui::widgets::Table;
|
||||||
/// let widths = [Constraint::Min(10), Constraint::Min(10), Constraint::Min(10)];
|
/// let widths = [Constraint::Min(10), Constraint::Min(10), Constraint::Min(10)];
|
||||||
/// let table = Table::new([])
|
/// let table = Table::new([], widths)
|
||||||
/// .widths(widths)
|
|
||||||
/// .segment_size(SegmentSize::LastTakesRemainder);
|
/// .segment_size(SegmentSize::LastTakesRemainder);
|
||||||
/// ```
|
/// ```
|
||||||
#[stability::unstable(
|
#[stability::unstable(
|
||||||
|
@ -514,6 +523,17 @@ impl<'a> Table<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ensure_percentages_less_than_100(widths: &[Constraint]) {
|
||||||
|
let between_0_and_100 = |&w| match w {
|
||||||
|
Constraint::Percentage(p) => p <= 100,
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
assert!(
|
||||||
|
widths.iter().all(between_0_and_100),
|
||||||
|
"Percentages should be between 0 and 100 inclusively."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Styled for Table<'a> {
|
impl<'a> Styled for Table<'a> {
|
||||||
type Item = Table<'a>;
|
type Item = Table<'a>;
|
||||||
|
|
||||||
|
@ -710,30 +730,30 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn table_invalid_percentages() {
|
fn table_invalid_percentages() {
|
||||||
Table::new(vec![]).widths([Constraint::Percentage(110)]);
|
Table::new(vec![], [Constraint::Percentage(110)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn widths_conversions() {
|
fn widths_conversions() {
|
||||||
let array = [Constraint::Percentage(100)];
|
let array = [Constraint::Percentage(100)];
|
||||||
let table = Table::new(vec![]).widths(array);
|
let table = Table::new(vec![], array);
|
||||||
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "array");
|
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "array");
|
||||||
|
|
||||||
let array_ref = &[Constraint::Percentage(100)];
|
let array_ref = &[Constraint::Percentage(100)];
|
||||||
let table = Table::new(vec![]).widths(array_ref);
|
let table = Table::new(vec![], array_ref);
|
||||||
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "array ref");
|
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "array ref");
|
||||||
|
|
||||||
let vec = vec![Constraint::Percentage(100)];
|
let vec = vec![Constraint::Percentage(100)];
|
||||||
let slice = vec.as_slice();
|
let slice = vec.as_slice();
|
||||||
let table = Table::new(vec![]).widths(slice);
|
let table = Table::new(vec![], slice);
|
||||||
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "slice");
|
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "slice");
|
||||||
|
|
||||||
let vec = vec![Constraint::Percentage(100)];
|
let vec = vec![Constraint::Percentage(100)];
|
||||||
let table = Table::new(vec![]).widths(vec);
|
let table = Table::new(vec![], vec);
|
||||||
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "vec");
|
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "vec");
|
||||||
|
|
||||||
let vec_ref = &vec![Constraint::Percentage(100)];
|
let vec_ref = &vec![Constraint::Percentage(100)];
|
||||||
let table = Table::new(vec![]).widths(vec_ref);
|
let table = Table::new(vec![], vec_ref);
|
||||||
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "vec ref");
|
assert_eq!(table.widths, vec![Constraint::Percentage(100)], "vec ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,9 +771,7 @@ mod tests {
|
||||||
selection_width: u16,
|
selection_width: u16,
|
||||||
expected: &[(u16, u16)],
|
expected: &[(u16, u16)],
|
||||||
) {
|
) {
|
||||||
let table = Table::new(vec![])
|
let table = Table::new(vec![], constraints).segment_size(segment_size);
|
||||||
.segment_size(segment_size)
|
|
||||||
.widths(constraints);
|
|
||||||
|
|
||||||
let widths = table.get_columns_widths(available_width, selection_width);
|
let widths = table.get_columns_widths(available_width, selection_width);
|
||||||
assert_eq!(widths, expected);
|
assert_eq!(widths, expected);
|
||||||
|
@ -997,12 +1015,14 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_render_table_with_alignment() {
|
fn test_render_table_with_alignment() {
|
||||||
let mut buf = Buffer::empty(Rect::new(0, 0, 20, 3));
|
let mut buf = Buffer::empty(Rect::new(0, 0, 20, 3));
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec![Line::from("Left").alignment(Alignment::Left)]),
|
Row::new(vec![Line::from("Left").alignment(Alignment::Left)]),
|
||||||
Row::new(vec![Line::from("Center").alignment(Alignment::Center)]),
|
Row::new(vec![Line::from("Center").alignment(Alignment::Center)]),
|
||||||
Row::new(vec![Line::from("Right").alignment(Alignment::Right)]),
|
Row::new(vec![Line::from("Right").alignment(Alignment::Right)]),
|
||||||
])
|
],
|
||||||
.widths([Percentage(100)]);
|
[Percentage(100)],
|
||||||
|
);
|
||||||
|
|
||||||
Widget::render(table, Rect::new(0, 0, 20, 3), &mut buf);
|
Widget::render(table, Rect::new(0, 0, 20, 3), &mut buf);
|
||||||
|
|
||||||
|
@ -1047,7 +1067,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn table_can_be_stylized() {
|
fn table_can_be_stylized() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Table::new(vec![Row::new(vec![Cell::from("")])])
|
Table::new(vec![Row::new(vec![Cell::from("")])], [Percentage(100)])
|
||||||
.black()
|
.black()
|
||||||
.on_white()
|
.on_white()
|
||||||
.bold()
|
.bold()
|
||||||
|
|
|
@ -19,19 +19,21 @@ fn widgets_table_column_spacing_can_be_changed() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]),
|
Row::new(vec!["Row21", "Row22", "Row23"]),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]),
|
Row::new(vec!["Row41", "Row42", "Row43"]),
|
||||||
])
|
],
|
||||||
|
[
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL))
|
||||||
.widths([
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
])
|
|
||||||
.column_spacing(column_spacing);
|
.column_spacing(column_spacing);
|
||||||
f.render_widget(table, size);
|
f.render_widget(table, size);
|
||||||
})
|
})
|
||||||
|
@ -117,15 +119,17 @@ fn widgets_table_columns_widths_can_use_fixed_length_constraints() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]),
|
Row::new(vec!["Row21", "Row22", "Row23"]),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]),
|
Row::new(vec!["Row41", "Row42", "Row43"]),
|
||||||
])
|
],
|
||||||
|
widths,
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL));
|
||||||
.widths(widths);
|
|
||||||
f.render_widget(table, size);
|
f.render_widget(table, size);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -206,15 +210,17 @@ fn widgets_table_columns_widths_can_use_percentage_constraints() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]),
|
Row::new(vec!["Row21", "Row22", "Row23"]),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]),
|
Row::new(vec!["Row41", "Row42", "Row43"]),
|
||||||
])
|
],
|
||||||
|
widths,
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL))
|
||||||
.widths(widths)
|
|
||||||
.column_spacing(0);
|
.column_spacing(0);
|
||||||
f.render_widget(table, size);
|
f.render_widget(table, size);
|
||||||
})
|
})
|
||||||
|
@ -313,15 +319,17 @@ fn widgets_table_columns_widths_can_use_mixed_constraints() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]),
|
Row::new(vec!["Row21", "Row22", "Row23"]),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]),
|
Row::new(vec!["Row41", "Row42", "Row43"]),
|
||||||
])
|
],
|
||||||
|
widths,
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL));
|
||||||
.widths(widths);
|
|
||||||
f.render_widget(table, size);
|
f.render_widget(table, size);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -423,15 +431,17 @@ fn widgets_table_columns_widths_can_use_ratio_constraints() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]),
|
Row::new(vec!["Row21", "Row22", "Row23"]),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]),
|
Row::new(vec!["Row41", "Row42", "Row43"]),
|
||||||
])
|
],
|
||||||
|
widths,
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL))
|
||||||
.widths(widths)
|
|
||||||
.column_spacing(0);
|
.column_spacing(0);
|
||||||
f.render_widget(table, size);
|
f.render_widget(table, size);
|
||||||
})
|
})
|
||||||
|
@ -528,20 +538,22 @@ fn widgets_table_can_have_rows_with_multi_lines() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]).height(2),
|
Row::new(vec!["Row21", "Row22", "Row23"]).height(2),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]).height(2),
|
Row::new(vec!["Row41", "Row42", "Row43"]).height(2),
|
||||||
])
|
],
|
||||||
|
[
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL))
|
||||||
.highlight_symbol(">> ")
|
.highlight_symbol(">> ")
|
||||||
.widths([
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
])
|
|
||||||
.column_spacing(1);
|
.column_spacing(1);
|
||||||
f.render_stateful_widget(table, size, state);
|
f.render_stateful_widget(table, size, state);
|
||||||
})
|
})
|
||||||
|
@ -622,21 +634,23 @@ fn widgets_table_enable_always_highlight_spacing() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]).height(2),
|
Row::new(vec!["Row21", "Row22", "Row23"]).height(2),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]).height(2),
|
Row::new(vec!["Row41", "Row42", "Row43"]).height(2),
|
||||||
])
|
],
|
||||||
|
[
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL))
|
||||||
.highlight_symbol(">> ")
|
.highlight_symbol(">> ")
|
||||||
.highlight_spacing(space)
|
.highlight_spacing(space)
|
||||||
.widths([
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
])
|
|
||||||
.column_spacing(1);
|
.column_spacing(1);
|
||||||
f.render_stateful_widget(table, size, state);
|
f.render_stateful_widget(table, size, state);
|
||||||
})
|
})
|
||||||
|
@ -756,8 +770,10 @@ fn widgets_table_can_have_elements_styled_individually() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]).style(Style::default().fg(Color::Green)),
|
vec![
|
||||||
|
Row::new(vec!["Row11", "Row12", "Row13"])
|
||||||
|
.style(Style::default().fg(Color::Green)),
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
Cell::from("Row21"),
|
Cell::from("Row21"),
|
||||||
Cell::from("Row22").style(Style::default().fg(Color::Yellow)),
|
Cell::from("Row22").style(Style::default().fg(Color::Yellow)),
|
||||||
|
@ -768,16 +784,17 @@ fn widgets_table_can_have_elements_styled_individually() {
|
||||||
.style(Style::default().fg(Color::Red)),
|
.style(Style::default().fg(Color::Red)),
|
||||||
])
|
])
|
||||||
.style(Style::default().fg(Color::LightGreen)),
|
.style(Style::default().fg(Color::LightGreen)),
|
||||||
])
|
],
|
||||||
|
[
|
||||||
|
Constraint::Length(6),
|
||||||
|
Constraint::Length(6),
|
||||||
|
Constraint::Length(6),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::LEFT | Borders::RIGHT))
|
.block(Block::default().borders(Borders::LEFT | Borders::RIGHT))
|
||||||
.highlight_symbol(">> ")
|
.highlight_symbol(">> ")
|
||||||
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
|
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
|
||||||
.widths([
|
|
||||||
Constraint::Length(6),
|
|
||||||
Constraint::Length(6),
|
|
||||||
Constraint::Length(6),
|
|
||||||
])
|
|
||||||
.column_spacing(1);
|
.column_spacing(1);
|
||||||
f.render_stateful_widget(table, size, &mut state);
|
f.render_stateful_widget(table, size, &mut state);
|
||||||
})
|
})
|
||||||
|
@ -831,14 +848,16 @@ fn widgets_table_should_render_even_if_empty() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![])
|
let table = Table::new(
|
||||||
|
vec![],
|
||||||
|
[
|
||||||
|
Constraint::Length(6),
|
||||||
|
Constraint::Length(6),
|
||||||
|
Constraint::Length(6),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]))
|
||||||
.block(Block::default().borders(Borders::LEFT | Borders::RIGHT))
|
.block(Block::default().borders(Borders::LEFT | Borders::RIGHT))
|
||||||
.widths([
|
|
||||||
Constraint::Length(6),
|
|
||||||
Constraint::Length(6),
|
|
||||||
Constraint::Length(6),
|
|
||||||
])
|
|
||||||
.column_spacing(1);
|
.column_spacing(1);
|
||||||
f.render_widget(table, size);
|
f.render_widget(table, size);
|
||||||
})
|
})
|
||||||
|
@ -869,17 +888,19 @@ fn widgets_table_columns_dont_panic() {
|
||||||
|
|
||||||
// based on https://github.com/fdehau/tui-rs/issues/470#issuecomment-852562848
|
// based on https://github.com/fdehau/tui-rs/issues/470#issuecomment-852562848
|
||||||
let table1_width = 98;
|
let table1_width = 98;
|
||||||
let table1 = Table::new(vec![Row::new(vec!["r1", "r2", "r3", "r4"])])
|
let table1 = Table::new(
|
||||||
.header(Row::new(vec!["h1", "h2", "h3", "h4"]))
|
vec![Row::new(vec!["r1", "r2", "r3", "r4"])],
|
||||||
.block(Block::default().borders(Borders::ALL))
|
[
|
||||||
.highlight_symbol(">> ")
|
|
||||||
.column_spacing(1)
|
|
||||||
.widths([
|
|
||||||
Constraint::Percentage(15),
|
Constraint::Percentage(15),
|
||||||
Constraint::Percentage(15),
|
Constraint::Percentage(15),
|
||||||
Constraint::Percentage(25),
|
Constraint::Percentage(25),
|
||||||
Constraint::Percentage(45),
|
Constraint::Percentage(45),
|
||||||
]);
|
],
|
||||||
|
)
|
||||||
|
.header(Row::new(vec!["h1", "h2", "h3", "h4"]))
|
||||||
|
.block(Block::default().borders(Borders::ALL))
|
||||||
|
.highlight_symbol(">> ")
|
||||||
|
.column_spacing(1);
|
||||||
|
|
||||||
let mut state = TableState::default();
|
let mut state = TableState::default();
|
||||||
|
|
||||||
|
@ -899,21 +920,23 @@ fn widgets_table_should_clamp_offset_if_rows_are_removed() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![
|
let table = Table::new(
|
||||||
|
vec![
|
||||||
Row::new(vec!["Row01", "Row02", "Row03"]),
|
Row::new(vec!["Row01", "Row02", "Row03"]),
|
||||||
Row::new(vec!["Row11", "Row12", "Row13"]),
|
Row::new(vec!["Row11", "Row12", "Row13"]),
|
||||||
Row::new(vec!["Row21", "Row22", "Row23"]),
|
Row::new(vec!["Row21", "Row22", "Row23"]),
|
||||||
Row::new(vec!["Row31", "Row32", "Row33"]),
|
Row::new(vec!["Row31", "Row32", "Row33"]),
|
||||||
Row::new(vec!["Row41", "Row42", "Row43"]),
|
Row::new(vec!["Row41", "Row42", "Row43"]),
|
||||||
Row::new(vec!["Row51", "Row52", "Row53"]),
|
Row::new(vec!["Row51", "Row52", "Row53"]),
|
||||||
])
|
],
|
||||||
|
[
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL))
|
||||||
.widths([
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
])
|
|
||||||
.column_spacing(1);
|
.column_spacing(1);
|
||||||
f.render_stateful_widget(table, size, &mut state);
|
f.render_stateful_widget(table, size, &mut state);
|
||||||
})
|
})
|
||||||
|
@ -935,14 +958,16 @@ fn widgets_table_should_clamp_offset_if_rows_are_removed() {
|
||||||
terminal
|
terminal
|
||||||
.draw(|f| {
|
.draw(|f| {
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let table = Table::new(vec![Row::new(vec!["Row31", "Row32", "Row33"])])
|
let table = Table::new(
|
||||||
|
vec![Row::new(vec!["Row31", "Row32", "Row33"])],
|
||||||
|
[
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
Constraint::Length(5),
|
||||||
|
],
|
||||||
|
)
|
||||||
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
.header(Row::new(vec!["Head1", "Head2", "Head3"]).bottom_margin(1))
|
||||||
.block(Block::default().borders(Borders::ALL))
|
.block(Block::default().borders(Borders::ALL))
|
||||||
.widths([
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
Constraint::Length(5),
|
|
||||||
])
|
|
||||||
.column_spacing(1);
|
.column_spacing(1);
|
||||||
f.render_stateful_widget(table, size, &mut state);
|
f.render_stateful_widget(table, size, &mut state);
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue