haya-select 1.0.46 → 1.0.47
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 +43 -24
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({
|
|
@@ -212,8 +215,6 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
212
215
|
const {className, placeholder, toggleOptions} = this.props
|
|
213
216
|
const {opened, optionsPlacement} = this.s
|
|
214
217
|
const currentOptions = this.getCurrentOptions()
|
|
215
|
-
const BodyPortal = config.getBodyPortal()
|
|
216
|
-
|
|
217
218
|
const selectContainerStyleActual = this.stylingFor("selectContainer", {
|
|
218
219
|
display: "flex",
|
|
219
220
|
flexDirection: "row",
|
|
@@ -266,15 +267,11 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
266
267
|
}}
|
|
267
268
|
style={this.stylingFor("main")}
|
|
268
269
|
>
|
|
269
|
-
{opened &&
|
|
270
|
-
<BodyPortal>
|
|
271
|
-
{this.optionsContainer()}
|
|
272
|
-
</BodyPortal>
|
|
273
|
-
}
|
|
274
270
|
<Pressable
|
|
275
271
|
dataSet={{class: "select-container"}}
|
|
276
272
|
onLayout={this.tt.onSelectContainerLayout}
|
|
277
273
|
onPress={this.tt.onSelectClicked}
|
|
274
|
+
ref={this.tt.selectContainerRef}
|
|
278
275
|
style={selectContainerStyleActual}
|
|
279
276
|
>
|
|
280
277
|
<View
|
|
@@ -364,7 +361,12 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
364
361
|
</Text>
|
|
365
362
|
</View>
|
|
366
363
|
</Pressable>
|
|
367
|
-
<View onLayout={this.tt.onEndOfSelectLayout} ref={endOfSelectRef} />
|
|
364
|
+
<View dataSet={{class: "end-of-select"}} onLayout={this.tt.onEndOfSelectLayout} ref={endOfSelectRef} />
|
|
365
|
+
{opened &&
|
|
366
|
+
<Portal dataSet={{class: "haya-select-portal"}}>
|
|
367
|
+
{this.optionsContainer()}
|
|
368
|
+
</Portal>
|
|
369
|
+
}
|
|
368
370
|
</View>
|
|
369
371
|
)
|
|
370
372
|
}
|
|
@@ -573,24 +575,14 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
573
575
|
|
|
574
576
|
optionsContainer() {
|
|
575
577
|
const {optionsContainerRef} = this.tt
|
|
578
|
+
const {optionsAbsolute} = this.p
|
|
576
579
|
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
|
-
}
|
|
580
|
+
let top
|
|
588
581
|
|
|
589
582
|
const style = this.stylingFor("optionsContainer", {
|
|
590
583
|
position: "absolute",
|
|
591
|
-
left,
|
|
592
|
-
top,
|
|
593
584
|
zIndex: 99999,
|
|
585
|
+
elevation: 99999,
|
|
594
586
|
visibility: optionsVisibility,
|
|
595
587
|
width: this.p.optionsWidth || this.s.optionsWidth,
|
|
596
588
|
backgroundColor: "#fff",
|
|
@@ -599,10 +591,37 @@ export default memo(shapeComponent(class HayaSelect extends ShapeComponent {
|
|
|
599
591
|
overflowY: "auto"
|
|
600
592
|
})
|
|
601
593
|
|
|
594
|
+
if (!optionsAbsolute) {
|
|
595
|
+
style.left = 0
|
|
596
|
+
style.bottom = 0
|
|
597
|
+
} else if (optionsPlacement == "below") {
|
|
598
|
+
if (Platform.OS == "web") {
|
|
599
|
+
// onLayout top value is sometimes negative so use browser JS to get it instead
|
|
600
|
+
top = digg(this.tt.endOfSelectRef.current.getBoundingClientRect(), "top")
|
|
601
|
+
} else {
|
|
602
|
+
top = selectContainerLayout.top
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
style.left = this.s.endOfSelectLayout.left
|
|
606
|
+
style.top = top - 2
|
|
607
|
+
} else if (optionsPlacement == "above") {
|
|
608
|
+
if (Platform.OS == "web") {
|
|
609
|
+
// onLayout top value is sometimes negative so use browser JS to get it instead
|
|
610
|
+
top = digg(this.tt.selectContainerRef.current.getBoundingClientRect(), "top")
|
|
611
|
+
} else {
|
|
612
|
+
top = selectContainerLayout.top
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
style.left = endOfSelectLayout.left
|
|
616
|
+
style.top = top - optionsContainerLayout.height + 1
|
|
617
|
+
} else {
|
|
618
|
+
throw new Error(`Unkonwn options placement: ${optionsPlacement}`)
|
|
619
|
+
}
|
|
620
|
+
|
|
602
621
|
return (
|
|
603
622
|
<View
|
|
604
623
|
dataSet={{class: "options-container", id: idForComponent(this)}}
|
|
605
|
-
onLayout={this.onOptionsContainerLayout}
|
|
624
|
+
onLayout={this.tt.onOptionsContainerLayout}
|
|
606
625
|
ref={optionsContainerRef}
|
|
607
626
|
style={style}
|
|
608
627
|
>
|