UNPKG

react-native-customisable-combobox

Version:
165 lines (164 loc) 9.66 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Combobox = Combobox; var react_1 = __importStar(require("react")); var react_native_1 = require("react-native"); var DownIcon_1 = __importDefault(require("../src/components/Icons/DownIcon")); var CloseIcon_1 = __importDefault(require("../src/components/Icons/CloseIcon")); var styles_1 = require("./styles"); var useDebounce_1 = require("./hooks/useDebounce"); var useGetShowValue_1 = require("./hooks/useGetShowValue"); var useGetSearchItems_1 = require("./hooks/useGetSearchItems"); function Combobox(_a) { var items = _a.items, renderItem = _a.renderItem, labelField = _a.labelField, valueField = _a.valueField, searchField = _a.searchField, style = _a.style, itemStyle = _a.itemStyle, selectedStyle = _a.selectedStyle, value = _a.value, onChange = _a.onChange, _b = _a.searchable, searchable = _b === void 0 ? false : _b, searchPlaceholder = _a.searchPlaceholder, onFocus = _a.onFocus, onBlur = _a.onBlur, showItemOnNoSearch = _a.showItemOnNoSearch, _c = _a.showAlwaysNoSearchItem, showAlwaysNoSearchItem = _c === void 0 ? false : _c, renderNoSearchItem = _a.renderNoSearchItem, renderSearchIcon = _a.renderSearchIcon, onSearchCallback = _a.onSearchCallback, onSelectedNotFoundItem = _a.onSelectedNotFoundItem, containerRadius = _a.containerRadius, showBorder = _a.showBorder, dropdownStyle = _a.dropdownStyle, label = _a.label, labelStyle = _a.labelStyle, renderLabel = _a.renderLabel, error = _a.error, errorStyle = _a.errorStyle, renderError = _a.renderError, mainContainerStyle = _a.mainContainerStyle, _d = _a.debounceDelay, debounceDelay = _d === void 0 ? 300 : _d, noFoundItemText = _a.noFoundItemText, noFoundItemTextStyle = _a.noFoundItemTextStyle, showTextStyle = _a.showTextStyle, _e = _a.useFlatList, useFlatList = _e === void 0 ? true : _e; var _f = (0, react_1.useState)(false), open = _f[0], setOpen = _f[1]; var _g = (0, react_1.useState)(""), search = _g[0], setSearch = _g[1]; var _h = (0, react_1.useState)(value), selected = _h[0], setSelected = _h[1]; var _j = (0, react_1.useState)(false), focus = _j[0], setFocus = _j[1]; var _k = (0, react_1.useState)(0), dropdownTop = _k[0], setDropdownTop = _k[1]; var containerRef = (0, react_1.useRef)(null); var debouncedSearch = (0, useDebounce_1.useDebounce)(search, debounceDelay); var showValue = (0, useGetShowValue_1.useGetShowValue)({ selected: selected, labelField: labelField, search: search, value: value, setSelected: setSelected, }); var searchedItems = (0, useGetSearchItems_1.useGetSearchItems)({ items: items, searchField: searchField, onSearchCallback: onSearchCallback, search: debouncedSearch, }); (0, react_1.useEffect)(function () { if (containerRef.current) { containerRef.current.measure(function (x, y, width, height, pageX, pageY) { var dropdownHeight = !isNaN(height) ? height : 0; setDropdownTop(dropdownHeight); }); } }, [open]); var handleSelect = function (item) { setSelected(item); onChange(item); handleClose(); }; var handleSearch = function (value) { setOpen(true); setSelected(null); setSearch(value); }; var handleFocus = function () { setFocus(true); onFocus && onFocus(); }; var handleBlur = function () { setFocus(false); onBlur && onBlur(); }; var handleOpen = function () { setOpen(true); }; var handleClose = function () { setOpen(false); }; var handleSelectedNotFoundItem = function () { onSelectedNotFoundItem && onSelectedNotFoundItem(debouncedSearch); setSelected(debouncedSearch); handleClose(); }; var renderDropdownItem = function (_a) { var item = _a.item, key = _a.key; return (react_1.default.createElement(react_native_1.Pressable, { key: key, style: [styles_1.styles.item, itemStyle, selected === item && selectedStyle], onPress: function () { return handleSelect(item); } }, renderItem ? (renderItem({ item: item, selected: selected === item, })) : typeof item === "object" ? (react_1.default.createElement(react_native_1.Text, null, item && labelField && item[labelField])) : (react_1.default.createElement(react_native_1.Text, null, item)))); }; var renderItems = function () { if (useFlatList) { return (react_1.default.createElement(react_native_1.FlatList, { data: searchedItems, renderItem: function (_a) { var item = _a.item, index = _a.index; return renderDropdownItem({ item: item, key: index }); }, keyExtractor: function (item, index) { return item && typeof item === "object" && valueField ? item[valueField].toString() : index.toString(); }, style: { maxHeight: 200 } })); } return (react_1.default.createElement(react_native_1.ScrollView, { style: { maxHeight: 200 } }, searchedItems.map(function (item, index) { return renderDropdownItem({ item: item, key: index }); }))); }; return (react_1.default.createElement(react_native_1.View, { style: [ styles_1.styles.mainContainer, mainContainerStyle, { position: "relative" }, open && react_native_1.Platform.OS === "ios" ? { zIndex: 1000 } : {}, ] }, renderLabel ? renderLabel() : label && react_1.default.createElement(react_native_1.Text, { style: [styles_1.styles.label, labelStyle] }, label), react_1.default.createElement(react_native_1.Pressable, { ref: containerRef, style: [ style, styles_1.styles.container, showBorder && styles_1.styles.border, { borderRadius: containerRadius || 5, }, ], onPress: handleOpen, onFocus: handleFocus, onBlur: handleBlur }, react_1.default.createElement(react_native_1.View, { style: [ focus && styles_1.styles.focus, { flex: 1, flexDirection: "row", alignItems: "center", }, ] }, searchable && open ? (react_1.default.createElement(react_native_1.View, { style: { flex: 1, flexDirection: "row" } }, renderSearchIcon && renderSearchIcon(), react_1.default.createElement(react_native_1.TextInput, { style: [styles_1.styles.text, showTextStyle, styles_1.styles.search], placeholder: searchPlaceholder, defaultValue: showValue, onChangeText: handleSearch }))) : (react_1.default.createElement(react_native_1.View, { style: (styles_1.styles.text, showTextStyle) }, react_1.default.createElement(react_native_1.Text, null, showValue)))), !open ? (react_1.default.createElement(DownIcon_1.default, { size: 18 })) : (react_1.default.createElement(react_native_1.Pressable, { onPress: handleClose }, react_1.default.createElement(CloseIcon_1.default, { size: 18 })))), error && (react_1.default.createElement(react_native_1.Text, { style: [styles_1.styles.error, errorStyle] }, renderError ? renderError() : error)), open && (react_1.default.createElement(react_native_1.View, { style: [ dropdownStyle, styles_1.styles.dropdown, { marginTop: dropdownTop + 30, }, ] }, renderItems(), searchedItems.length === 0 && !showItemOnNoSearch && (react_1.default.createElement(react_native_1.Pressable, { style: styles_1.styles.item }, react_1.default.createElement(react_native_1.Text, { style: [noFoundItemTextStyle] }, noFoundItemText ? noFoundItemText : "No items found"))), (showAlwaysNoSearchItem || (showItemOnNoSearch && debouncedSearch.length === 0)) && (react_1.default.createElement(react_native_1.Pressable, { style: styles_1.styles.item, onPress: handleSelectedNotFoundItem }, renderNoSearchItem ? (renderNoSearchItem(search)) : (react_1.default.createElement(react_native_1.Text, null, search)))))))); }