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 date_picker;
|
||||
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