react-animated-select 0.1.5 → 0.2.0
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 +84 -18
- package/dist/index.cjs.js +9 -9
- package/dist/index.css +1 -1
- package/dist/index.es.js +420 -395
- package/package.json +1 -1
- package/src/getText.jsx +11 -0
- package/src/option.jsx +6 -3
- package/src/select.css +2 -2
- package/src/select.jsx +6 -4
- package/src/slideLeft.jsx +1 -1
- package/src/useSelect.jsx +21 -11
- package/src/useSelectLogic.jsx +262 -241
package/package.json
CHANGED
package/src/getText.jsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
const getText = (children) => {
|
|
4
|
+
if (!children) return ''
|
|
5
|
+
if (typeof children === 'string' || typeof children === 'number') return String(children)
|
|
6
|
+
if (Array.isArray(children)) return children.map(getText).join(' ').replace(/\s+/g, ' ').trim()
|
|
7
|
+
if (React.isValidElement(children)) return getText(children.props.children)
|
|
8
|
+
return ''
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default getText
|
package/src/option.jsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {useEffect, useContext} from 'react'
|
|
2
2
|
import {SelectContext} from './selectContext'
|
|
3
3
|
import {makeId} from './makeId'
|
|
4
|
+
import getText from './getText'
|
|
4
5
|
|
|
5
6
|
export default function Option({value, id, className, children, disabled}) {
|
|
6
7
|
const ctx = useContext(SelectContext)
|
|
@@ -8,9 +9,11 @@ export default function Option({value, id, className, children, disabled}) {
|
|
|
8
9
|
useEffect(() => {
|
|
9
10
|
if (!ctx) return
|
|
10
11
|
|
|
12
|
+
const textFallback = getText(children)
|
|
13
|
+
|
|
11
14
|
const option = {
|
|
12
|
-
id: id ?? makeId(String(
|
|
13
|
-
value,
|
|
15
|
+
id: String(id ?? makeId(String(textFallback))),
|
|
16
|
+
value: value !== undefined ? value : textFallback,
|
|
14
17
|
label: typeof children === 'string' ? children : String(value ?? id),
|
|
15
18
|
jsx: children,
|
|
16
19
|
className,
|
|
@@ -22,4 +25,4 @@ export default function Option({value, id, className, children, disabled}) {
|
|
|
22
25
|
}, [id, value, children, className, disabled])
|
|
23
26
|
|
|
24
27
|
return null
|
|
25
|
-
}
|
|
28
|
+
}
|
package/src/select.css
CHANGED
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
|
|
126
126
|
.rac-select-option {
|
|
127
127
|
padding: 0.5em;
|
|
128
|
-
transition: background-color 300ms, border-radius 300ms, font-size 300ms, 300ms height;
|
|
129
|
-
|
|
128
|
+
transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1), border-radius 300ms, font-size 300ms, 300ms height;
|
|
129
|
+
background-color: transparent;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
.rac-select-option:not(.rac-disabled-option):hover {
|
package/src/select.jsx
CHANGED
|
@@ -63,7 +63,7 @@ export default function Select({children, renderedDropdown, ...props}) {
|
|
|
63
63
|
|
|
64
64
|
const option = normalizedOptions[highlightedIndex]
|
|
65
65
|
if (option) {
|
|
66
|
-
const elementId = `
|
|
66
|
+
const elementId = `opt-${selectId}-${makeId(option.id)}`
|
|
67
67
|
const domElement = document.getElementById(elementId)
|
|
68
68
|
|
|
69
69
|
if (domElement) {
|
|
@@ -85,7 +85,7 @@ export default function Select({children, renderedDropdown, ...props}) {
|
|
|
85
85
|
if (loading) return loadingText
|
|
86
86
|
if (disabled) return disabledText
|
|
87
87
|
|
|
88
|
-
if (selected) return selected.name
|
|
88
|
+
if (selected) return selected.jsx ?? selected.name
|
|
89
89
|
|
|
90
90
|
if (hasActualValue) {
|
|
91
91
|
return typeof selectedValue === 'object'
|
|
@@ -102,11 +102,13 @@ export default function Select({children, renderedDropdown, ...props}) {
|
|
|
102
102
|
|
|
103
103
|
// option list rendering
|
|
104
104
|
const renderOptions = useMemo(() => normalizedOptions?.map((element, index) => {
|
|
105
|
-
const optionId = `
|
|
105
|
+
const optionId = `opt-${selectId}-${makeId(element.id)}`
|
|
106
106
|
|
|
107
107
|
let optionClass = 'rac-select-option'
|
|
108
108
|
if (element.className) optionClass += ` ${element.className}`
|
|
109
109
|
|
|
110
|
+
if (selected?.id === element.id) optionClass += ' rac-selected'
|
|
111
|
+
|
|
110
112
|
if (index === highlightedIndex) optionClass += ' rac-highlighted'
|
|
111
113
|
|
|
112
114
|
if (element.disabled) optionClass += ' rac-disabled-option'
|
|
@@ -199,7 +201,7 @@ export default function Select({children, renderedDropdown, ...props}) {
|
|
|
199
201
|
visibility={loading && !error}
|
|
200
202
|
>
|
|
201
203
|
<span className='rac-loading-dots'>
|
|
202
|
-
<i
|
|
204
|
+
<i/><i/><i/>
|
|
203
205
|
</span>
|
|
204
206
|
</SlideLeft>
|
|
205
207
|
</div>
|
package/src/slideLeft.jsx
CHANGED
|
@@ -8,7 +8,7 @@ function SlideLeft({visibility, children, duration = 300, unmount}) {
|
|
|
8
8
|
<CSSTransition
|
|
9
9
|
in={visibility}
|
|
10
10
|
timeout={duration}
|
|
11
|
-
classNames='slide-left'
|
|
11
|
+
classNames='rac-slide-left'
|
|
12
12
|
unmountOnExit
|
|
13
13
|
nodeRef={nodeRef}
|
|
14
14
|
onEnter={() => (nodeRef.current.style.width = '0px')}
|
package/src/useSelect.jsx
CHANGED
|
@@ -13,14 +13,22 @@ function useSelect({
|
|
|
13
13
|
|
|
14
14
|
useEffect(() => {
|
|
15
15
|
if (isOpen) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
let index = -1
|
|
17
|
+
|
|
18
|
+
if (selected) {
|
|
19
|
+
const selectedIndex = options.findIndex(o => o.id === selected.id && !o.disabled)
|
|
20
|
+
if (selectedIndex >= 0) index = selectedIndex
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (index === -1) {
|
|
24
|
+
index = options.findIndex(o => !o.disabled)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setHighlightedIndex(index)
|
|
20
28
|
} else {
|
|
21
29
|
setHighlightedIndex(-1)
|
|
22
30
|
}
|
|
23
|
-
}, [isOpen, selected])
|
|
31
|
+
}, [isOpen, selected, options])
|
|
24
32
|
|
|
25
33
|
const handleBlur = useCallback((e) => {
|
|
26
34
|
if (e.currentTarget.contains(e.relatedTarget)) return
|
|
@@ -49,20 +57,22 @@ function useSelect({
|
|
|
49
57
|
}, [disabled, isOpen, setIsOpen])
|
|
50
58
|
|
|
51
59
|
const getNextIndex = (current, direction) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
if (options.every(o => o.disabled)) return -1
|
|
61
|
+
|
|
62
|
+
let next = current
|
|
56
63
|
let loops = 0
|
|
57
|
-
|
|
64
|
+
|
|
65
|
+
do {
|
|
58
66
|
next += direction
|
|
59
67
|
if (next < 0) next = options.length - 1
|
|
60
68
|
if (next >= options.length) next = 0
|
|
61
69
|
loops++
|
|
62
|
-
}
|
|
70
|
+
} while (options[next]?.disabled && loops <= options.length)
|
|
71
|
+
|
|
63
72
|
return next
|
|
64
73
|
}
|
|
65
74
|
|
|
75
|
+
|
|
66
76
|
const handleKeyDown = useCallback((e) => {
|
|
67
77
|
if (disabled) return
|
|
68
78
|
|