@devrue/rn-select
Version:
Custom typescript only select component for react native
133 lines (132 loc) • 4.73 kB
JavaScript
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useEffect, useRef } from 'react';
import { Pressable, Text, View, Dimensions, Platform } from 'react-native';
import useStyles from '../hooks/useStyles';
import ChevronDownIcon from '../icons/ChevronDownIcon';
import Selections from './Selections';
import CloseIcon from '../icons/CloseIcon';
import { StyleSheet } from 'react-native';
import debounce from 'lodash/debounce';
export default function Anchor({
placeholder,
selected,
multi = false,
clearable,
disabled,
onRemove,
onClear,
onLayout,
selectStyle,
selectPlaceholderTextStyle,
selectTextStyle,
selectPillTextStyle,
selectPillRemoveContainerStyle,
selectPillRemoveIconStyle,
selectIconStyle,
...rest
}) {
var _selected$;
const styles = useStyles(({
tokens,
hairlineWidth
}) => ({
anchorContainer: {
height: tokens.size.xl + 4,
paddingLeft: tokens.size.xs,
borderColor: '#c5c5c5',
borderWidth: hairlineWidth,
borderRadius: tokens.size.xs,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
},
icon: {
width: (selectIconStyle === null || selectIconStyle === void 0 ? void 0 : selectIconStyle.fontSize) ?? tokens.size.sm,
height: (selectIconStyle === null || selectIconStyle === void 0 ? void 0 : selectIconStyle.fontSize) ?? tokens.size.sm,
paddingHorizontal: tokens.size.sm - 4
},
iconContainer: {
flexDirection: 'row',
alignItems: 'center'
},
fill: {
flex: 1
},
placeholder: {
color: '#808080'
},
closeIconContainer: {
height: tokens.size.xl + 4,
justifyContent: 'center'
},
disabled: {
cursor: 'not-allowed',
backgroundColor: 'white',
opacity: 0.4,
borderRadius: tokens.size.xs
}
}), [selectIconStyle, disabled]);
const ref = useRef(null);
const onLayoutRef = useRef(onLayout);
useEffect(() => {
const updatePosition = () => {
if (ref.current) {
ref.current.measure((x, y, width, height, pageX, pageY) => {
onLayoutRef.current({
x,
y,
width,
height,
left: pageX,
top: pageY
});
});
}
};
const debouncedUpdate = debounce(updatePosition, 16);
const subscription = Dimensions.addEventListener('change', debouncedUpdate);
// Track scroll events on web
if (Platform.OS === 'web' && window) {
window.addEventListener('scroll', debouncedUpdate, true);
}
updatePosition();
return () => {
subscription.remove();
debouncedUpdate.cancel();
if (Platform.OS === 'web') {
window.removeEventListener('scroll', debouncedUpdate, true);
}
};
}, []);
return /*#__PURE__*/React.createElement(Pressable, _extends({
ref: ref
}, rest, {
style: [styles.anchorContainer, selectStyle]
}), selected.length === 0 && /*#__PURE__*/React.createElement(Text, {
style: [styles.placeholder, selectPlaceholderTextStyle, styles.fill],
numberOfLines: 1
}, placeholder), selected.length === 1 && !multi && /*#__PURE__*/React.createElement(Text, {
style: [selectTextStyle, styles.fill],
numberOfLines: 1
}, (_selected$ = selected[0]) === null || _selected$ === void 0 ? void 0 : _selected$[1]), selected.length > 0 && multi && /*#__PURE__*/React.createElement(Selections, {
items: selected,
onRemove: onRemove,
pillTextStyle: selectPillTextStyle,
pillRemoveContainerStyle: selectPillRemoveContainerStyle,
pillRemoveIconStyle: selectPillRemoveIconStyle
}), /*#__PURE__*/React.createElement(View, {
style: styles.iconContainer
}, selected.length > 0 && clearable && !disabled && /*#__PURE__*/React.createElement(Pressable, {
style: styles.closeIconContainer,
onPress: onClear
}, /*#__PURE__*/React.createElement(CloseIcon, {
stroke: (selectIconStyle === null || selectIconStyle === void 0 ? void 0 : selectIconStyle.color) ?? '#c5c5c5',
style: styles.icon
})), /*#__PURE__*/React.createElement(ChevronDownIcon, {
stroke: (selectIconStyle === null || selectIconStyle === void 0 ? void 0 : selectIconStyle.color) ?? '#c5c5c5',
style: styles.icon
})), disabled && /*#__PURE__*/React.createElement(View, {
style: [StyleSheet.absoluteFill, styles.disabled]
}));
}
//# sourceMappingURL=Anchor.js.map