Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Building styled and more featured component libraries on top of Dioxus Primitive

We're still in the early days - Many components are still being created and stabilized.

30/30
31/31

- [x] Accordion
- [x] Alert Dialog
Expand All @@ -60,6 +60,7 @@ We're still in the early days - Many components are still being created and stab
- [x] Slider
- [x] Switch
- [x] Tabs
- [x] Textarea
- [x] Toast
- [x] Toggle
- [x] Toggle Group
Expand Down
1 change: 1 addition & 0 deletions component.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"preview/src/components/aspect_ratio",
"preview/src/components/scroll_area",
"preview/src/components/date_picker",
"preview/src/components/textarea",
"preview/src/components/skeleton",
"preview/src/components/card"
]
Expand Down
1 change: 1 addition & 0 deletions preview/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ examples!(
slider,
switch,
tabs,
textarea[outline, fade, ghost],
toast,
toggle_group,
toggle,
Expand Down
21 changes: 21 additions & 0 deletions preview/src/components/textarea/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "textarea",
"description": "a textarea component used to allow users to enter multi-line text input",
"authors": [
"zhiyanzhaijie"
],
"exclude": [
"variants",
"docs.md",
"component.json"
],
"cargoDependencies": [
{
"name": "dioxus-primitives",
"git": "https://github.com/DioxusLabs/components"
}
],
"globalAssets": [
"../../../assets/dx-components-theme.css"
]
}
78 changes: 78 additions & 0 deletions preview/src/components/textarea/component.rs
Original file line number Diff line number Diff line change
@@ -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}
}
}
}
14 changes: 14 additions & 0 deletions preview/src/components/textarea/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
The textarea element is used to allow users to enter multi-line text input in a user interface.

## Component Structure

```rust
textarea {
// Global html attributes
class: "textarea",
"data-style": "default",
// Children
{children}
}
```

2 changes: 2 additions & 0 deletions preview/src/components/textarea/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod component;
pub use component::*;
87 changes: 87 additions & 0 deletions preview/src/components/textarea/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* Base */
.textarea {
width: 100%;
min-height: 4rem;
padding: 8px 12px;
line-height: 1.5;
font-family: inherit;
color: var(--secondary-color-4);
outline: none;
resize: vertical;
transition: background-color 100ms ease-out, border-color 100ms ease-out, box-shadow 100ms ease-out;

-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
margin: 0;
border: none;
background: none;
box-sizing: border-box;
border-radius: 0.5rem;
}

.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):not(: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);
}
33 changes: 33 additions & 0 deletions preview/src/components/textarea/variants/fade/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use super::super::component::*;
use crate::components::label::Label;
use dioxus::prelude::*;

#[component]
pub fn Demo() -> Element {
let mut description = use_signal(String::new);
rsx! {
div {
display: "flex",
flex_direction: "column",
gap: "1.5rem",

p { id: "textarea-message", "Description here: {description}" }

div {
display: "flex",
flex_direction: "column",
gap: ".5rem",
justify_content: "center",

Label { html_for: "fade", "Fade" }
Textarea {
id: "fade",
variant: TextareaVariant::Fade,
placeholder: "Enter your description",
value: description,
oninput: move |e: FormEvent| description.set(e.value()),
}
}
}
}
}
33 changes: 33 additions & 0 deletions preview/src/components/textarea/variants/ghost/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use super::super::component::*;
use crate::components::label::Label;
use dioxus::prelude::*;

#[component]
pub fn Demo() -> Element {
let mut description = use_signal(String::new);
rsx! {
div {
display: "flex",
flex_direction: "column",
gap: "1.5rem",

p { id: "textarea-message", "Description here: {description}" }

div {
display: "flex",
flex_direction: "column",
gap: ".5rem",
justify_content: "center",

Label { html_for: "ghost", "Ghost" }
Textarea {
id: "ghost",
variant: TextareaVariant::Ghost,
placeholder: "Enter your description",
value: description,
oninput: move |e: FormEvent| description.set(e.value()),
}
}
}
}
}
33 changes: 33 additions & 0 deletions preview/src/components/textarea/variants/main/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use super::super::component::*;
use crate::components::label::Label;
use dioxus::prelude::*;

#[component]
pub fn Demo() -> Element {
let mut description = use_signal(String::new);
rsx! {
div {
display: "flex",
flex_direction: "column",
gap: "1.5rem",

p { id: "textarea-message", "Description here: {description}" }

div {
display: "flex",
flex_direction: "column",
gap: ".5rem",
justify_content: "center",

Label { html_for: "default", "Default" }
Textarea {
id: "default",
variant: TextareaVariant::Default,
placeholder: "Enter your description",
value: description,
oninput: move |e: FormEvent| description.set(e.value()),
}
}
}
}
}
32 changes: 32 additions & 0 deletions preview/src/components/textarea/variants/outline/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use super::super::component::*;
use crate::components::label::Label;
use dioxus::prelude::*;

#[component]
pub fn Demo() -> Element {
let mut description = use_signal(String::new);
rsx! {
div {
display: "flex",
flex_direction: "column",
gap: "1.5rem",

p { id: "textarea-message", "Description here: {description}" }

div {
display: "flex",
flex_direction: "column",
gap: ".5rem",
justify_content: "center",
Label { html_for: "outline", "Outline" }
Textarea {
id: "outline",
variant: TextareaVariant::Outline,
placeholder: "Enter your description",
value: description,
oninput: move |e: FormEvent| description.set(e.value()),
}
}
}
}
}
Loading