UNPKG

react-native-autocomplete-dropdown

Version:

Dropdown Item picker with search and autocomplete (typeahead) functionality for react native

140 lines (139 loc) 5.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AutocompleteDropdownContextProvider = exports.AutocompleteDropdownContext = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const AutocompleteDropdownContext = exports.AutocompleteDropdownContext = /*#__PURE__*/_react.default.createContext({ content: undefined, setContent: () => null, direction: undefined, setDirection: () => null, activeInputContainerRef: undefined, activeControllerRef: undefined, controllerRefs: undefined }); const AutocompleteDropdownContextProvider = ({ headerOffset = 0, children }) => { const [content, setContent] = (0, _react.useState)(); const [direction, setDirection] = (0, _react.useState)(undefined); const [show, setShow] = (0, _react.useState)(false); const [dropdownHeight, setDropdownHeight] = (0, _react.useState)(0); const [inputMeasurements, setInputMeasurements] = (0, _react.useState)(); const [opacity, setOpacity] = (0, _react.useState)(0); const [contentStyles, setContentStyles] = (0, _react.useState)(undefined); const activeInputContainerRef = (0, _react.useRef)(null); const wrapperRef = (0, _react.useRef)(null); const activeControllerRef = (0, _react.useRef)(null); const controllerRefs = (0, _react.useRef)([]); const positionTrackingIntervalRef = (0, _react.useRef)(undefined); (0, _react.useEffect)(() => { if (!inputMeasurements?.height) { setOpacity(0); return; } if (dropdownHeight && direction === 'up') { setContentStyles({ bottom: inputMeasurements.bottomY + 5 + headerOffset, top: undefined, left: inputMeasurements.x, width: inputMeasurements.width }); setOpacity(1); } else if (direction === 'down') { setContentStyles({ top: inputMeasurements.topY + inputMeasurements.height + 5 + headerOffset, bottom: undefined, left: inputMeasurements.x, width: inputMeasurements.width }); setOpacity(1); } }, [direction, dropdownHeight, headerOffset, inputMeasurements]); const recalculatePosition = (0, _react.useCallback)((showAfterCalculation = false) => { activeInputContainerRef?.current?.measure((x, y, width, height, inputPageX, inputPageY) => { wrapperRef.current?.measure((wrapperX, wrapperY, wrapperW, wrapperH, wrapperPageX, wrapperPageY) => { const currentMeasurement = { width, height, x: inputPageX, topY: inputPageY - wrapperPageY, bottomY: wrapperH - inputPageY + wrapperPageY }; setInputMeasurements(prev => JSON.stringify(prev) === JSON.stringify(currentMeasurement) ? prev : currentMeasurement); showAfterCalculation && setShow(true); }); }); }, []); (0, _react.useEffect)(() => { if (content) { recalculatePosition(true); } else { setInputMeasurements(undefined); setDropdownHeight(0); setOpacity(0); setContentStyles(undefined); setShow(false); } }, [content, recalculatePosition]); (0, _react.useEffect)(() => { if (show && !!opacity) { positionTrackingIntervalRef.current = setInterval(() => { requestAnimationFrame(() => { recalculatePosition(); }); }, 16); } else { clearInterval(positionTrackingIntervalRef.current); } return () => { clearInterval(positionTrackingIntervalRef.current); }; }, [recalculatePosition, opacity, show]); const onLayout = (0, _react.useCallback)(e => { setDropdownHeight(e.nativeEvent.layout.height); }, []); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(AutocompleteDropdownContext.Provider, { value: { content, setContent, activeInputContainerRef, direction, setDirection, activeControllerRef, controllerRefs }, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { ref: wrapperRef, style: styles.clickOutsideHandlerArea, onTouchEnd: () => { activeControllerRef.current?.close(); activeControllerRef.current?.blur(); }, children: children }), !!content && show && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { onLayout: onLayout, style: { ...styles.wrapper, opacity, ...contentStyles }, children: content })] }); }; exports.AutocompleteDropdownContextProvider = AutocompleteDropdownContextProvider; const styles = _reactNative.StyleSheet.create({ clickOutsideHandlerArea: { flex: 1 }, wrapper: { position: 'absolute' } }); //# sourceMappingURL=AutocompleteDropdownContext.js.map