This repository has been archived by the owner on Aug 21, 2023. It is now read-only.
/
Dropdown.Trigger.tsx
165 lines (142 loc) · 3.72 KB
/
Dropdown.Trigger.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import * as React from 'react'
import getValidProps from '@helpscout/react-utils/dist/getValidProps'
import { connect } from '@helpscout/wedux'
import { toggleOpen, openDropdown, closeDropdown } from './Dropdown.actions'
import propConnect from '../../PropProvider/propConnect'
import { TriggerUI } from './Dropdown.css.js'
import Keys from '../../../constants/Keys'
import { classNames } from '../../../utilities/classNames'
import {
namespaceComponent,
renderRenderPropComponent,
} from '../../../utilities/component'
import { noop } from '../../../utilities/other'
import { COMPONENT_KEY } from './Dropdown.utils'
export interface Props {
children?: any
className?: string
closeDropdown: () => void
disabled: boolean
innerRef: (node: HTMLElement) => void
id?: string
isOpen: boolean
onBlur: (event: Event) => void
onFocus: (event: Event) => void
onKeyDown: (event: KeyboardEvent) => void
onClick: (event: Event) => void
openDropdown: () => void
style: any
toggleOpen: () => void
}
export class Trigger extends React.PureComponent<Props> {
static defaultProps = {
disabled: false,
innerRef: noop,
isOpen: false,
onBlur: noop,
onFocus: noop,
onKeyDown: noop,
onClick: noop,
openDropdown: noop,
closeDropdown: noop,
style: {},
toggleOpen: noop,
}
state = { isHovered: false }
handleOnClick = (event: Event) => {
this.props.onClick(event)
this.props.toggleOpen()
}
handleOnKeyDown = (event: KeyboardEvent) => {
switch (event.keyCode) {
case Keys.DOWN_ARROW:
this.openDropdown(event)
break
case Keys.ENTER:
this.openDropdown(event)
break
case Keys.TAB:
if (event.shiftKey) {
this.closeDropdown()
}
break
default:
break
}
this.props.onKeyDown(event)
}
openDropdown(event) {
const { isOpen, openDropdown } = this.props
if (!isOpen) {
event.preventDefault()
return openDropdown()
}
}
closeDropdown() {
const { isOpen, closeDropdown } = this.props
if (isOpen) {
return closeDropdown()
}
}
renderChildren() {
const { children } = this.props
const { isHovered } = this.state
const renderedChildren = renderRenderPropComponent(children, { isHovered })
return renderedChildren ? renderedChildren : children
}
render() {
const {
className,
disabled,
onBlur,
onFocus,
innerRef,
isOpen,
...rest
} = this.props
const componentClassName = classNames(
className,
isOpen && 'is-open',
disabled && 'is-disabled',
'c-DropdownV2Trigger'
)
return (
<TriggerUI
role="button"
{...getValidProps(rest)}
aria-haspopup="listbox"
aria-expanded={isOpen}
className={componentClassName}
disabled={disabled}
innerRef={innerRef}
onBlur={onBlur}
onFocus={onFocus}
onClick={this.handleOnClick}
onKeyDown={this.handleOnKeyDown}
onMouseOver={() => this.setState({ isHovered: true })}
onMouseLeave={() => this.setState({ isHovered: false })}
>
{this.renderChildren()}
</TriggerUI>
)
}
}
namespaceComponent(COMPONENT_KEY.Trigger)(Trigger)
const PropConnectedTrigger = propConnect(COMPONENT_KEY.Trigger)(Trigger)
export const mapStateToProps = (state: any) => {
const { isOpen, triggerId, triggerProps, triggerStyle } = state
return { ...triggerProps, isOpen, id: triggerId, style: triggerStyle }
}
const ConnectedTrigger: any = connect(
mapStateToProps,
// mapDispatchToProps
{
toggleOpen,
openDropdown,
closeDropdown,
}
)(
// @ts-ignore
PropConnectedTrigger
)
export default ConnectedTrigger