feat(adminui): T0-1 reusable ContextMenu component + demo page
Adds a reusable right-click / context menu Blazor component for the AdminUI: - ContextMenu.razor: right-click surface (browser menu suppressed) + optional ellipsis fallback trigger, both anchoring the menu at the pointer; keyboard nav (arrows/Enter/Esc), transparent backdrop outside-click close (no JS). - ContextMenu.razor.css: scoped styles on the shared theme tokens. - ContextMenuItem.cs: Label/OnClick/Icon/Disabled/IsSeparator model + Separator(). - Dev demo page at /dev/context-menu-demo. Claude-Session: https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/* Scoped styles for ContextMenu. Colours come from the shared ZB.MOM.WW.Theme
|
||||
tokens (theme.css) so the menu tracks the app palette in light and dark. */
|
||||
|
||||
.ctx-surface {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* The "⋯" fallback trigger — a compact, quiet icon button. */
|
||||
.ctx-ellipsis {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
padding: 0;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0.375rem;
|
||||
background: transparent;
|
||||
color: var(--ink-soft);
|
||||
font-size: 1.1rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ctx-ellipsis:hover,
|
||||
.ctx-ellipsis[aria-expanded="true"] {
|
||||
background: var(--hover-bg);
|
||||
border-color: var(--bs-border-color);
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
/* Transparent full-viewport catch-all; sits just under the menu. */
|
||||
.ctx-backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1080;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.ctx-menu {
|
||||
position: fixed;
|
||||
z-index: 1081; /* above the backdrop, below toasts (1090) */
|
||||
min-width: 11rem;
|
||||
max-width: 20rem;
|
||||
padding: 0.25rem;
|
||||
background: var(--card);
|
||||
border: 1px solid var(--bs-border-color);
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.16);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ctx-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
padding: 0.35rem 0.6rem;
|
||||
border: 0;
|
||||
border-radius: 0.375rem;
|
||||
background: transparent;
|
||||
color: var(--ink);
|
||||
font-size: 0.875rem;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ctx-item:hover:not(:disabled),
|
||||
.ctx-item.active:not(:disabled) {
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
.ctx-item:disabled {
|
||||
color: var(--ink-faint);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.ctx-icon {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
width: 1.1rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ctx-label {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.ctx-separator {
|
||||
height: 1px;
|
||||
margin: 0.25rem 0.3rem;
|
||||
background: var(--bs-border-color);
|
||||
}
|
||||
Reference in New Issue
Block a user