mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-23 06:19:22 -05:00
feat: adds ListboxInjection
This commit is contained in:
parent
87a4ef115c
commit
7da18dc9e5
3 changed files with 51 additions and 22 deletions
|
@ -1,19 +1,23 @@
|
||||||
use super::AutoCompleteInjection;
|
use super::AutoCompleteInjection;
|
||||||
|
use crate::combobox::listbox::ListboxInjection;
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn AutoCompleteOption(value: String, children: Children) -> impl IntoView {
|
pub fn AutoCompleteOption(value: String, children: Children) -> impl IntoView {
|
||||||
let auto_complete = AutoCompleteInjection::expect_context();
|
let auto_complete = AutoCompleteInjection::expect_context();
|
||||||
|
let listbox = ListboxInjection::expect_context();
|
||||||
let is_selected = Memo::new({
|
let is_selected = Memo::new({
|
||||||
let value = value.clone();
|
let value = value.clone();
|
||||||
move |_| auto_complete.is_selected(&value)
|
move |_| auto_complete.is_selected(&value)
|
||||||
});
|
});
|
||||||
let id = uuid::Uuid::new_v4().to_string();
|
let id = uuid::Uuid::new_v4().to_string();
|
||||||
auto_complete.insert_option(id.clone(), value.clone());
|
|
||||||
{
|
{
|
||||||
|
auto_complete.insert_option(id.clone(), value.clone());
|
||||||
let id = id.clone();
|
let id = id.clone();
|
||||||
|
listbox.trigger();
|
||||||
on_cleanup(move || {
|
on_cleanup(move || {
|
||||||
auto_complete.remove_option(&id);
|
auto_complete.remove_option(&id);
|
||||||
|
listbox.trigger();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use super::listbox::ListboxInjection;
|
||||||
use crate::ComboboxInjection;
|
use crate::ComboboxInjection;
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use thaw_components::{Fallback, If, OptionComp, Then};
|
use thaw_components::{Fallback, If, OptionComp, Then};
|
||||||
|
@ -10,6 +11,7 @@ pub fn ComboboxOption(
|
||||||
#[prop(optional)] children: Option<Children>,
|
#[prop(optional)] children: Option<Children>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let combobox = ComboboxInjection::expect_context();
|
let combobox = ComboboxInjection::expect_context();
|
||||||
|
let listbox = ListboxInjection::expect_context();
|
||||||
let value = StoredValue::new(value.unwrap_or_else(|| text.clone()));
|
let value = StoredValue::new(value.unwrap_or_else(|| text.clone()));
|
||||||
let text = StoredValue::new(text);
|
let text = StoredValue::new(text);
|
||||||
let is_selected = Memo::new(move |_| value.with_value(|value| combobox.is_selected(&value)));
|
let is_selected = Memo::new(move |_| value.with_value(|value| combobox.is_selected(&value)));
|
||||||
|
@ -26,8 +28,10 @@ pub fn ComboboxOption(
|
||||||
{
|
{
|
||||||
combobox.insert_option(id.clone(), (value.get_value(), text.get_value()));
|
combobox.insert_option(id.clone(), (value.get_value(), text.get_value()));
|
||||||
let id = id.clone();
|
let id = id.clone();
|
||||||
|
listbox.trigger();
|
||||||
on_cleanup(move || {
|
on_cleanup(move || {
|
||||||
combobox.remove_option(&id);
|
combobox.remove_option(&id);
|
||||||
|
listbox.trigger();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use super::utils::{get_dropdown_action_from_key, DropdownAction};
|
use super::utils::{get_dropdown_action_from_key, DropdownAction};
|
||||||
use crate::{ConfigInjection, _aria::ActiveDescendantController};
|
use crate::{ConfigInjection, _aria::ActiveDescendantController};
|
||||||
use leptos::{ev, html, prelude::*};
|
use leptos::{context::Provider, ev, html, prelude::*};
|
||||||
|
use std::sync::Arc;
|
||||||
use thaw_components::CSSTransition;
|
use thaw_components::CSSTransition;
|
||||||
use thaw_utils::mount_style;
|
use thaw_utils::mount_style;
|
||||||
use web_sys::{HtmlElement, Node};
|
use web_sys::{HtmlElement, Node};
|
||||||
|
@ -18,16 +17,22 @@ pub fn Listbox(
|
||||||
mount_style("listbox", include_str!("./listbox.css"));
|
mount_style("listbox", include_str!("./listbox.css"));
|
||||||
|
|
||||||
let config_provider = ConfigInjection::expect_context();
|
let config_provider = ConfigInjection::expect_context();
|
||||||
let effect = RenderEffect::new(move |_| {
|
let trigger = ArcTrigger::new();
|
||||||
|
let effect = RenderEffect::new({
|
||||||
|
let trigger = trigger.clone();
|
||||||
|
move |_| {
|
||||||
|
trigger.track();
|
||||||
if let Some(listbox_el) = listbox_ref.get() {
|
if let Some(listbox_el) = listbox_ref.get() {
|
||||||
set_listbox(listbox_el.into());
|
set_listbox(listbox_el.into());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
on_cleanup(move || {
|
on_cleanup(move || {
|
||||||
drop(effect);
|
drop(effect);
|
||||||
});
|
});
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
<Provider value=ListboxInjection(trigger)>
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
node_ref=listbox_ref
|
node_ref=listbox_ref
|
||||||
name="fade-in-scale-up-transition"
|
name="fade-in-scale-up-transition"
|
||||||
|
@ -45,6 +50,22 @@ pub fn Listbox(
|
||||||
{children()}
|
{children()}
|
||||||
</div>
|
</div>
|
||||||
</CSSTransition>
|
</CSSTransition>
|
||||||
|
</Provider>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) struct ListboxInjection(ArcTrigger);
|
||||||
|
|
||||||
|
impl ListboxInjection {
|
||||||
|
#[inline]
|
||||||
|
pub fn expect_context() -> Self {
|
||||||
|
expect_context()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn trigger(&self) {
|
||||||
|
self.0.trigger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue