haya-select 1.0.46 → 1.0.48
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/package.json +1 -1
- package/src/select/index.jsx +58 -43
package/package.json
CHANGED
package/src/select/index.jsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {anythingDifferent} from "set-state-compare/src/diff-utils"
|
|
2
|
-
import
|
|
3
|
-
import {dig, digg, digs} from "diggerize"
|
|
2
|
+
import {dig, digg} from "diggerize"
|
|
4
3
|
import debounce from "debounce"
|
|
5
4
|
import FontAwesomeIcon from "react-native-vector-icons/FontAwesome"
|
|
6
5
|
import idForComponent from "@kaspernj/api-maker/src/inputs/id-for-component.mjs"
|
|
@@ -10,6 +9,7 @@ import OptionGroup from "./option-group"
|
|
|
10
9
|
import PropTypes from "prop-types"
|
|
11
10
|
import propTypesExact from "prop-types-exact"
|
|
12
11
|
import RenderHtml from "react-native-render-html"
|
|
12
|
+
import {Portal} from "react-native-portalize"
|
|
13
13
|
import {memo, useEffect, useRef} from "react"
|
|
14
14
|
import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
|
|
15
15
|
import {Platform, Pressable, Text, TextInput, View} from "react-native"
|
|
@@ -26,6 +26,7 @@ const nameForComponentWithMultiple = (component) => {
|
|
|
26
26
|
export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
27
27
|
static defaultProps = {
|
|
28
28
|
multiple: false,
|
|
29
|
+
optionsAbsolute: true,
|
|
29
30
|
optionsWidth: null,
|
|
30
31
|
search: false
|
|
31
32
|
}
|
|
@@ -45,6 +46,7 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
45
46
|
onChangeValue: PropTypes.func,
|
|
46
47
|
onOptionsClosed: PropTypes.func,
|
|
47
48
|
options: PropTypes.oneOfType([PropTypes.array, PropTypes.func]).isRequired,
|
|
49
|
+
optionsAbsolute: PropTypes.bool.isRequired,
|
|
48
50
|
optionsWidth: PropTypes.number,
|
|
49
51
|
placeholder: PropTypes.node,
|
|
50
52
|
search: PropTypes.bool.isRequired,
|
|
@@ -79,6 +81,7 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
79
81
|
endOfSelectRef: useRef(),
|
|
80
82
|
optionsContainerRef: useRef(),
|
|
81
83
|
searchTextInputRef: useRef(),
|
|
84
|
+
selectContainerRef: useRef(),
|
|
82
85
|
t
|
|
83
86
|
})
|
|
84
87
|
this.useStates({
|
|
@@ -144,29 +147,25 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
144
147
|
if ("values" in this.props && typeof this.props.values != "undefined") {
|
|
145
148
|
if (Array.isArray(this.props.options) && this.props.values) {
|
|
146
149
|
return this.p.values.map((value) => this.p.options.find((option) => option.value == value))
|
|
147
|
-
} else if (this.s.loadedOptions
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
let foundOption = this.s.loadedOptions.find((option) => option.value == value)
|
|
150
|
+
} else if (this.s.loadedOptions && this.props.values) {
|
|
151
|
+
return this.p.values.map((value) => {
|
|
152
|
+
let foundOption = this.s.loadedOptions.find((option) => option.value == value)
|
|
151
153
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
if (!foundOption) {
|
|
155
|
+
foundOption = this.s.currentOptions.find((option) => option.value == value)
|
|
154
156
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
157
|
+
if (!foundOption) {
|
|
158
|
+
console.error(
|
|
159
|
+
`Couldn't find option: ${value} in loadedOptions or state currentOptions`,
|
|
160
|
+
{stateLoadedOptions: this.s.loadedOptions, stateCurrentOptions: this.s.currentOptions, propsOptions: this.props.options}
|
|
161
|
+
)
|
|
161
162
|
}
|
|
163
|
+
}
|
|
162
164
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
} else {
|
|
168
|
-
this.setCurrentFromGivenValues()
|
|
169
|
-
}
|
|
165
|
+
return foundOption
|
|
166
|
+
})
|
|
167
|
+
} else if (this.props.options == "function" && this.props.values) {
|
|
168
|
+
this.setCurrentFromGivenValues()
|
|
170
169
|
} else if (this.props.values) {
|
|
171
170
|
return this.p.values.map((value) => ({value}))
|
|
172
171
|
}
|
|
@@ -212,8 +211,6 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
212
211
|
const {className, placeholder, toggleOptions} = this.props
|
|
213
212
|
const {opened, optionsPlacement} = this.s
|
|
214
213
|
const currentOptions = this.getCurrentOptions()
|
|
215
|
-
const BodyPortal = config.getBodyPortal()
|
|
216
|
-
|
|
217
214
|
const selectContainerStyleActual = this.stylingFor("selectContainer", {
|
|
218
215
|
display: "flex",
|
|
219
216
|
flexDirection: "row",
|
|
@@ -266,15 +263,11 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
266
263
|
}}
|
|
267
264
|
style={this.stylingFor("main")}
|
|
268
265
|
>
|
|
269
|
-
{opened &&
|
|
270
|
-
<BodyPortal>
|
|
271
|
-
{this.optionsContainer()}
|
|
272
|
-
</BodyPortal>
|
|
273
|
-
}
|
|
274
266
|
<Pressable
|
|
275
267
|
dataSet={{class: "select-container"}}
|
|
276
268
|
onLayout={this.tt.onSelectContainerLayout}
|
|
277
269
|
onPress={this.tt.onSelectClicked}
|
|
270
|
+
ref={this.tt.selectContainerRef}
|
|
278
271
|
style={selectContainerStyleActual}
|
|
279
272
|
>
|
|
280
273
|
<View
|
|
@@ -364,7 +357,12 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
364
357
|
</Text>
|
|
365
358
|
</View>
|
|
366
359
|
</Pressable>
|
|
367
|
-
<View onLayout={this.tt.onEndOfSelectLayout} ref={endOfSelectRef} />
|
|
360
|
+
<View dataSet={{class: "end-of-select"}} onLayout={this.tt.onEndOfSelectLayout} ref={endOfSelectRef} />
|
|
361
|
+
{opened &&
|
|
362
|
+
<Portal dataSet={{class: "haya-select-portal"}}>
|
|
363
|
+
{this.optionsContainer()}
|
|
364
|
+
</Portal>
|
|
365
|
+
}
|
|
368
366
|
</View>
|
|
369
367
|
)
|
|
370
368
|
}
|
|
@@ -573,24 +571,14 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
573
571
|
|
|
574
572
|
optionsContainer() {
|
|
575
573
|
const {optionsContainerRef} = this.tt
|
|
574
|
+
const {optionsAbsolute} = this.p
|
|
576
575
|
const {selectContainerLayout, loadedOptions, endOfSelectLayout, optionsContainerLayout, optionsPlacement, optionsVisibility} = this.s
|
|
577
|
-
let
|
|
578
|
-
|
|
579
|
-
if (optionsPlacement == "below") {
|
|
580
|
-
left = this.s.endOfSelectLayout.left
|
|
581
|
-
top = this.s.endOfSelectLayout.top - 2
|
|
582
|
-
} else if (optionsPlacement == "above") {
|
|
583
|
-
left = endOfSelectLayout.left
|
|
584
|
-
top = selectContainerLayout.top - optionsContainerLayout.height + 1
|
|
585
|
-
} else {
|
|
586
|
-
throw new Error(`Unkonwn options placement: ${optionsPlacement}`)
|
|
587
|
-
}
|
|
576
|
+
let top
|
|
588
577
|
|
|
589
578
|
const style = this.stylingFor("optionsContainer", {
|
|
590
579
|
position: "absolute",
|
|
591
|
-
left,
|
|
592
|
-
top,
|
|
593
580
|
zIndex: 99999,
|
|
581
|
+
elevation: 99999,
|
|
594
582
|
visibility: optionsVisibility,
|
|
595
583
|
width: this.p.optionsWidth || this.s.optionsWidth,
|
|
596
584
|
backgroundColor: "#fff",
|
|
@@ -599,10 +587,37 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
599
587
|
overflowY: "auto"
|
|
600
588
|
})
|
|
601
589
|
|
|
590
|
+
if (!optionsAbsolute) {
|
|
591
|
+
style.left = 0
|
|
592
|
+
style.bottom = 0
|
|
593
|
+
} else if (optionsPlacement == "below") {
|
|
594
|
+
if (Platform.OS == "web") {
|
|
595
|
+
// onLayout top value is sometimes negative so use browser JS to get it instead
|
|
596
|
+
top = digg(this.tt.endOfSelectRef.current.getBoundingClientRect(), "top")
|
|
597
|
+
} else {
|
|
598
|
+
top = selectContainerLayout.top
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
style.left = this.s.endOfSelectLayout.left
|
|
602
|
+
style.top = top - 2
|
|
603
|
+
} else if (optionsPlacement == "above") {
|
|
604
|
+
if (Platform.OS == "web") {
|
|
605
|
+
// onLayout top value is sometimes negative so use browser JS to get it instead
|
|
606
|
+
top = digg(this.tt.selectContainerRef.current.getBoundingClientRect(), "top")
|
|
607
|
+
} else {
|
|
608
|
+
top = selectContainerLayout.top
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
style.left = endOfSelectLayout.left
|
|
612
|
+
style.top = top - optionsContainerLayout.height + 1
|
|
613
|
+
} else {
|
|
614
|
+
throw new Error(`Unkonwn options placement: ${optionsPlacement}`)
|
|
615
|
+
}
|
|
616
|
+
|
|
602
617
|
return (
|
|
603
618
|
<View
|
|
604
619
|
dataSet={{class: "options-container", id: idForComponent(this)}}
|
|
605
|
-
onLayout={this.onOptionsContainerLayout}
|
|
620
|
+
onLayout={this.tt.onOptionsContainerLayout}
|
|
606
621
|
ref={optionsContainerRef}
|
|
607
622
|
style={style}
|
|
608
623
|
>
|