+
{children()}
-
}
}
#[component]
pub fn DropdownMenuSub(children: Children) -> impl IntoView {
- // TODO. Find a better way for dropdown__menu_sub_trigger.
- clx! {DropdownMenuSubRoot, li, "dropdown__menu_sub_trigger", " relative inline-flex relative gap-2 items-center py-1.5 px-2 w-full text-sm no-underline rounded-sm transition-colors duration-200 cursor-pointer text-popover-foreground [&_svg:not([class*='size-'])]:size-4 hover:bg-accent hover:text-accent-foreground"}
-
+ clx! {DropdownMenuSubRoot, li, "dropdown__menu_sub_trigger", "relative inline-flex gap-2 items-center py-1.5 px-2 w-full text-sm no-underline rounded-sm transition-colors duration-200 cursor-pointer text-popover-foreground hover:bg-accent hover:text-accent-foreground"}
view! {
{children()} }
}
#[component]
pub fn DropdownMenuSubTrigger(children: Children, #[prop(optional, into)] class: String) -> impl IntoView {
let class = tw_merge!("flex items-center justify-between w-full", class);
-
view! {
{children()}
-
+
}
}
#[component]
pub fn DropdownMenuSubItem(children: Children, #[prop(optional, into)] class: String) -> impl IntoView {
- let class = tw_merge!(
- "inline-flex gap-2 items-center w-full rounded-sm px-3 py-2 text-sm transition-all duration-150 ease text-popover-foreground hover:bg-accent hover:text-accent-foreground cursor-pointer hover:translate-x-[2px]",
- class
- );
-
- view! {
-
- {children()}
-
- }
+ let class = tw_merge!("inline-flex gap-2 items-center w-full rounded-sm px-3 py-2 text-sm transition-all duration-150 ease text-popover-foreground hover:bg-accent hover:text-accent-foreground cursor-pointer hover:translate-x-[2px]", class);
+ view! {
{children()} }
}
diff --git a/frontend/src/components/ui/multi_select.rs b/frontend/src/components/ui/multi_select.rs
index d5ddc0d..b2699dd 100644
--- a/frontend/src/components/ui/multi_select.rs
+++ b/frontend/src/components/ui/multi_select.rs
@@ -1,43 +1,29 @@
use std::collections::HashSet;
-
use icons::{Check, ChevronDown, ChevronUp};
use leptos::context::Provider;
use leptos::prelude::*;
use tw_merge::*;
-
use crate::components::hooks::use_can_scroll_vertical::use_can_scroll_vertical;
use crate::components::hooks::use_random::use_random_id_for;
-// * Reuse @select.rs
pub use crate::components::ui::select::{
SelectGroup as MultiSelectGroup, SelectItem as MultiSelectItem,
};
#[derive(Clone, Copy, PartialEq, Eq, Default)]
+#[allow(dead_code)]
pub enum MultiSelectAlign {
- Start,
- #[default]
- Center,
- End,
+ Start, #[default] Center, End,
}
-/* ========================================================== */
-/* ✨ FUNCTIONS ✨ */
-/* ========================================================== */
-
#[component]
pub fn MultiSelectValue(#[prop(optional, into)] placeholder: String) -> impl IntoView {
let multi_select_ctx = expect_context::
();
-
view! {
{move || {
let values = multi_select_ctx.values_signal.get();
- if values.is_empty() {
- placeholder.clone()
- } else {
- let count = values.len();
- if count == 1 { "1 selected".to_string() } else { format!("{} selected", count) }
- }
+ if values.is_empty() { placeholder.clone() }
+ else { let count = values.len(); if count == 1 { "1 selected".to_string() } else { format!("{} selected", count) } }
}}
}
@@ -50,41 +36,17 @@ pub fn MultiSelectOption(
#[prop(optional, into)] value: Option,
) -> impl IntoView {
let multi_select_ctx = expect_context::();
-
let value_clone = value.clone();
let is_selected = Signal::derive(move || {
- if let Some(ref val) = value_clone {
- multi_select_ctx.values_signal.with(|values| values.contains(val))
- } else {
- false
- }
+ if let Some(ref val) = value_clone { multi_select_ctx.values_signal.with(|values| values.contains(val)) } else { false }
});
-
- let class = tw_merge!(
- "group inline-flex gap-2 items-center w-full text-sm text-left transition-colors duration-200 focus:outline-none focus-visible:outline-none text-popover-foreground [&_svg:not([class*='size-'])]:size-4 hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50",
- class
- );
-
+ let class = tw_merge!("group inline-flex gap-2 items-center w-full text-sm text-left transition-colors duration-200 focus:outline-none focus-visible:outline-none text-popover-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50", class);
view! {
-