Skip to main content

ratatui_kit/components/adapter/
widget.rs

1use crate::{Component, Props};
2use ratatui::widgets::Widget;
3
4pub struct WidgetAdapterProps<T>
5where
6    T: 'static,
7{
8    pub inner: T,
9}
10
11impl<T: 'static> Props for WidgetAdapterProps<T> {}
12
13pub struct WidgetAdapter<T>
14where
15    T: 'static,
16{
17    inner: T,
18}
19
20impl<T> Component for WidgetAdapter<T>
21where
22    // 约束改为**按值** `Widget`(而非旧的 `for<'a> &'a T: Widget`)。这是一笔**双向取舍**,非纯扩展:
23    // - 纳入:0.30 起内置 widget 多同时实现按值与按引用 `Widget`,但不少第三方/纯按值 widget
24    //   (如 `tui-big-text` 的 `BigText`)只实现按值 `Widget`,旧约束会把它们挡在 `widget(...)` 之外。
25    // - 失去:**只实现按引用 `impl Widget for &T` 的 widget**(如 `ratatui-widgets` 的 `Shadow`——
26    //   亦 ratatui 官方为无状态 widget 推荐的写法)在新约束下不再被接纳;如需用可自行 wrap 成按值 widget。
27    // 组件已要求 `Clone`(new/update 从借用 props 拷入),draw 里再 clone 一次按值渲染,代价对 TUI 可忽略。
28    T: 'static + Unpin + Clone + Widget,
29{
30    type Props<'a> = WidgetAdapterProps<T>;
31
32    fn new(props: &Self::Props<'_>) -> Self {
33        Self {
34            inner: props.inner.clone(),
35        }
36    }
37
38    fn update(
39        &mut self,
40        props: &mut Self::Props<'_>,
41        _hooks: crate::Hooks,
42        _updater: &mut crate::ComponentUpdater,
43    ) {
44        self.inner = props.inner.clone();
45    }
46
47    fn draw(&mut self, drawer: &mut crate::ComponentDrawer<'_, '_>) {
48        // 按值渲染:克隆持久持有的 widget 交给消费式 `Widget::render`。
49        drawer.render_widget(self.inner.clone(), drawer.area);
50    }
51}