feat(components): add the Textarea component
This commit is contained in:
@@ -17,3 +17,4 @@ pub use edit_quote::EditQuote;
|
|||||||
pub mod calendar;
|
pub mod calendar;
|
||||||
pub mod date_picker;
|
pub mod date_picker;
|
||||||
pub mod popover;
|
pub mod popover;
|
||||||
|
pub mod textarea;
|
||||||
|
|||||||
78
src/components/textarea/component.rs
Normal file
78
src/components/textarea/component.rs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Default)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum TextareaVariant {
|
||||||
|
#[default]
|
||||||
|
Default,
|
||||||
|
Fade,
|
||||||
|
Outline,
|
||||||
|
Ghost,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextareaVariant {
|
||||||
|
pub fn class(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
TextareaVariant::Default => "default",
|
||||||
|
TextareaVariant::Fade => "fade",
|
||||||
|
TextareaVariant::Outline => "outline",
|
||||||
|
TextareaVariant::Ghost => "ghost",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Textarea(
|
||||||
|
oninput: Option<EventHandler<FormEvent>>,
|
||||||
|
onchange: Option<EventHandler<FormEvent>>,
|
||||||
|
oninvalid: Option<EventHandler<FormEvent>>,
|
||||||
|
onselect: Option<EventHandler<SelectionEvent>>,
|
||||||
|
onselectionchange: Option<EventHandler<SelectionEvent>>,
|
||||||
|
onfocus: Option<EventHandler<FocusEvent>>,
|
||||||
|
onblur: Option<EventHandler<FocusEvent>>,
|
||||||
|
onfocusin: Option<EventHandler<FocusEvent>>,
|
||||||
|
onfocusout: Option<EventHandler<FocusEvent>>,
|
||||||
|
onkeydown: Option<EventHandler<KeyboardEvent>>,
|
||||||
|
onkeypress: Option<EventHandler<KeyboardEvent>>,
|
||||||
|
onkeyup: Option<EventHandler<KeyboardEvent>>,
|
||||||
|
oncompositionstart: Option<EventHandler<CompositionEvent>>,
|
||||||
|
oncompositionupdate: Option<EventHandler<CompositionEvent>>,
|
||||||
|
oncompositionend: Option<EventHandler<CompositionEvent>>,
|
||||||
|
oncopy: Option<EventHandler<ClipboardEvent>>,
|
||||||
|
oncut: Option<EventHandler<ClipboardEvent>>,
|
||||||
|
onpaste: Option<EventHandler<ClipboardEvent>>,
|
||||||
|
#[props(default)] variant: TextareaVariant,
|
||||||
|
#[props(extends=GlobalAttributes)]
|
||||||
|
#[props(extends=textarea)]
|
||||||
|
attributes: Vec<Attribute>,
|
||||||
|
children: Element,
|
||||||
|
) -> Element {
|
||||||
|
rsx! {
|
||||||
|
document::Link { rel: "stylesheet", href: asset!("./style.css") }
|
||||||
|
textarea {
|
||||||
|
class: "textarea",
|
||||||
|
"data-slot": "textarea",
|
||||||
|
"data-style": variant.class(),
|
||||||
|
oninput: move |e| _ = oninput.map(|callback| callback(e)),
|
||||||
|
onchange: move |e| _ = onchange.map(|callback| callback(e)),
|
||||||
|
oninvalid: move |e| _ = oninvalid.map(|callback| callback(e)),
|
||||||
|
onselect: move |e| _ = onselect.map(|callback| callback(e)),
|
||||||
|
onselectionchange: move |e| _ = onselectionchange.map(|callback| callback(e)),
|
||||||
|
onfocus: move |e| _ = onfocus.map(|callback| callback(e)),
|
||||||
|
onblur: move |e| _ = onblur.map(|callback| callback(e)),
|
||||||
|
onfocusin: move |e| _ = onfocusin.map(|callback| callback(e)),
|
||||||
|
onfocusout: move |e| _ = onfocusout.map(|callback| callback(e)),
|
||||||
|
onkeydown: move |e| _ = onkeydown.map(|callback| callback(e)),
|
||||||
|
onkeypress: move |e| _ = onkeypress.map(|callback| callback(e)),
|
||||||
|
onkeyup: move |e| _ = onkeyup.map(|callback| callback(e)),
|
||||||
|
oncompositionstart: move |e| _ = oncompositionstart.map(|callback| callback(e)),
|
||||||
|
oncompositionupdate: move |e| _ = oncompositionupdate.map(|callback| callback(e)),
|
||||||
|
oncompositionend: move |e| _ = oncompositionend.map(|callback| callback(e)),
|
||||||
|
oncopy: move |e| _ = oncopy.map(|callback| callback(e)),
|
||||||
|
oncut: move |e| _ = oncut.map(|callback| callback(e)),
|
||||||
|
onpaste: move |e| _ = onpaste.map(|callback| callback(e)),
|
||||||
|
..attributes,
|
||||||
|
{children}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/components/textarea/mod.rs
Normal file
2
src/components/textarea/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
mod component;
|
||||||
|
pub use component::*;
|
||||||
84
src/components/textarea/style.css
Normal file
84
src/components/textarea/style.css
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/* Base */
|
||||||
|
.textarea {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 4rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
margin: 0;
|
||||||
|
appearance: none;
|
||||||
|
background: none;
|
||||||
|
color: var(--secondary-color-4);
|
||||||
|
font-family: inherit;
|
||||||
|
line-height: 1.5;
|
||||||
|
outline: none;
|
||||||
|
resize: vertical;
|
||||||
|
transition: background-color 100ms ease-out, border-color 100ms ease-out, box-shadow 100ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea:disabled {
|
||||||
|
color: var(--secondary-color-5);
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea::placeholder {
|
||||||
|
color: var(--secondary-color-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default Variant */
|
||||||
|
.textarea[data-style="default"] {
|
||||||
|
background: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3));
|
||||||
|
box-shadow: inset 0 0 0 1px var(--light, var(--primary-color-6)) var(--dark, var(--primary-color-7));
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea[data-style="default"]:hover:not(:disabled),
|
||||||
|
.textarea[data-style="default"]:focus {
|
||||||
|
background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-5));
|
||||||
|
color: var(--secondary-color-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fade Variant */
|
||||||
|
.textarea[data-style="fade"] {
|
||||||
|
background: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3));
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea[data-style="fade"]:hover:not(:disabled),
|
||||||
|
.textarea[data-style="fade"]:focus {
|
||||||
|
background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-5));
|
||||||
|
color: var(--secondary-color-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Outline Variant */
|
||||||
|
.textarea[data-style="outline"] {
|
||||||
|
border: 1px solid var(--primary-color-6);
|
||||||
|
background-color: var(--light, var(--primary-color))
|
||||||
|
var(--dark, var(--primary-color-3));
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea[data-style="outline"]:hover:not(:disabled, :focus) {
|
||||||
|
border-color: var(--primary-color-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea[data-style="outline"]:focus {
|
||||||
|
border-color: var(--focused-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea[data-style="outline"]:invalid,
|
||||||
|
.textarea[data-style="outline"][aria-invalid="true"] {
|
||||||
|
border-color: var(--primary-error-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ghost Variant */
|
||||||
|
.textarea[data-style="ghost"] {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea[data-style="ghost"]:hover:not(:disabled) {
|
||||||
|
background-color: var(--primary-color-5);
|
||||||
|
color: var(--secondary-color-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea[data-style="ghost"]:focus {
|
||||||
|
border-color: var(--focused-border-color);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user