context menu implementation testing
This commit is contained in:
@@ -1,64 +1,63 @@
|
||||
use super::props::*;
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_primitives::context_menu::{
|
||||
self, ContextMenuContentProps, ContextMenuItemProps, ContextMenuProps, ContextMenuTriggerProps,
|
||||
};
|
||||
|
||||
const CONTEXT_MENU_CSS: Asset = asset!("./style.scss");
|
||||
|
||||
#[component]
|
||||
pub fn ContextMenu(props: ContextMenuProps) -> Element {
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: asset!("./style.css") }
|
||||
context_menu::ContextMenu {
|
||||
disabled: props.disabled,
|
||||
open: props.open,
|
||||
default_open: props.default_open,
|
||||
on_open_change: props.on_open_change,
|
||||
roving_loop: props.roving_loop,
|
||||
attributes: props.attributes,
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
pub fn ContextMenu(props: ContextMenuProps) -> Element
|
||||
{
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: CONTEXT_MENU_CSS }
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ContextMenuTrigger(props: ContextMenuTriggerProps) -> Element {
|
||||
rsx! {
|
||||
context_menu::ContextMenuTrigger {
|
||||
padding: "20px",
|
||||
background: "var(--primary-color)",
|
||||
border: "1px dashed var(--primary-color-6)",
|
||||
border_radius: ".5rem",
|
||||
cursor: "context-menu",
|
||||
user_select: "none",
|
||||
text_align: "center",
|
||||
attributes: props.attributes,
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
pub fn ContextMenuTrigger(props: ContextMenuTriggerProps) -> Element
|
||||
{
|
||||
rsx! {
|
||||
div{
|
||||
class: "contextMenuTrigger",
|
||||
oncontextmenu: move|e|{
|
||||
|
||||
},
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ContextMenuContent(props: ContextMenuContentProps) -> Element {
|
||||
rsx! {
|
||||
context_menu::ContextMenuContent {
|
||||
class: "context-menu-content",
|
||||
id: props.id,
|
||||
attributes: props.attributes,
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
pub fn ContextMenuContent(props: ContextMenuContentProps) -> Element
|
||||
{
|
||||
rsx! {
|
||||
div{
|
||||
class: "contextMenuContent",
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ContextMenuItem(props: ContextMenuItemProps) -> Element {
|
||||
rsx! {
|
||||
context_menu::ContextMenuItem {
|
||||
class: "context-menu-item",
|
||||
disabled: props.disabled,
|
||||
value: props.value,
|
||||
index: props.index,
|
||||
on_select: props.on_select,
|
||||
attributes: props.attributes,
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
pub fn ContextMenuItem(props: ContextMenuItemProps) -> Element
|
||||
{
|
||||
rsx! {
|
||||
div {
|
||||
class: "contextMenuItem",
|
||||
onclick: move |_|{
|
||||
props.on_select.call(props.value.clone());
|
||||
},
|
||||
div {
|
||||
class: "content",
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ContextMenuNestedContent(props: ContextMenuNestedProps) -> Element
|
||||
{
|
||||
rsx! {
|
||||
{props.children}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
mod component;
|
||||
pub use component::*;
|
||||
mod props;
|
||||
pub use component::*;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[derive(Props, Clone, PartialEq)]
|
||||
pub struct ContextMenuProps
|
||||
{
|
||||
pub children: Element,
|
||||
}
|
||||
|
||||
#[derive(Props, Clone, PartialEq)]
|
||||
pub struct ContextMenuItemProps
|
||||
{
|
||||
pub value: String,
|
||||
pub on_select: EventHandler<String>,
|
||||
pub children: Element,
|
||||
}
|
||||
|
||||
#[derive(Props, Clone, PartialEq)]
|
||||
pub struct ContextMenuTriggerProps
|
||||
{
|
||||
pub children: Element,
|
||||
}
|
||||
|
||||
#[derive(Props, Clone, PartialEq)]
|
||||
pub struct ContextMenuContentProps
|
||||
{
|
||||
pub children: Element,
|
||||
}
|
||||
|
||||
#[derive(Props, Clone, PartialEq)]
|
||||
pub struct ContextMenuNestedProps
|
||||
{
|
||||
pub children: Element,
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
.context-menu-content {
|
||||
z-index: 1000;
|
||||
min-width: 220px;
|
||||
padding: 0.25rem;
|
||||
border-radius: 0.5rem;
|
||||
background: var(--dark, var(--primary-color-5))
|
||||
var(--light, var(--primary-color));
|
||||
box-shadow: inset 0 0 0 1px var(--dark, var(--primary-color-7))
|
||||
var(--light, var(--primary-color-6));
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
|
||||
.context-menu-content[data-state="closed"] {
|
||||
animation: context-menu-animate-out 150ms ease-in forwards;
|
||||
}
|
||||
|
||||
@keyframes context-menu-animate-out {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(0.95) translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu-content[data-state="open"] {
|
||||
animation: context-menu-animate-in 150ms ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes context-menu-animate-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.95) translateY(-2px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-radius: calc(0.5rem - 0.25rem);
|
||||
color: var(--secondary-color-4);
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
transition: background-color 100ms ease-out;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.context-menu-item[data-disabled="true"] {
|
||||
color: var(--secondary-color-5);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.context-menu-item:hover:not([data-disabled="true"]),
|
||||
.context-menu-item:focus-visible {
|
||||
background: var(--light, var(--primary-color-4))
|
||||
var(--dark, var(--primary-color-7));
|
||||
color: var(--light, var(--secondary-color-1))
|
||||
var(--dark, var(--secondary-color-4));
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_primitives::context_menu::{
|
||||
ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger,
|
||||
};
|
||||
use dioxus_primitives::context_menu::{ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger};
|
||||
use tonic::{Response, Status};
|
||||
use web_sys::window;
|
||||
|
||||
@@ -13,13 +11,15 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
pub struct MediaClassChangeEvent {
|
||||
pub struct MediaClassChangeEvent
|
||||
{
|
||||
pub index: usize,
|
||||
pub class: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Props)]
|
||||
pub struct MediaItemProps {
|
||||
pub struct MediaItemProps
|
||||
{
|
||||
pub item: MediaModel,
|
||||
pub index: usize,
|
||||
pub on_class_changed: Option<EventHandler<MediaClassChangeEvent>>,
|
||||
@@ -27,14 +27,16 @@ pub struct MediaItemProps {
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn MediaItem(props: MediaItemProps) -> Element {
|
||||
pub fn MediaItem(props: MediaItemProps) -> Element
|
||||
{
|
||||
let item = props.item;
|
||||
let mtype = item.media_type().as_str_name();
|
||||
let filename = item.file_name;
|
||||
let id = item.id.unwrap().value;
|
||||
let thumb = item.thumb_url;
|
||||
let class = item.class;
|
||||
let mut class_signal = use_signal(|| match class {
|
||||
let mut class_signal = use_signal(|| match class
|
||||
{
|
||||
1 => "blur",
|
||||
2 => "secret",
|
||||
_ => "",
|
||||
@@ -42,13 +44,6 @@ pub fn MediaItem(props: MediaItemProps) -> Element {
|
||||
let url = item.media_url;
|
||||
let download = format!("{HOST}{url}");
|
||||
|
||||
// class_signal.set(match class
|
||||
// {
|
||||
// 1 => "blur",
|
||||
// 2 => "secret",
|
||||
// _ => "",
|
||||
// });
|
||||
|
||||
return rsx! {
|
||||
ContextMenu{
|
||||
ContextMenuTrigger{
|
||||
@@ -181,7 +176,8 @@ pub fn MediaItem(props: MediaItemProps) -> Element {
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn MediaItemPlaceHolder() -> Element {
|
||||
pub fn MediaItemPlaceHolder() -> Element
|
||||
{
|
||||
return rsx! {
|
||||
div { class: "mediaItem placeholder",
|
||||
img { },
|
||||
@@ -196,7 +192,8 @@ pub fn MediaItemPlaceHolder() -> Element {
|
||||
};
|
||||
}
|
||||
|
||||
async fn set_class(id: String, class: i32) -> Result<Response<()>, Status> {
|
||||
async fn set_class(id: String, class: i32) -> Result<Response<()>, Status>
|
||||
{
|
||||
let mut client = get_rpc_client();
|
||||
return client
|
||||
.set_media_class(SetMediaClassRequest {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pub mod basic;
|
||||
// mod context_menu;
|
||||
mod context_menu;
|
||||
mod icons;
|
||||
mod media_grid;
|
||||
mod media_item;
|
||||
@@ -9,7 +9,7 @@ mod notif;
|
||||
mod pagination;
|
||||
mod passkey;
|
||||
mod search;
|
||||
// pub use context_menu::*;
|
||||
pub use context_menu::*;
|
||||
pub use media_grid::*;
|
||||
pub use media_item::*;
|
||||
pub use metrics_token::*;
|
||||
@@ -18,4 +18,4 @@ pub use notif::*;
|
||||
pub use pagination::*;
|
||||
pub use passkey::*;
|
||||
pub use search::*;
|
||||
pub mod radio_group;
|
||||
pub mod radio_group;
|
||||
|
||||
Reference in New Issue
Block a user