Skip to main content

patternfly_yew/components/
file_upload.rs

1use yew::prelude::*;
2
3#[derive(Clone, Debug, PartialEq, Properties)]
4pub struct FileUploadProperties {
5    #[prop_or_default]
6    pub children: Html,
7    #[prop_or_default]
8    pub drag_over: bool,
9    #[prop_or_default]
10    pub r#ref: NodeRef,
11}
12
13/// File upload component
14///
15/// > A **file upload** component allows the users to upload a single file into the browser.
16///
17/// See: <https://www.patternfly.org/components/file-upload>
18///
19/// # Properties
20///
21/// Defined in [`FileUploadProperties`].
22#[function_component(FileUpload)]
23pub fn file_upload(props: &FileUploadProperties) -> Html {
24    let mut class = classes!("pf-v6-c-file-upload");
25
26    if props.drag_over {
27        class.push(classes!("pf-m-drag-hover"));
28    }
29
30    html! (<div {class} ref={props.r#ref.clone()}>{ props.children.clone() }</div>)
31}
32
33#[derive(Clone, Debug, PartialEq, Properties)]
34pub struct FileUploadSelectProperties {
35    #[prop_or_default]
36    pub children: Html,
37}
38
39#[function_component(FileUploadSelect)]
40pub fn file_upload_select(props: &FileUploadSelectProperties) -> Html {
41    html!(<div class="pf-v6-c-file-upload__file-select">{ props.children.clone() }</div>)
42}
43
44#[derive(Clone, Debug, PartialEq, Properties)]
45pub struct FileUploadDetailsProperties {
46    /// The details section, supposed to be a single [`crate::components::TextArea`].
47    #[prop_or_default]
48    pub children: Html,
49
50    /// Set flag if upload is processing.
51    ///
52    /// This will render a spinner on the detail component section.
53    #[prop_or_default]
54    pub processing: bool,
55
56    /// If the validation state is invalid
57    #[prop_or_default]
58    pub invalid: bool,
59}
60
61#[function_component(FileUploadDetails)]
62pub fn file_upload_select(props: &FileUploadDetailsProperties) -> Html {
63    html!(
64        <div class="pf-v6-c-file-upload__file-details">
65            { props.children.clone() }
66            if props.processing {
67                <div class="pf-v6-c-file-upload__file-details-spinner">
68                    <span
69                        class="pf-v6-c-spinner pf-m-lg"
70                        role="progressbar"
71                        aria-label="Loading..."
72                    >
73                        <span class="pf-v6-c-spinner__clipper" />
74                        <span class="pf-v6-c-spinner__lead-ball" />
75                        <span class="pf-v6-c-spinner__tail-ball" />
76                    </span>
77                </div>
78            }
79        </div>
80    )
81}