diff --git a/rich/panel.py b/rich/panel.py index 8fbaab0a..70d5e0dd 100644 --- a/rich/panel.py +++ b/rich/panel.py @@ -42,6 +42,8 @@ class Panel(JupyterMixin): *, title: Optional[TextType] = None, title_align: AlignMethod = "center", + footer: Optional[TextType] = None, + footer_align: AlignMethod = "center", safe_box: Optional[bool] = None, expand: bool = True, style: StyleType = "none", @@ -55,6 +57,8 @@ class Panel(JupyterMixin): self.box = box self.title = title self.title_align = title_align + self.footer = footer + self.footer_align = footer_align self.safe_box = safe_box self.expand = expand self.style = style @@ -72,6 +76,8 @@ class Panel(JupyterMixin): *, title: Optional[TextType] = None, title_align: AlignMethod = "center", + footer: Optional[TextType] = None, + footer_align: AlignMethod = "center", safe_box: Optional[bool] = None, style: StyleType = "none", border_style: StyleType = "none", @@ -84,6 +90,8 @@ class Panel(JupyterMixin): box, title=title, title_align=title_align, + footer=footer, + footer_align=footer, safe_box=safe_box, style=style, border_style=border_style, @@ -108,6 +116,22 @@ class Panel(JupyterMixin): return title_text return None + @property + def _footer(self) -> Optional[Text]: + if self.footer: + footer_text = ( + Text.from_markup(self.footer) + if isinstance(self.footer, str) + else self.footer.copy() + ) + footer_text.end = "" + footer_text.plain = footer_text.plain.replace("\n", " ") + footer_text.no_wrap = True + footer_text.expand_tabs() + footer_text.pad(1) + return footer_text + return None + def __rich_console__( self, console: "Console", options: "ConsoleOptions" ) -> "RenderResult": @@ -168,6 +192,19 @@ class Panel(JupyterMixin): yield from line yield line_end yield new_line + + footer_text = self._footer + if footer_text is not None: + footer_text.style = border_style + + if footer_text is None or width <= 4: + yield Segment(box.get_bottom([width - 2]), border_style) + else: + footer_text.align(self.footer_align, width - 4, character=box.bottom) + yield Segment(box.bottom_left + box.bottom, border_style) + yield from console.render(footer_text) + yield Segment(box.bottom + box.bottom_right, border_style) + yield Segment(box.get_bottom([width - 2]), border_style) yield new_line