返回 CodeWhale
transcript.rs
根目录 / vendor / codewhale-ratatui / src / gallery / transcript.rs
1 //! Authored transcript fixtures: prose with semantic spans, a quote, a list,
2 //! a table, fenced code and linked text. The host owns parsing and copying.
3
4 use std::borrow::Cow;
5
6 use ratatui::{
7 buffer::Buffer,
8 layout::Rect,
9 style::Modifier,
10 text::{Line, Span},
11 };
12
13 use super::Entry;
14 use crate::{CodeBlock, Paint, Theme, Transcript, TranscriptBlock, TranscriptSpan};
15
16 fn prose(area: Rect, buf: &mut Buffer, theme: &Theme) {
17 Transcript::new(vec![
18 TranscriptBlock::heading(1, "Release notes"),
19 TranscriptBlock::paragraph(vec![
20 TranscriptSpan::plain("The "),
21 TranscriptSpan::strong("workbar"),
22 TranscriptSpan::plain(" is summoned, and the "),
23 TranscriptSpan::emphasis("habitat"),
24 TranscriptSpan::plain(" stays quiet under "),
25 TranscriptSpan::code("MotionMode::Reduced"),
26 TranscriptSpan::plain("."),
27 ]),
28 TranscriptBlock::paragraph(vec![
29 TranscriptSpan::muted("Reported by the host. "),
30 TranscriptSpan::success("Receipts read."),
31 ]),
32 TranscriptBlock::quote_by("Ship the quiet version first.", "a review note"),
33 ])
34 .paint(area, buf, theme);
35 }
36
37 fn list_and_table(area: Rect, buf: &mut Buffer, theme: &Theme) {
38 Transcript::new(vec![
39 TranscriptBlock::heading(2, "Before landing"),
40 TranscriptBlock::ordered(vec![
41 TranscriptSpan::plain("Run the narrow layout checks"),
42 TranscriptSpan::plain("Read the receipt and the diff"),
43 TranscriptSpan::warning("Confirm the 40-column view"),
44 ]),
45 TranscriptBlock::table(
46 vec![Cow::Borrowed("Check"), Cow::Borrowed("State")],
47 vec![
48 vec![Cow::Borrowed("narrow layout"), Cow::Borrowed("kept")],
49 vec![Cow::Borrowed("all profiles"), Cow::Borrowed("kept")],
50 ],
51 ),
52 ])
53 .paint(area, buf, theme);
54 }
55
56 fn fenced_code(area: Rect, buf: &mut Buffer, theme: &Theme) {
57 let block = CodeBlock::new(
58 "rust",
59 "let theme = Theme::detect();\nframe.render_widget(view.themed(&theme), area);",
60 );
61 Transcript::new(vec![
62 TranscriptBlock::heading(2, "Paint into the frame"),
63 TranscriptBlock::code(block),
64 ])
65 .paint(area, buf, theme);
66 }
67
68 fn linked(area: Rect, buf: &mut Buffer, theme: &Theme) {
69 Transcript::new(vec![
70 TranscriptBlock::paragraph(vec![
71 TranscriptSpan::plain("Read the "),
72 TranscriptSpan::link("component guide", "https://example.invalid/guide"),
73 TranscriptSpan::plain(" before adding a component."),
74 ]),
75 TranscriptBlock::paragraph(vec![TranscriptSpan::muted(
76 "Links are metadata; the host dispatches.",
77 )]),
78 ])
79 .paint(area, buf, theme);
80 }
81
82 fn mounted(area: Rect, buf: &mut Buffer, theme: &Theme) {
83 use crate::{Role, TranscriptScrollFacts, TranscriptViewport, TranscriptViewportStyles};
84 let plain = theme.fg(Role::Foreground);
85 let selected = plain.patch(theme.bg(Role::Selected)).add_modifier(
86 if theme.color(Role::Foreground).is_none() {
87 Modifier::REVERSED
88 } else {
89 Modifier::empty()
90 },
91 );
92 let rows = vec![
93 Line::styled("User: Review the changed source", theme.fg(Role::Attention)),
94 Line::from(vec![
95 Span::styled("The ", plain),
96 Span::styled("selected words", selected),
97 Span::styled(" retain their source.", plain),
98 ]),
99 Line::styled(
100 if theme.ascii() {
101 "A composed cafe draft"
102 } else {
103 "A composed cafe\u{0301} draft with 鲸鱼"
104 },
105 plain,
106 ),
107 Line::styled(
108 "let source = exact_source;",
109 theme.fg(Role::Live).patch(theme.bg(Role::Surface)),
110 ),
111 Line::styled(
112 "Keep the permission receipt visible",
113 theme.fg(Role::Attention),
114 ),
115 Line::styled(
116 "Read the linked guide",
117 theme.fg(Role::Primary).add_modifier(Modifier::UNDERLINED),
118 ),
119 ];
120 let background = theme.bg(Role::Surface);
121 let mut viewport = TranscriptViewport::new(&rows);
122 viewport.style = background;
123 viewport.fill = true;
124 viewport.ascii = theme.ascii();
125 viewport.scrollbar = Some(TranscriptScrollFacts {
126 top: 4,
127 visible: usize::from(area.height),
128 total: 30,
129 });
130 viewport.jump_to_latest = true;
131 viewport.styles = TranscriptViewportStyles {
132 background,
133 track: theme.fg(Role::Border),
134 thumb: theme.fg(Role::Live),
135 jump_border: theme.fg(Role::Border),
136 jump_arrow: theme.fg(Role::Live),
137 };
138 viewport.paint(area, buf, theme);
139 }
140 fn focused(area: Rect, buf: &mut Buffer, theme: &Theme) {
141 let rows = vec![
142 Line::styled(
143 "Worker: Builder | paused",
144 theme
145 .fg(crate::Role::Attention)
146 .add_modifier(Modifier::BOLD),
147 ),
148 Line::styled("Old source row", theme.fg(crate::Role::Muted)),
149 Line::styled(
150 "The host supplies the current source rows",
151 theme.fg(crate::Role::Foreground),
152 ),
153 Line::styled(
154 "The pure viewport keeps the banner pinned",
155 theme.fg(crate::Role::Foreground),
156 ),
157 ];
158 let mut viewport = crate::TranscriptViewport::new(&rows);
159 viewport.pinned_rows = 1;
160 viewport.offset = 1;
161 viewport.style = theme.bg(crate::Role::Surface);
162 viewport.paint(area, buf, theme);
163 }
164
165 pub(crate) fn entries() -> Vec<Entry> {
166 vec![
167 Entry {
168 name: "transcript-mounted",
169 width: 52,
170 height: 9,
171 draw: mounted,
172 },
173 Entry {
174 name: "transcript-mounted-focus",
175 width: 52,
176 height: 6,
177 draw: focused,
178 },
179 Entry {
180 name: "transcript-prose",
181 width: 40,
182 height: 10,
183 draw: prose,
184 },
185 Entry {
186 name: "transcript-list-table",
187 width: 40,
188 height: 9,
189 draw: list_and_table,
190 },
191 Entry {
192 name: "transcript-code",
193 width: 40,
194 height: 6,
195 draw: fenced_code,
196 },
197 Entry {
198 name: "transcript-links",
199 width: 40,
200 height: 5,
201 draw: linked,
202 },
203 ]
204 }
205
205 lines RUST