fc_dioxus/components/
tool_call.rs1use crate::{
3 core::{
4 assets,
5 attrs::{clipped_attributes, component_attributes, FcData, Kind},
6 measure::{custom_property, CustomProperty},
7 },
8 prelude::*,
9 theme::use_stylesheets,
10};
11const BEM: Bem = Bem::new("fc-tool");
12
13#[derive(Debug, Clone, Copy, PartialEq)]
15pub enum ToolProgress {
16 Indeterminate,
18 Done(Percent),
20}
21
22#[component]
26pub fn ToolCall(
27 name: String,
28 state: Lifecycle,
29 #[props(default)]
31 duration: Option<String>,
32 #[props(default)] progress: Option<ToolProgress>,
33 #[props(default)]
35 payload_label: Option<Element>,
36 #[props(default)]
38 payload: Option<Clipped>,
39 #[props(default)] error: Option<Element>,
40 #[props(default)] record: Record,
41 #[props(default)] class: Option<String>,
42 #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
43) -> Element {
44 let mut attributes = component_attributes(
45 attributes,
46 ClassList::new(BEM.block()).extend(class.as_deref()),
47 &[],
48 );
49 attributes.extend(
50 FcData {
51 kind: Some(Kind::ToolCall),
52 id: record.id.clone(),
53 seq: record.seq,
54 state: Some(state),
55 ts: record.ts.clone(),
56 ..FcData::default()
57 }
58 .attributes(),
59 );
60 let state_attr = FcData {
61 state: Some(state),
62 ..FcData::default()
63 }
64 .attributes();
65 rsx! {
66 if use_stylesheets() { document::Stylesheet { href: assets::COMPONENTS_TOOL_CALL_CSS } }
67 div { ..attributes,
68 div { class: BEM.element("header"),
69 span { class: BEM.element("name"), "{name}" }
70 span { class: BEM.element("state"), ..state_attr, "{state.as_str()}" }
71 if let Some(duration) = duration { span { class: BEM.element("duration"), "{duration}" } }
72 }
73 if let Some(progress) = progress {
74 div { class: BEM.element("progress"),
75 div { class: BEM.element("progress-track"),
76 match progress {
77 ToolProgress::Indeterminate => rsx! {
78 div { class: BEM.element("progress-bar"), role: "progressbar", aria_label: "{name} progress" }
79 },
80 ToolProgress::Done(percent) => {
81 let width = custom_property(CustomProperty::ToolProgress, format!("{percent}%"));
82 rsx! {
83 div { class: BEM.element("progress-bar"), role: "progressbar", aria_label: "{name} progress",
84 aria_valuemin: "0", aria_valuemax: "100", aria_valuenow: "{percent}", ..crate::spread![width] }
85 }
86 }
87 }
88 }
89 }
90 }
91 if let Some(label) = payload_label { span { class: BEM.element("label"), {label} } }
92 if let Some(payload) = payload {
93 div { class: BEM.element("payload"), ..clipped_attributes(&payload), "{payload.shown()}" }
94 }
95 if let Some(error) = error { div { class: BEM.element("error"), {error} } }
96 }
97 }
98}