Skip to content

Commit

Permalink
Fix an issue with context menus appearing below content in the rundow…
Browse files Browse the repository at this point in the history
…n and allow single types to render as their own categories

Signed-off-by: Axel Boberg <[email protected]>
  • Loading branch information
axelboberg committed Jan 22, 2024
1 parent 458b85d commit 363224d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 10 deletions.
39 changes: 36 additions & 3 deletions app/components/ContextMenu/index.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
import React from 'react'
import { createPortal } from 'react-dom'

import './style.css'

/**
* A threshold for how long the context menu has
* to have been open before an event can close it
*
* This it to prevent the same event to
* both open and close a context menu
*
* @type { Number }
*/
const OPEN_THRESHOLD_MS = 100

export const ContextMenu = ({ x, y, children, onClose = () => {} }) => {
const elRef = React.useRef()
const openTimestampRef = React.useRef()

React.useEffect(() => {
openTimestampRef.current = Date.now()
}, [])

React.useEffect(() => {
function closeContext () {
/*
Check how long the context menu has been opened
to prevent it from closing on the same event that
opened it
*/
if (Date.now() - openTimestampRef.current <= OPEN_THRESHOLD_MS) {
return
}
onClose()
}

Expand All @@ -20,8 +46,15 @@ export const ContextMenu = ({ x, y, children, onClose = () => {} }) => {
}, [onClose])

return (
<div ref={elRef} className='ContextMenu u-theme--light' style={{ top: y, left: x }}>
{children}
</div>
<>
{
createPortal(
<div ref={elRef} className='ContextMenu u-theme--light' style={{ top: y, left: x }}>
{children}
</div>,
document.body
)
}
</>
)
}
21 changes: 18 additions & 3 deletions app/components/ContextMenu/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,25 @@
color: black;

border-radius: 5px;
overflow: hidden;


box-sizing: border-box;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);


margin-top: -3px;

animation-name: context-menu-in;
animation-duration: 200ms;
animation-fill-mode: forwards;

overflow: hidden;
z-index: 100;
}

@keyframes context-menu-in {
0% {
margin-top: -3px;
}
100% {
margin-top: 0;
}
}
2 changes: 1 addition & 1 deletion app/components/ContextMenuItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const CTX_MENU_OFFSET_Y_PX = 5
* mouse leaves the current item
* @type { Number }
*/
const MOUSE_LEAVE_DELAY_MS = 200
const MOUSE_LEAVE_DELAY_MS = 150

export const ContextMenuItem = ({ text, children = [], onClick = () => {} }) => {
const elRef = React.useRef()
Expand Down
24 changes: 21 additions & 3 deletions plugins/rundown/app/components/ContextAddMenu/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { SharedContext } from '../../sharedContext'

import { ContextMenuItem } from '../../../../../app/components/ContextMenuItem'

const NO_CATEGORY_ID = '__none__'

export function ContextAddMenu ({ onAdd = () => {} }) {
const [shared] = React.useContext(SharedContext)

Expand All @@ -28,7 +30,7 @@ export function ContextAddMenu ({ onAdd = () => {} }) {
if (!type.name) {
continue
}
const categoryName = type.category || type.id
const categoryName = type.category || NO_CATEGORY_ID
if (!out[categoryName]) {
out[categoryName] = []
}
Expand All @@ -41,10 +43,26 @@ export function ContextAddMenu ({ onAdd = () => {} }) {
<>
{
Object.entries(categories || {})
/*
Make sure items that don't belong to
a category are rendered first
*/
.sort((a) => a[0] === NO_CATEGORY_ID ? -1 : 1)
.map(([id, category]) => {
if (category.length === 1) {
return <ContextMenuItem key={category[0].id} text={category[0].name} onClick={() => handleClick(category[0].id)} />
/*
Render single items that don't
belong to any specific category
*/
if (id === NO_CATEGORY_ID) {
return category.map(type =>
<ContextMenuItem key={type.id} text={type.name} onClick={() => handleClick(type.id)} />
)
}

/*
Render categories
as nested menus
*/
return (
<ContextMenuItem key={id} text={id}>
{
Expand Down

0 comments on commit 363224d

Please sign in to comment.