-
-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathItem.tsx
More file actions
77 lines (71 loc) · 1.96 KB
/
Item.tsx
File metadata and controls
77 lines (71 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import * as React from 'react'
import styled, { css } from 'styled-components'
import { useDebounce } from '../hooks'
import { CommonStyle } from '../styles'
import { Customize, Item } from '../types'
import { $width } from '../vars'
export const ItemStyle = styled(CommonStyle) <{ hasSubitems?: boolean }>`
${props => props.hasSubitems && css`&:after {
content: '►';
position: absolute;
opacity: 0.6;
right: 5px;
top: 5px;
}`}
`
export const SubitemStyles = styled.div`
position: absolute;
top: 0;
left: 100%;
width: ${$width}px;
`
type Props = {
data: Item
delay: number
hide(): void
children: React.ReactNode
components?: Pick<Customize, 'item' | 'subitems'>
}
export function ItemElement(props: Props) {
const [visibleSubitems, setVisibleSubitems] = React.useState(false)
const setInvisibile = React.useCallback(() => {
setVisibleSubitems(false)
}, [setVisibleSubitems])
const [hide, cancelHide] = useDebounce(setInvisibile, props.delay)
const Component = props.components?.item?.(props.data) || ItemStyle
const Subitems = props.components?.subitems?.(props.data) || SubitemStyles
return <Component
onClick={(e: React.MouseEvent) => {
e.stopPropagation()
props.data.handler()
props.hide()
}}
hasSubitems={Boolean(props.data.subitems)}
onPointerDown={(e: React.PointerEvent) => {
e.stopPropagation()
}}
onPointerOver={() => {
cancelHide()
setVisibleSubitems(true)
}}
onPointerLeave={() => {
if (hide) hide()
}}
data-testid="context-menu-item"
>
{props.children}
{props.data.subitems && visibleSubitems && (
<Subitems>
{props.data.subitems.map(item => (
<ItemElement
key={item.key}
data={item}
delay={props.delay}
hide={props.hide}
components={props.components}
>{item.label}</ItemElement>
))}
</Subitems>
)}
</Component>
}