nova_forms/components/
repeatable.rs1use leptos::*;
2
3use crate::{ButtonGroup, GroupContext, QueryStringPart};
4
5use super::{Button, Group};
6
7#[component]
9pub fn Repeatable<F, IV>(
10 #[prop(into)] bind: QueryStringPart,
12 item: F
14) -> impl IntoView
15where
16 F: Fn(usize) -> IV + 'static,
17 IV: IntoView,
18{
19 let item = store_value(item);
20
21 view! {
22 <Group bind=bind>
23 {
24 let group = expect_context::<GroupContext>();
25 let (size, set_size) = create_signal(group.len().get_untracked().unwrap_or_default());
26
27 view! {
28 <div class="repeatable">
29 <For
30 each=move || (0..size.get())
31 key=|i| *i
32 children=move |i| {
33 view! {
34 <Group bind=QueryStringPart::from(i)>{item.with_value(|item| item(i))}</Group>
35 }
36 }
37 />
38 <ButtonGroup>
39 <Button
40 on:click=move |_| set_size.update(|i| *i -= 1)
41 label="Remove"
42 icon="remove"
43 disabled=Signal::derive(move || size.get() == 0)
44 />
45 <Button on:click=move |_| set_size.update(|i| *i += 1) label="Add" icon="add" />
46 </ButtonGroup>
47 </div>
48 }
49 }
50 </Group>
51
52 }
53}