-
Notifications
You must be signed in to change notification settings - Fork 331
/
Copy pathpopover.tsx
107 lines (99 loc) · 2.87 KB
/
popover.tsx
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React, { useEffect, useMemo, useState } from 'react'
import Tooltip, {
TooltipOnVisibleChange,
TooltipProps,
TooltipTypes,
} from '../tooltip/tooltip'
import { Placement, TriggerTypes } from '../utils/prop-types'
import { getReactNode } from '../utils/collections'
import useScale, { withScale } from '../use-scale'
import { PopoverContext, PopoverConfig } from './popover-context'
import useClasses from '../use-classes'
export type PopoverTriggerTypes = TriggerTypes
export type PopoverPlacement = Placement
interface Props {
content?: React.ReactNode | (() => React.ReactNode)
trigger?: PopoverTriggerTypes
placement?: Placement
disableItemsAutoClose?: boolean
}
const defaultProps = {
disableItemsAutoClose: false,
trigger: 'click' as PopoverTriggerTypes,
placement: 'bottom' as Placement,
portalClassName: '',
initialVisible: false,
hideArrow: false,
type: 'default' as TooltipTypes,
enterDelay: 100,
leaveDelay: 150,
offset: 12,
className: '',
onVisibleChange: (() => {}) as TooltipOnVisibleChange,
}
type ExcludeTooltipProps = {
type: any
text: any
trigger: any
placement: any
}
export type PopoverProps = Props & Omit<TooltipProps, keyof ExcludeTooltipProps>
const PopoverComponent: React.FC<React.PropsWithChildren<PopoverProps>> = ({
content,
children,
trigger,
placement,
initialVisible,
portalClassName,
disableItemsAutoClose,
onVisibleChange,
visible: customVisible,
...props
}: React.PropsWithChildren<PopoverProps> & typeof defaultProps) => {
const { SCALES } = useScale()
const [visible, setVisible] = useState<boolean>(initialVisible)
const textNode = useMemo(() => getReactNode(content), [content])
const onChildClick = () => {
onPopoverVisibleChange(false)
}
const value = useMemo<PopoverConfig>(
() => ({
onItemClick: onChildClick,
disableItemsAutoClose,
}),
[disableItemsAutoClose],
)
const classes = useClasses('popover', portalClassName)
const onPopoverVisibleChange = (next: boolean) => {
setVisible(next)
onVisibleChange(next)
}
useEffect(() => {
if (customVisible === undefined) return
onPopoverVisibleChange(customVisible)
}, [customVisible])
return (
<PopoverContext.Provider value={value}>
<Tooltip
text={textNode}
trigger={trigger}
placement={placement}
portalClassName={classes}
visible={visible}
onVisibleChange={onPopoverVisibleChange}
{...props}
>
{children}
<style jsx>{`
:global(.tooltip-content.popover > .inner) {
padding: ${SCALES.pt(0.9)} ${SCALES.pr(0)} ${SCALES.pb(0.9)} ${SCALES.pl(0)};
}
`}</style>
</Tooltip>
</PopoverContext.Provider>
)
}
PopoverComponent.defaultProps = defaultProps
PopoverComponent.displayName = 'GeistPopover'
const Popover = withScale(PopoverComponent)
export default Popover