# 🎨 **Command Component Design** ## **Overview** Design for the Command component that provides a command palette interface with search, filtering, and keyboard navigation. ## **Core Components** ### **Command Component** ```rust #[component] pub fn Command( #[prop(into, optional)] value: Option>, #[prop(into, optional)] on_select: Option>, #[prop(into, optional)] class: Option, #[prop(into, optional)] id: Option, #[prop(into, optional)] placeholder: Option, #[prop(into, optional)] disabled: Option>, #[prop(into, optional)] children: Option, ) -> impl IntoView { let (is_open, set_is_open) = signal(false); let (search_value, set_search_value) = signal(String::new()); let (selected_index, set_selected_index) = signal(0); let command_class = move || { let mut classes = vec!["flex", "h-full", "w-full", "flex-col", "overflow-hidden", "rounded-md", "border", "bg-popover", "text-popover-foreground"]; if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; let handle_keydown = move |ev: leptos::ev::KeyboardEvent| { match ev.key().as_str() { "ArrowDown" => { ev.prevent_default(); set_selected_index.update(|i| *i += 1); } "ArrowUp" => { ev.prevent_default(); set_selected_index.update(|i| if *i > 0 { *i -= 1 }); } "Enter" => { ev.prevent_default(); if let Some(on_select) = on_select.as_ref() { on_select.call(search_value.get()); } } "Escape" => { ev.prevent_default(); set_is_open.set(false); } _ => {} } }; view! {
{children}
} } ``` ### **CommandInput Component** ```rust #[component] pub fn CommandInput( #[prop(into, optional)] value: Option>, #[prop(into, optional)] on_change: Option>, #[prop(into, optional)] placeholder: Option, #[prop(into, optional)] class: Option, #[prop(into, optional)] disabled: Option>, ) -> impl IntoView { let (input_value, set_input_value) = value.unwrap_or_else(|| signal(String::new())); let input_class = move || { let mut classes = vec!["flex", "h-11", "w-full", "rounded-md", "bg-transparent", "py-3", "text-sm", "outline-none", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed", "disabled:opacity-50"]; if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; let handle_input = move |ev: leptos::ev::InputEvent| { let value = event_target_value(&ev); set_input_value.set(value.clone()); if let Some(on_change) = on_change.as_ref() { on_change.call(value); } }; view! { } } ``` ### **CommandList Component** ```rust #[component] pub fn CommandList( #[prop(into, optional)] class: Option, #[prop(into, optional)] children: Option, ) -> impl IntoView { let list_class = move || { let mut classes = vec!["max-h-[300px]", "overflow-y-auto", "overflow-x-hidden"]; if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; view! {
{children}
} } ``` ### **CommandEmpty Component** ```rust #[component] pub fn CommandEmpty( #[prop(into, optional)] class: Option, #[prop(into, optional)] children: Option, ) -> impl IntoView { let empty_class = move || { let mut classes = vec!["py-6", "text-center", "text-sm"]; if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; view! {
{children.unwrap_or_else(|| view! { "No results found." })}
} } ``` ### **CommandGroup Component** ```rust #[component] pub fn CommandGroup( #[prop(into, optional)] heading: Option, #[prop(into, optional)] class: Option, #[prop(into, optional)] children: Option, ) -> impl IntoView { let group_class = move || { let mut classes = vec!["overflow-hidden", "p-1", "text-foreground"]; if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; view! {
if let Some(heading) = heading {
{heading}
} {children}
} } ``` ### **CommandItem Component** ```rust #[component] pub fn CommandItem( #[prop(into, optional)] value: Option, #[prop(into, optional)] on_select: Option>, #[prop(into, optional)] class: Option, #[prop(into, optional)] disabled: Option>, #[prop(into, optional)] children: Option, ) -> impl IntoView { let (is_selected, set_is_selected) = signal(false); let item_class = move || { let mut classes = vec!["relative", "flex", "cursor-default", "select-none", "items-center", "rounded-sm", "px-2", "py-1.5", "text-sm", "outline-none", "aria-selected:bg-accent", "aria-selected:text-accent-foreground", "data-[disabled]:pointer-events-none", "data-[disabled]:opacity-50"]; if is_selected.get() { classes.push("bg-accent", "text-accent-foreground"); } if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; let handle_click = move |_| { if let Some(value) = value.as_ref() { if let Some(on_select) = on_select.as_ref() { on_select.call(value.clone()); } } }; view! {
{children}
} } ``` ### **CommandShortcut Component** ```rust #[component] pub fn CommandShortcut( #[prop(into, optional)] class: Option, #[prop(into, optional)] children: Option, ) -> impl IntoView { let shortcut_class = move || { let mut classes = vec!["ml-auto", "text-xs", "tracking-widest", "opacity-60"]; if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; view! { {children} } } ``` ### **CommandSeparator Component** ```rust #[component] pub fn CommandSeparator( #[prop(into, optional)] class: Option, ) -> impl IntoView { let separator_class = move || { let mut classes = vec!["-mx-1", "h-px", "bg-border"]; if let Some(custom_class) = class.as_ref() { classes.push(custom_class); } classes.join(" ") }; view! {