-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[dashboard] improved workspaces #3457
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { useState } from 'react'; | ||
|
||
export interface ContextMenuProps { | ||
children: React.ReactChild[] | React.ReactChild; | ||
menuEntries: ContextMenuEntry[]; | ||
} | ||
|
||
export interface ContextMenuEntry { | ||
title: string; | ||
active?: boolean; | ||
/** | ||
* whether a separator line should be rendered below this item | ||
*/ | ||
separator?: boolean; | ||
customFontStyle?: string; | ||
onClick?: ()=>void; | ||
href?: string; | ||
} | ||
|
||
function ContextMenu(props: ContextMenuProps) { | ||
const [expanded, setExpanded] = useState(false); | ||
const toggleExpanded = () => { | ||
setExpanded(!expanded); | ||
} | ||
|
||
if (expanded) { | ||
// HACK! I want to skip the bubbling phase of the current click | ||
setTimeout(() => { | ||
window.addEventListener('click', () => setExpanded(false), { once: true }); | ||
}, 0); | ||
} | ||
|
||
const enhancedEntries = props.menuEntries.map(e => { | ||
return { | ||
... e, | ||
onClick: () => { | ||
e.onClick && e.onClick(); | ||
toggleExpanded(); | ||
} | ||
} | ||
}) | ||
const font = "text-gray-400 hover:text-gray-800" | ||
return ( | ||
<div className="relative cursor-pointer"> | ||
<div onClick={(e) => { | ||
toggleExpanded(); | ||
e.preventDefault(); | ||
}}> | ||
{props.children} | ||
</div> | ||
{expanded? | ||
<div className={`z-50 w-40 bg-white absolute py-2 right-0 flex flex-col border border-gray-200 rounded-lg space-y-2`}> | ||
{enhancedEntries.map(e => { | ||
const entry = <div key={e.title} className={`px-4 flex py-2 text-gray-600 hover:bg-gray-200 text-sm leading-1 ${e.customFontStyle || font} ${e.separator? ' border-b border-gray-200':''}`} > | ||
<div>{e.title}</div><div className="flex-1"></div>{e.active ? <div className="pl-1 font-semibold">✓</div>: null} | ||
</div> | ||
return <a href={e.href} onClick={e.onClick}> | ||
{entry} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. quesrtion: Also, could we change the text and dropdown arrow icon color to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you clarify, I think it is already gray-600 without hover. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember seeing the status filter dropdown label and arrow using the same color on hover. Ideally both the label and the icon arrow would use |
||
</a> | ||
})} | ||
</div> | ||
: | ||
null | ||
} | ||
</div> | ||
); | ||
} | ||
|
||
export default ContextMenu; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { useState } from 'react'; | ||
import ContextMenu from './ContextMenu'; | ||
|
||
export interface DropDownProps { | ||
entries: { | ||
title: string, | ||
onClick: ()=>void | ||
}[]; | ||
} | ||
|
||
function Arrow(props: {up: boolean}) { | ||
return <span className="mx-2 border-gray-400" style={{ margin: 2, padding: 3, border: 'solid black', borderWidth: '0 2px 2px 0', display: 'inline-block', transform: `rotate(${props.up ? '-135deg' : '45deg'})`}}></span> | ||
} | ||
|
||
function DropDown(props: DropDownProps) { | ||
const [current, setCurrent] = useState(props.entries[0].title); | ||
const enhancedEntries = props.entries.map(e => { | ||
return { | ||
...e, | ||
active: e.title === current, | ||
onClick: () => { | ||
e.onClick(); | ||
setCurrent(e.title); | ||
} | ||
} | ||
}) | ||
const font = "text-gray-400 text-sm leading-1" | ||
return ( | ||
<ContextMenu menuEntries={enhancedEntries}> | ||
<span className={`py-2 cursor-pointer ${font}`}>{current}<Arrow up={false}/></span> | ||
</ContextMenu> | ||
); | ||
} | ||
|
||
export default DropDown; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
export default function Separator() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this component really necessary? |
||
return <div className="bg-gray-200 h-0.5 absolute left-0 w-screen"></div>; | ||
return <div className="border-gray-200 border-b h-0.5 absolute left-0 w-screen"></div>; | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it would be great to find an alternative to format relative time. this is quite a balloon in the resulting bundle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's used just to format relative time, maybe it's good to use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat, and there is a polyfill available, too.