dioxus_tw_components/components/
formlist.rs1use dioxus::prelude::*;
2
3pub struct FormListState {
4 max_size: usize,
5 current_size: usize,
6}
7
8impl FormListState {
9 fn new(current_size: usize) -> Self {
10 FormListState {
11 max_size: 1,
12 current_size,
13 }
14 }
15
16 fn get_max_size(&self) -> usize {
17 self.max_size
18 }
19
20 fn set_max_size(&mut self, max_size: usize) {
21 self.max_size = max_size;
22 }
23
24 fn get_current_size(&self) -> usize {
25 self.current_size
26 }
27
28 fn add_one(&mut self) {
29 if self.current_size < self.max_size {
30 self.current_size += 1;
31 }
32 }
33
34 fn remove_one(&mut self) {
35 if self.current_size > 1 {
36 self.current_size -= 1;
37 }
38 }
39}
40
41#[derive(Clone, PartialEq, Props)]
42pub struct FormListProps {
43 #[props(extends = div, extends = GlobalAttributes)]
44 attributes: Vec<Attribute>,
45
46 #[props(default = 1)]
47 max_size: usize,
48 #[props(default = 1)]
49 current_size: usize,
50
51 children: Element,
52}
53
54#[component]
55pub fn FormList(mut props: FormListProps) -> Element {
56 let default_classes = "formlist";
57 crate::setup_class_attribute(&mut props.attributes, default_classes);
58
59 let mut state = use_context_provider(|| Signal::new(FormListState::new(props.current_size)));
60
61 use_effect(move || {
62 state.write().set_max_size(props.max_size);
63 });
64
65 rsx! {
66 div { ..props.attributes, {props.children} }
67 }
68}
69
70#[derive(Clone, PartialEq, Props)]
71pub struct FormListItemProps {
72 #[props(extends = div, extends = GlobalAttributes)]
73 attributes: Vec<Attribute>,
74
75 children: Element,
76}
77
78#[component]
79pub fn FormListItem(mut props: FormListItemProps) -> Element {
80 let default_classes = "formlist-item";
81 crate::setup_class_attribute(&mut props.attributes, default_classes);
82
83 rsx! {
84 div { ..props.attributes, {props.children} }
85 }
86}
87
88#[derive(Clone, PartialEq, Props)]
89pub struct FormListLabelProps {
90 #[props(extends = label, extends = GlobalAttributes)]
91 attributes: Vec<Attribute>,
92
93 children: Element,
94}
95
96#[component]
97pub fn FormListLabel(mut props: FormListLabelProps) -> Element {
98 let default_classes = "formlist-label";
99 crate::setup_class_attribute(&mut props.attributes, default_classes);
100
101 rsx! {
102 label { ..props.attributes, {props.children} }
103 }
104}
105
106#[derive(Clone, PartialEq, Props)]
107pub struct FormListTriggerPlusProps {
108 #[props(extends = div, extends = GlobalAttributes)]
109 attributes: Vec<Attribute>,
110
111 children: Element,
112}
113
114#[component]
115pub fn FormListTriggerPlus(mut props: FormListTriggerPlusProps) -> Element {
116 let mut state = use_context::<Signal<FormListState>>();
117
118 let default_classes = "formlist-trigger-plus";
119 crate::setup_class_attribute(&mut props.attributes, default_classes);
120
121 rsx! {
122 div {
123 onclick: move |_| {
124 state.write().add_one();
125 },
126 ..props.attributes,
127 {props.children}
128 }
129 }
130}
131
132#[derive(Clone, PartialEq, Props)]
133pub struct FormListTriggerMinusProps {
134 #[props(extends = div, extends = GlobalAttributes)]
135 attributes: Vec<Attribute>,
136
137 children: Element,
138}
139
140#[component]
141pub fn FormListTriggerMinus(mut props: FormListTriggerMinusProps) -> Element {
142 let mut state = use_context::<Signal<FormListState>>();
143
144 let default_classes = "formlist-trigger-minus";
145 crate::setup_class_attribute(&mut props.attributes, default_classes);
146
147 rsx! {
148 div {
149 onclick: move |_| {
150 state.write().remove_one();
151 },
152 ..props.attributes,
153 {props.children}
154 }
155 }
156}
157
158#[derive(Clone, PartialEq, Props)]
159pub struct FormListContentProps {
160 #[props(extends = div, extends = GlobalAttributes)]
161 attributes: Vec<Attribute>,
162
163 #[props(default)]
164 list_fields: Vec<Element>,
165}
166
167#[component]
168pub fn FormListContent(mut props: FormListContentProps) -> Element {
169 let mut state = use_context::<Signal<FormListState>>();
170
171 let default_classes = "formlist-content";
172 crate::setup_class_attribute(&mut props.attributes, default_classes);
173
174 let max_size = props.list_fields.len();
175 use_effect(move || {
176 state.write().set_max_size(max_size);
177 });
178
179 let fields = props
180 .list_fields
181 .iter()
182 .take(state.read().get_current_size())
183 .map(|field| {
184 rsx! {
185 {field.clone()}
186 }
187 });
188
189 rsx! {
190 div { ..props.attributes,{fields} }
191 }
192}
193
194#[component]
195pub fn FormListMaxSize() -> Element {
196 let state = use_context::<Signal<FormListState>>();
197
198 rsx! { "{state.read().get_max_size()}" }
199}
200
201#[component]
202pub fn FormListCurrentSize() -> Element {
203 let state = use_context::<Signal<FormListState>>();
204
205 rsx! { "{state.read().get_current_size()}" }
206}