react-animated-select 0.2.9 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -29
- package/demo/README.md +16 -0
- package/demo/eslint.config.js +29 -0
- package/demo/index.html +13 -0
- package/demo/package-lock.json +3436 -0
- package/demo/package.json +38 -0
- package/demo/public/vite.svg +1 -0
- package/demo/src/App.tsx +425 -0
- package/demo/src/main.jsx +9 -0
- package/demo/src/rac.css +735 -0
- package/demo/src/shake.js +11 -0
- package/demo/src/slideDown.jsx +35 -0
- package/demo/vite.config.js +7 -0
- package/dist/index.cjs.js +6 -9
- package/dist/index.css +1 -1
- package/dist/index.es.js +926 -687
- package/index.d.ts +20 -2
- package/package.json +3 -2
- package/src/index.js +1 -0
- package/src/optgroup.jsx +36 -0
- package/src/option.jsx +31 -11
- package/src/options.jsx +11 -11
- package/src/select.css +45 -1
- package/src/select.jsx +209 -238
- package/src/selectContext.js +1 -1
- package/src/selectJSX.jsx +148 -0
- package/src/slideDown.jsx +36 -0
- package/src/useSelect.jsx +113 -79
- package/src/useSelectLogic.jsx +215 -131
package/src/select.jsx
CHANGED
|
@@ -1,34 +1,44 @@
|
|
|
1
1
|
import './select.css'
|
|
2
|
-
|
|
3
2
|
import {XMarkIcon, ArrowUpIcon} from './icons'
|
|
4
3
|
import {forwardRef, useImperativeHandle, useRef, useMemo, useState, useEffect, useCallback, useId, isValidElement, cloneElement} from 'react'
|
|
4
|
+
import {makeId} from './makeId'
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import SelectJSX from './selectJSX'
|
|
7
7
|
import useSelect from './useSelect'
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import Options from './options'
|
|
8
|
+
import useSelectLogic from './useSelectLogic'
|
|
9
|
+
import SlideDown from './slideDown'
|
|
11
10
|
import SlideLeft from './slideLeft'
|
|
12
11
|
|
|
12
|
+
// universal icon display
|
|
13
13
|
const renderIcon = (Icon, defaultProps) => {
|
|
14
14
|
if (!Icon) return null
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
return <img src={Icon} {...defaultProps} alt='' />
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (isValidElement(Icon)) {
|
|
21
|
-
return cloneElement(Icon, defaultProps)
|
|
22
|
-
}
|
|
23
|
-
|
|
15
|
+
if (typeof Icon === 'string') return <img src={Icon} {...defaultProps} alt=''/>
|
|
16
|
+
if (isValidElement(Icon)) return cloneElement(Icon, defaultProps)
|
|
24
17
|
if (typeof Icon === 'function' || (typeof Icon === 'object' && Icon.$$typeof)) {
|
|
25
18
|
const IconComponent = Icon
|
|
26
|
-
return <IconComponent {...defaultProps}
|
|
19
|
+
return <IconComponent {...defaultProps}/>
|
|
27
20
|
}
|
|
28
|
-
|
|
29
21
|
return null
|
|
30
22
|
}
|
|
31
23
|
|
|
24
|
+
// adding classes to style options according to their state
|
|
25
|
+
const getOptionClassName = (element, index, highlightedIndex, selectedId, loadingTitle, loadMoreText, invalidOption) => {
|
|
26
|
+
if (element.groupHeader) {
|
|
27
|
+
return 'rac-select-option rac-group-option'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return [
|
|
31
|
+
'rac-select-option',
|
|
32
|
+
element.className,
|
|
33
|
+
selectedId === element.id && 'rac-selected',
|
|
34
|
+
index === highlightedIndex && 'rac-highlighted',
|
|
35
|
+
(element.disabled || element.loading) && 'rac-disabled-option',
|
|
36
|
+
(element.invalid || element.name === invalidOption) && 'rac-invalid-option',
|
|
37
|
+
(element.loadMore && loadingTitle === loadMoreText) && 'rac-loading-option',
|
|
38
|
+
typeof element.raw === 'boolean' && (element.raw ? 'rac-true-option' : 'rac-false-option')
|
|
39
|
+
].filter(Boolean).join(' ')
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
const Select = forwardRef(({
|
|
33
43
|
unmount,
|
|
34
44
|
children,
|
|
@@ -44,294 +54,255 @@ const Select = forwardRef(({
|
|
|
44
54
|
className = '',
|
|
45
55
|
ArrowIcon = ArrowUpIcon,
|
|
46
56
|
ClearIcon = XMarkIcon,
|
|
57
|
+
hasMore = false,
|
|
58
|
+
loadMore = () => {console.warn('loadMore not implemented')},
|
|
59
|
+
loadButton = false,
|
|
60
|
+
loadButtonText = 'Load more',
|
|
61
|
+
loadMoreText = 'Loading',
|
|
62
|
+
loadOffset = 100,
|
|
63
|
+
loadAhead = 3,
|
|
64
|
+
childrenFirst = false,
|
|
47
65
|
...props
|
|
48
66
|
}, ref) => {
|
|
49
67
|
|
|
50
68
|
const reactId = useId()
|
|
51
|
-
|
|
52
69
|
const selectId = useMemo(() => reactId.replace(/:/g, ''), [reactId])
|
|
53
|
-
|
|
54
70
|
const [jsxOptions, setJsxOptions] = useState([])
|
|
71
|
+
const [internalVisibility, setInternalVisibility] = useState(false)
|
|
72
|
+
const [loadingTitle, setLoadingTitle] = useState(loadButton ? loadButtonText : loadMoreText)
|
|
73
|
+
const [animationFinished, setAnimationFinished] = useState(false)
|
|
74
|
+
const selectRef = useRef(null)
|
|
75
|
+
|
|
55
76
|
|
|
56
77
|
const registerOption = useCallback((opt) => {
|
|
57
|
-
|
|
78
|
+
setJsxOptions(prev => {
|
|
79
|
+
const index = prev.findIndex(o => o.id === opt.id)
|
|
80
|
+
if (index !== -1) {
|
|
81
|
+
const existing = prev[index]
|
|
82
|
+
if (
|
|
83
|
+
existing.label === opt.label &&
|
|
84
|
+
existing.value === opt.value &&
|
|
85
|
+
existing.disabled === opt.disabled &&
|
|
86
|
+
existing.group === opt.group
|
|
87
|
+
) {
|
|
88
|
+
return prev
|
|
89
|
+
}
|
|
90
|
+
const next = [...prev]
|
|
91
|
+
next[index] = opt
|
|
92
|
+
return next
|
|
93
|
+
}
|
|
94
|
+
return [...prev, opt]
|
|
95
|
+
})
|
|
58
96
|
}, [])
|
|
59
97
|
|
|
60
98
|
const unregisterOption = useCallback((id) => {
|
|
61
|
-
setJsxOptions(prev =>
|
|
99
|
+
setJsxOptions(prev => {
|
|
100
|
+
const filtered = prev.filter(o => o.id !== id)
|
|
101
|
+
return filtered.length === prev.length ? prev : filtered
|
|
102
|
+
})
|
|
62
103
|
}, [])
|
|
63
104
|
|
|
64
|
-
//
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
if (!ref) return
|
|
69
|
-
if (typeof ref === 'function') {
|
|
70
|
-
ref(selectRef.current)
|
|
71
|
-
} else {
|
|
72
|
-
ref.current = selectRef.current
|
|
73
|
-
}
|
|
74
|
-
}, [ref])
|
|
75
|
-
|
|
76
|
-
useImperativeHandle(ref, () => selectRef.current)
|
|
77
|
-
|
|
78
|
-
// open/closed status select
|
|
79
|
-
const [internalVisibility, setInternalVisibility] = useState(false)
|
|
80
|
-
|
|
81
|
-
const visibility = useMemo(() => {
|
|
82
|
-
if (alwaysOpen) return true
|
|
83
|
-
if (ownBehavior) return !!externalVisibility
|
|
84
|
-
|
|
85
|
-
return internalVisibility
|
|
86
|
-
}, [alwaysOpen, ownBehavior, externalVisibility, internalVisibility])
|
|
87
|
-
|
|
105
|
+
// select visibility control
|
|
106
|
+
const visibility = alwaysOpen ? true : (ownBehavior ? !!externalVisibility : internalVisibility)
|
|
107
|
+
|
|
88
108
|
const setVisibility = useCallback((newState) => {
|
|
89
|
-
if (alwaysOpen) return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
setInternalVisibility(prev => {
|
|
93
|
-
const next = typeof newState === 'function' ? newState(prev) : newState
|
|
94
|
-
return next
|
|
95
|
-
})
|
|
109
|
+
if (alwaysOpen || ownBehavior) return
|
|
110
|
+
setInternalVisibility(newState)
|
|
96
111
|
}, [alwaysOpen, ownBehavior])
|
|
97
112
|
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const {handleBlur, handleFocus, handleToggle, handleKeyDown, highlightedIndex, setHighlightedIndex} = useSelect({
|
|
102
|
-
disabled,
|
|
103
|
-
isOpen: visibility,
|
|
104
|
-
setIsOpen: setVisibility,
|
|
105
|
-
options: normalizedOptions,
|
|
106
|
-
selectOption: selectOption,
|
|
107
|
-
selected: selected
|
|
113
|
+
const logic = useSelectLogic({
|
|
114
|
+
...props, visibility, setVisibility, jsxOptions, hasMore,
|
|
115
|
+
loadButton, loadingTitle, loadMore, loadMoreText, setLoadingTitle, childrenFirst
|
|
108
116
|
})
|
|
109
117
|
|
|
110
|
-
const
|
|
118
|
+
const {normalizedOptions, selected, selectOption, clear, hasOptions, active, selectedValue, disabled, loading, error, placeholder, invalidOption, emptyText, disabledText, loadingText, errorText, expandedGroups} = logic
|
|
119
|
+
|
|
120
|
+
const behavior = useSelect({setLoadingTitle, loadButton, loadButtonText, hasMore, loadMore, disabled, open: visibility, setOpen: setVisibility, options: normalizedOptions, selectOption, selected, loadOffset, loadAhead})
|
|
121
|
+
|
|
122
|
+
const {handleListScroll, handleBlur, handleFocus, handleToggle, handleKeyDown, highlightedIndex, setHighlightedIndex} = behavior
|
|
123
|
+
|
|
124
|
+
useImperativeHandle(ref, () => selectRef.current)
|
|
111
125
|
|
|
112
126
|
useEffect(() => {
|
|
113
|
-
if (!visibility)
|
|
114
|
-
setAnimationFinished(false)
|
|
115
|
-
}
|
|
127
|
+
if (!visibility) setAnimationFinished(false)
|
|
116
128
|
}, [visibility])
|
|
117
129
|
|
|
118
130
|
useEffect(() => {
|
|
119
|
-
if (error || disabled || loading || !hasOptions)
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
}, [error, disabled, loading, hasOptions])
|
|
131
|
+
if (error || disabled || loading || !hasOptions) setVisibility(false)
|
|
132
|
+
}, [error, disabled, loading, hasOptions, setVisibility])
|
|
123
133
|
|
|
124
134
|
useEffect(() => {
|
|
125
135
|
if (visibility && animationFinished && highlightedIndex !== -1) {
|
|
126
|
-
|
|
127
136
|
const option = normalizedOptions[highlightedIndex]
|
|
128
137
|
if (option) {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (domElement) {
|
|
133
|
-
domElement.scrollIntoView({block: 'nearest'})
|
|
134
|
-
}
|
|
138
|
+
const domElement = document.getElementById(`opt-${selectId}-${makeId(option.id)}`)
|
|
139
|
+
domElement?.scrollIntoView({ block: 'nearest' })
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
}, [highlightedIndex, visibility, animationFinished, normalizedOptions, selectId])
|
|
138
143
|
|
|
139
|
-
const hasActualValue =
|
|
144
|
+
const hasActualValue = useMemo(() => (
|
|
140
145
|
selectedValue !== undefined &&
|
|
141
146
|
selectedValue !== null &&
|
|
142
147
|
!(Array.isArray(selectedValue) && selectedValue.length === 0) &&
|
|
143
148
|
!(typeof selectedValue === 'object' && Object.keys(selectedValue).length === 0)
|
|
149
|
+
), [selectedValue])
|
|
144
150
|
|
|
145
|
-
// displaying title according to state of select
|
|
146
151
|
const title = useMemo(() => {
|
|
147
152
|
if (error) return errorText
|
|
148
153
|
if (loading) return loadingText
|
|
149
154
|
if (disabled) return disabledText
|
|
150
|
-
|
|
151
155
|
if (selected) return selected.jsx ?? selected.name
|
|
152
156
|
|
|
153
157
|
if (hasActualValue) {
|
|
154
158
|
const recovered = normalizedOptions.find(o => o.raw === selectedValue)
|
|
155
159
|
if (recovered) return recovered.name
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
return String(selectedValue)
|
|
160
|
+
return (typeof selectedValue === 'object' && selectedValue !== null)
|
|
161
|
+
? (selectedValue.name ?? selectedValue.label ?? 'Selected Object')
|
|
162
|
+
: String(selectedValue)
|
|
161
163
|
}
|
|
164
|
+
return hasOptions ? placeholder : emptyText
|
|
165
|
+
}, [disabled, loading, error, hasOptions, selected, selectedValue, placeholder, errorText, loadingText, disabledText, emptyText, hasActualValue, normalizedOptions])
|
|
162
166
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const listboxId = `${selectId}-listbox`
|
|
167
|
+
const renderOptions = useMemo(() => {
|
|
168
|
+
const nodes = []
|
|
169
|
+
let currentGroupChildren = []
|
|
170
|
+
let currentGroupName = null
|
|
169
171
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (selected?.id === element.id) optionClass += ' rac-selected'
|
|
178
|
-
|
|
179
|
-
if (index === highlightedIndex) optionClass += ' rac-highlighted'
|
|
180
|
-
|
|
181
|
-
if (element.disabled) optionClass += ' rac-disabled-option'
|
|
182
|
-
|
|
183
|
-
if (element.isInvalid) optionClass += ' rac-invalid-option'
|
|
184
|
-
|
|
185
|
-
if (typeof element.raw === 'boolean') {
|
|
186
|
-
optionClass += element.raw ? ' rac-true-option' : ' rac-false-option'
|
|
187
|
-
}
|
|
172
|
+
const groupCounts = normalizedOptions.reduce((acc, opt) => {
|
|
173
|
+
if (opt.group) {
|
|
174
|
+
acc[opt.group] = (acc[opt.group] || 0) + 1
|
|
175
|
+
}
|
|
176
|
+
return acc
|
|
177
|
+
}, {})
|
|
188
178
|
|
|
189
|
-
|
|
190
|
-
|
|
179
|
+
const flushGroup = (name) => {
|
|
180
|
+
if (name === null || currentGroupChildren.length === 0) return
|
|
181
|
+
|
|
182
|
+
nodes.push(
|
|
183
|
+
<SlideDown
|
|
184
|
+
key={`slide-${name}`}
|
|
185
|
+
visibility={expandedGroups.has(name)}
|
|
186
|
+
>
|
|
187
|
+
{currentGroupChildren}
|
|
188
|
+
</SlideDown>
|
|
189
|
+
)
|
|
190
|
+
currentGroupChildren = []
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
const createOptionNode = (element, index) => (
|
|
194
194
|
<div
|
|
195
|
-
className={optionClass}
|
|
196
|
-
onClick={(e) => selectOption(element, e)}
|
|
197
|
-
onMouseEnter={() => !element.disabled && setHighlightedIndex(index)}
|
|
198
195
|
key={element.id}
|
|
199
|
-
id={
|
|
196
|
+
id={`opt-${selectId}-${makeId(element.id)}`}
|
|
200
197
|
role='option'
|
|
201
198
|
aria-selected={selected?.id === element.id}
|
|
202
|
-
aria-disabled={element.disabled}
|
|
199
|
+
aria-disabled={element.disabled || element.loading}
|
|
200
|
+
className={getOptionClassName(element, index, highlightedIndex, selected?.id, loadingTitle, loadMoreText, invalidOption)}
|
|
201
|
+
onClick={(e) => !element.loading && selectOption(element, e)}
|
|
202
|
+
onMouseEnter={() => (!element.disabled && !element.loading) && setHighlightedIndex(index)}
|
|
203
203
|
>
|
|
204
204
|
{element.jsx ?? element.name}
|
|
205
|
+
{element.loading && <span className='rac-loading-dots'><i/><i/><i/></span>}
|
|
205
206
|
</div>
|
|
206
207
|
)
|
|
207
|
-
}), [normalizedOptions, selectOption, selectId, selected, highlightedIndex])
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const receivedType = typeof options
|
|
213
|
-
if (options && typeof options !== 'object') {
|
|
214
|
-
console.error(
|
|
215
|
-
`%c[Select Library]:%c Invalid prop %coptions%c.\n` +
|
|
216
|
-
`Expected %cArray%c or %cObject%c, but received %c${receivedType}%c.\n`,
|
|
217
|
-
'color: #ff4d4f; font-weight: bold;', 'color: default;',
|
|
218
|
-
'color: #1890ff; font-weight: bold;', 'color: default;',
|
|
219
|
-
'color: #52c41a; font-weight: bold;', 'color: default;',
|
|
220
|
-
'color: #52c41a; font-weight: bold;', 'color: default;',
|
|
221
|
-
'color: #ff4d4f; font-weight: bold;', 'color: default;'
|
|
222
|
-
)
|
|
223
|
-
}
|
|
209
|
+
normalizedOptions.forEach((element, index) => {
|
|
210
|
+
const isHeader = element.groupHeader
|
|
211
|
+
const belongsToGroup = !!element.group
|
|
224
212
|
|
|
225
|
-
if (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
``,
|
|
229
|
-
'color: #faad14; font-weight: bold;', 'color: default;'
|
|
230
|
-
)
|
|
213
|
+
if (isHeader || (!belongsToGroup && currentGroupName !== null)) {
|
|
214
|
+
flushGroup(currentGroupName)
|
|
215
|
+
if (!isHeader) currentGroupName = null
|
|
231
216
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
'--rac-duration': `${duration}ms`,
|
|
244
|
-
...style
|
|
245
|
-
}}
|
|
246
|
-
className={`rac-select
|
|
247
|
-
${className}
|
|
248
|
-
${(!hasOptions || disabled) ? 'rac-disabled-style' : ''}
|
|
249
|
-
${loading ? 'rac-loading-style' : ''}
|
|
250
|
-
${error ? 'rac-error-style' : ''}`
|
|
251
|
-
}
|
|
252
|
-
tabIndex={active ? 0 : -1}
|
|
253
|
-
ref={selectRef}
|
|
254
|
-
role='combobox'
|
|
255
|
-
aria-haspopup='listbox'
|
|
256
|
-
aria-expanded={visibility}
|
|
257
|
-
aria-controls={listboxId}
|
|
258
|
-
aria-label={placeholder}
|
|
259
|
-
aria-disabled={disabled || !hasOptions}
|
|
260
|
-
{...(active && {
|
|
261
|
-
onBlur: handleBlur,
|
|
262
|
-
onFocus: handleFocus,
|
|
263
|
-
onClick: handleToggle,
|
|
264
|
-
onKeyDown: handleKeyDown
|
|
265
|
-
})}
|
|
266
|
-
>
|
|
267
|
-
<div
|
|
268
|
-
className={`rac-select-title ${(!error && !loading && selected?.type == 'boolean')
|
|
269
|
-
? selected.raw ? 'rac-true-option' : 'rac-false-option'
|
|
270
|
-
: ''
|
|
271
|
-
}`}
|
|
272
|
-
>
|
|
273
|
-
<span
|
|
274
|
-
className='rac-title-text'
|
|
275
|
-
key={title}
|
|
276
|
-
>
|
|
277
|
-
{title}
|
|
278
|
-
</span>
|
|
279
|
-
<SlideLeft
|
|
280
|
-
visibility={loading && !error}
|
|
281
|
-
duration={duration}
|
|
282
|
-
>
|
|
283
|
-
<span className='rac-loading-dots'>
|
|
284
|
-
<i/><i/><i/>
|
|
285
|
-
</span>
|
|
286
|
-
</SlideLeft>
|
|
287
|
-
</div>
|
|
288
|
-
<div
|
|
289
|
-
className='rac-select-buttons'
|
|
290
|
-
>
|
|
291
|
-
<SlideLeft
|
|
292
|
-
visibility={hasActualValue && hasOptions && !disabled && !loading && !error}
|
|
293
|
-
duration={duration}
|
|
294
|
-
style={{display: 'grid'}}
|
|
295
|
-
>
|
|
296
|
-
{renderIcon(ClearIcon, {
|
|
297
|
-
className: 'rac-select-cancel',
|
|
298
|
-
onClick: (e) => clear(e)
|
|
299
|
-
})}
|
|
300
|
-
</SlideLeft>
|
|
301
|
-
<SlideLeft
|
|
302
|
-
visibility={active}
|
|
303
|
-
duration={duration}
|
|
304
|
-
style={{display: 'grid'}}
|
|
217
|
+
|
|
218
|
+
if (isHeader) {
|
|
219
|
+
currentGroupName = element.name
|
|
220
|
+
const open = expandedGroups.has(element.name)
|
|
221
|
+
const hasChildren = groupCounts[element.name] > 0
|
|
222
|
+
|
|
223
|
+
nodes.push(
|
|
224
|
+
<div
|
|
225
|
+
key={element.id}
|
|
226
|
+
className='rac-group-header'
|
|
227
|
+
onClick={(e) => selectOption(element, e)}
|
|
305
228
|
>
|
|
306
|
-
<span
|
|
307
|
-
|
|
229
|
+
<span className='rac-group-title-text'>{element.name}</span>
|
|
230
|
+
<SlideLeft
|
|
231
|
+
visibility={hasChildren}
|
|
232
|
+
duration={duration}
|
|
233
|
+
style={{display: 'grid'}}
|
|
308
234
|
>
|
|
309
|
-
{
|
|
310
|
-
className: 'rac-select-arrow-wrapper'
|
|
311
|
-
|
|
312
|
-
</
|
|
313
|
-
</SlideLeft>
|
|
314
|
-
</div>
|
|
315
|
-
<Options
|
|
316
|
-
visibility={visibility}
|
|
317
|
-
selectRef={selectRef}
|
|
318
|
-
onAnimationDone={() => setAnimationFinished(true)}
|
|
319
|
-
unmount={unmount}
|
|
320
|
-
duration={duration}
|
|
321
|
-
easing={easing}
|
|
322
|
-
offset={offset}
|
|
323
|
-
animateOpacity={animateOpacity}
|
|
324
|
-
>
|
|
325
|
-
<div
|
|
326
|
-
className='rac-select-list'
|
|
327
|
-
role='listbox'
|
|
328
|
-
aria-label='Options'
|
|
329
|
-
>
|
|
330
|
-
{renderOptions}
|
|
235
|
+
<span className={`rac-group-arrow-wrapper ${open ? '--open' : ''}`}>
|
|
236
|
+
{renderIcon(ArrowIcon, {className: 'rac-select-arrow-wrapper'})}
|
|
237
|
+
</span>
|
|
238
|
+
</SlideLeft>
|
|
331
239
|
</div>
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
240
|
+
)
|
|
241
|
+
} else if (belongsToGroup) {
|
|
242
|
+
currentGroupChildren.push(createOptionNode(element, index))
|
|
243
|
+
} else {
|
|
244
|
+
nodes.push(createOptionNode(element, index))
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
flushGroup(currentGroupName)
|
|
249
|
+
|
|
250
|
+
return nodes
|
|
251
|
+
}, [
|
|
252
|
+
normalizedOptions, selectOption, selectId, selected, highlightedIndex,
|
|
253
|
+
loadingTitle, loadMoreText, invalidOption, setHighlightedIndex,
|
|
254
|
+
expandedGroups, ArrowIcon
|
|
255
|
+
])
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<SelectJSX
|
|
259
|
+
selectRef={selectRef}
|
|
260
|
+
selectId={selectId}
|
|
261
|
+
|
|
262
|
+
renderIcon={renderIcon}
|
|
263
|
+
normalizedOptions={normalizedOptions}
|
|
264
|
+
renderOptions={renderOptions}
|
|
265
|
+
selected={selected}
|
|
266
|
+
title={title}
|
|
267
|
+
visibility={visibility}
|
|
268
|
+
active={active}
|
|
269
|
+
hasOptions={hasOptions}
|
|
270
|
+
hasActualValue={hasActualValue}
|
|
271
|
+
highlightedIndex={highlightedIndex}
|
|
272
|
+
animationFinished={animationFinished}
|
|
273
|
+
|
|
274
|
+
disabled={disabled}
|
|
275
|
+
loading={loading}
|
|
276
|
+
error={error}
|
|
277
|
+
|
|
278
|
+
setVisibility={setVisibility}
|
|
279
|
+
setHighlightedIndex={setHighlightedIndex}
|
|
280
|
+
setAnimationFinished={setAnimationFinished}
|
|
281
|
+
handleBlur={handleBlur}
|
|
282
|
+
handleFocus={handleFocus}
|
|
283
|
+
handleToggle={handleToggle}
|
|
284
|
+
handleKeyDown={handleKeyDown}
|
|
285
|
+
handleListScroll={handleListScroll}
|
|
286
|
+
selectOption={selectOption}
|
|
287
|
+
clear={clear}
|
|
288
|
+
registerOption={registerOption}
|
|
289
|
+
unregisterOption={unregisterOption}
|
|
290
|
+
|
|
291
|
+
children={children}
|
|
292
|
+
renderedDropdown={renderedDropdown}
|
|
293
|
+
placeholder={placeholder}
|
|
294
|
+
className={className}
|
|
295
|
+
style={style}
|
|
296
|
+
duration={duration}
|
|
297
|
+
easing={easing}
|
|
298
|
+
offset={offset}
|
|
299
|
+
animateOpacity={animateOpacity}
|
|
300
|
+
unmount={unmount}
|
|
301
|
+
ArrowIcon={ArrowIcon}
|
|
302
|
+
ClearIcon={ClearIcon}
|
|
303
|
+
hasMore={hasMore}
|
|
304
|
+
loadButton={loadButton}
|
|
305
|
+
/>
|
|
335
306
|
)
|
|
336
307
|
})
|
|
337
308
|
|
package/src/selectContext.js
CHANGED