UNPKG

react-insect

Version:

Highly customisable, minimalistic input x select field for React.

241 lines (227 loc) 21 kB
function ___$insertStyle(css) { if (!css || typeof window === 'undefined') { return; } const style = document.createElement('style'); style.setAttribute('type', 'text/css'); style.innerHTML = css; document.head.appendChild(style); return css; } Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var React__namespace = /*#__PURE__*/_interopNamespace(React); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } ___$insertStyle(":root {\n --insect-rem: 16;\n --insect-norm: 10 / var(--insect-rem);\n}\n\n.insect {\n width: 100%;\n display: grid;\n grid-template-columns: 1fr;\n gap: calc(0.6rem * var(--insect-norm));\n}\n\n.insect_label {\n font-size: calc(1.6rem * var(--insect-norm));\n color: #424242;\n font-weight: 400;\n}\n.insect_label[data-iosdevice=true] {\n font-size: 16px;\n}\n\n.insect_wrapper {\n position: relative;\n padding: 0 calc(1.2rem * var(--insect-norm));\n height: fit-content;\n transition: all 0.1s ease-in;\n background-color: #ffffff;\n border: 1px solid rgba(66, 66, 66, 0.2);\n display: flex;\n justify-content: flex-start;\n align-items: center;\n flex-wrap: nowrap;\n flex-flow: row;\n gap: 0 calc(1rem * var(--insect-norm));\n}\n.insect_wrapper:focus-within {\n transition: all 0.2s linear;\n border-color: rgba(66, 66, 66, 0.5);\n}\n.insect_wrapper[data-focused=true] {\n border-color: rgba(66, 66, 66, 0.5);\n}\n.insect_wrapper[data-icon=suffix] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: nowrap;\n flex-flow: row;\n gap: 0 0;\n}\n.insect_wrapper[data-type=select] {\n cursor: pointer;\n}\n\n.insect_icon {\n margin: 0;\n width: calc(2rem * var(--insect-norm));\n height: calc(2rem * var(--insect-norm));\n flex-shrink: 0;\n position: relative;\n pointer-events: none;\n transition: all 0.3s linear;\n}\n.insect_icon img,\n.insect_icon svg {\n max-width: 100%;\n max-height: 100%;\n}\n\n.insect_wrapper[data-focused=true] [data-icon-type=caret] {\n transition: all 0.3s linear;\n transform: rotate(-180deg);\n}\n\n.insect_input {\n all: unset;\n flex-grow: 1;\n padding-right: calc(1.5rem * var(--insect-norm));\n height: 100%;\n font-size: calc(1.6rem * var(--insect-norm));\n min-height: calc(1.5rem * var(--insect-norm));\n padding: calc(1.2rem * var(--insect-norm)) calc(1.2rem * var(--insect-norm)) calc(1.2rem * var(--insect-norm)) 0;\n color: #424242;\n /* Chrome, Safari, Edge, Opera */\n /* Firefox */\n}\n.insect_input::-webkit-outer-spin-button, .insect_input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n.insect_input[type=number] {\n -moz-appearance: textfield;\n}\n.insect_input::placeholder {\n color: rgba(66, 66, 66, 0.4);\n}\n.insect_input[type=select] {\n cursor: pointer;\n caret-color: transparent;\n pointer-events: none;\n}\n.insect_input[data-search] {\n cursor: text;\n pointer-events: auto;\n}\n.insect_input[data-iosdevice=true] {\n /* prevent zoom on ios */\n font-size: 16px;\n}\n\n.insect_dd {\n position: absolute;\n min-height: calc(5rem * var(--insect-norm));\n max-height: calc(25.6rem * var(--insect-norm));\n left: -1px;\n right: -1px;\n padding: calc(1rem * var(--insect-norm)) 0;\n border-radius: 4px;\n overflow-y: hidden;\n overflow-x: hidden;\n pointer-events: none;\n z-index: 10;\n opacity: 0;\n background-color: #ffffff;\n transform: translateY(-1.5rem);\n transition: opacity 0.25s 0.1s, transform 0.25s 0.1s, box-shadow 0.2ms 0.1ms;\n}\n.insect_dd[data-open=true] {\n opacity: 1;\n pointer-events: auto;\n overflow-y: auto;\n transform: translateY(0);\n box-shadow: 0 4px 15px 0 rgba(66, 66, 66, 0.08);\n}\n\n.insect_dd-menu {\n padding: 0;\n margin: 0;\n border: 0;\n font-size: 100%;\n font-family: inherit;\n vertical-align: baseline;\n display: grid;\n grid-template-columns: 1fr;\n}\n\n.insect_dd-item {\n padding: calc(1.5rem * var(--insect-norm)) calc(2rem * var(--insect-norm));\n font-size: calc(1.6rem * var(--insect-norm));\n font-family: inherit;\n flex-grow: 1;\n margin: 0;\n border: 0;\n vertical-align: baseline;\n transition: all 0.2s linear;\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: nowrap;\n flex-flow: row nowrap;\n gap: 0 0;\n}\n.insect_dd-item:hover {\n background-color: rgba(66, 66, 66, 0.1);\n transition: all 0.2s linear;\n}\n.insect_dd-item[data-disabled=true] {\n opacity: 0.5;\n pointer-events: none;\n cursor: default;\n}\n.insect_dd-item[data-empty] {\n padding-top: calc(3rem * var(--insect-norm));\n padding-bottom: calc(3rem * var(--insect-norm));\n font-size: calc(1.3rem * var(--insect-norm));\n color: rgba(66, 66, 66, 0.4);\n display: flex;\n justify-content: center;\n align-items: center;\n flex-wrap: nowrap;\n flex-flow: column;\n gap: calc(0.8rem * var(--insect-norm)) 0;\n}\n.insect_dd-item[data-empty]:hover {\n background-color: inherit;\n}\n\n.insect_dd-item_icon {\n width: calc(1.8rem * var(--insect-norm));\n height: calc(1.7rem * var(--insect-norm));\n margin: 0;\n position: relative;\n}\n\n.insect_svg,\n.insect_image {\n width: 100%;\n height: 100%;\n max-width: 100%;\n object-fit: contain;\n}"); var Insect = function (_a) { var name = _a.name, _b = _a.type, type = _b === void 0 ? "text" : _b, value = _a.value, options = _a.options, defaultOption = _a.defaultOption, prefixIcon = _a.prefixIcon, suffixIcon = _a.suffixIcon, dropdownIcon = _a.dropdownIcon, checkmarkIcon = _a.checkmarkIcon, label = _a.label, _c = _a.placeholder, placeholder = _c === void 0 ? "Input or select an option" : _c, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onSelect = _a.onSelect, _d = _a.closeOnBlur, closeOnBlur = _d === void 0 ? true : _d, allowMultiple = _a.allowMultiple, className = _a.className, inputWrapperClass = _a.inputWrapperClass, inputClass = _a.inputClass, labelClass = _a.labelClass, iconsClass = _a.iconsClass, dropdownClass = _a.dropdownClass, checkerClass = _a.checkerClass, search = _a.search, rows = _a.rows; var containerRef = React.useRef(null); var inputRef = React.useRef(null); var textareaRef = React.useRef(null); var searchRef = React.useRef(null); var ddRef = React.useRef(null); var _e = React.useState(false), iosDevice = _e[0], setIosDevice = _e[1]; var _f = React.useState(false), showDD = _f[0], setShowDD = _f[1]; var _g = React.useState(""), selected = _g[0], setSelected = _g[1]; var _h = React.useState([]), selecteds = _h[0], setSelecteds = _h[1]; var _j = React.useState([]), selectedsValue = _j[0], setSelectedsValue = _j[1]; var _k = React.useState(""), filter = _k[0], setFilter = _k[1]; var searchCondiionOne = !allowMultiple && search && showDD; var searchConditionTwo = search && showDD && allowMultiple && selecteds.length < allowMultiple; var showSearch = searchCondiionOne || searchConditionTwo; var inputValue = type === "select" && allowMultiple ? selecteds === null || selecteds === void 0 ? void 0 : selecteds.filter(function (item) { return item !== null; }).join(", ") : type === "select" ? selected : value ? value : ""; var filteredDropdown = options === null || options === void 0 ? void 0 : options.filter(function (option) { return option.title.toLowerCase().includes(filter.toLowerCase()); }); var handleSelect = function (title, value) { if (!onSelect) { return; } // reset filter setFilter(""); // set or unset single value if multiple is off if (!allowMultiple) { // update state and return value to parent selected === name ? [onSelect(null, name), setSelected("")] : [onSelect(value, name), setSelected(title)]; } if (!!allowMultiple) { // check if selected item is already present var isPresent = selecteds === null || selecteds === void 0 ? void 0 : selecteds.find(function (item) { return item === title; }); var spaceAvailable = (selecteds === null || selecteds === void 0 ? void 0 : selecteds.length) < allowMultiple; if (isPresent) { var newOptions = selecteds.filter(function (option) { return option !== title; }); var newValues = selectedsValue.filter(function (option) { return option !== value; }); setSelecteds(newOptions); setSelectedsValue(newValues); } else if (spaceAvailable) { var previousOptions = __spreadArray([], selecteds, true); var previousValues = __spreadArray([], selectedsValue, true); previousOptions.push(title); previousValues.push(value); setSelecteds(previousOptions); setSelectedsValue(previousValues); } } }; var handleSearch = function (e) { var value = e.currentTarget.value; var strippedValue = value.split(", "); setFilter(strippedValue[strippedValue.length - 1]); }; var formatFilterText = function () { // const allSelectedValues = flattenObj(selectedsValue); var selectedItemsPresent = (selecteds === null || selecteds === void 0 ? void 0 : selecteds.length) > 0; var previousItemsPresent = !!selected || selectedItemsPresent; if (previousItemsPresent && allowMultiple) { return "".concat(inputValue, ", ").concat(filter); } else { return filter; } }; var isSelected = function (title) { return selecteds.includes(title); }; var totalSelected = React.useCallback(function () { return selecteds.length; }, [selectedsValue]); React.useEffect(function () { if (onSelect && allowMultiple && selectedsValue.length !== 0) { onSelect(selectedsValue, name); } }, [selectedsValue]); React.useEffect(function () { var handleClick = function (e) { if (!showDD) { return; } else if (showDD && !!closeOnBlur) { var shouldClose_1 = true; var target_1 = e.target; var componentList = [ containerRef.current, inputRef.current, textareaRef.current, searchRef.current, ]; componentList.forEach(function (item) { target_1 === item ? (shouldClose_1 = false) : null; }); shouldClose_1 && setShowDD(false); } }; window.addEventListener("click", handleClick); return function () { return window.removeEventListener("click", handleClick); }; }, [showDD]); React.useLayoutEffect(function () { var dd = ddRef.current; var setPosition = function () { var height = ((dd === null || dd === void 0 ? void 0 : dd.getBoundingClientRect()) || {}).height; if (dd && height) { dd.style.bottom = "".concat(-height - 6, "px"); } }; setPosition(); window.addEventListener("resize", setPosition); return function () { return window.removeEventListener("resize", setPosition); }; }, [showDD, filter]); React.useEffect(function () { // get device type in order to set input field size var isIOS = [ "iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod", ].includes(navigator.platform); var isIPAD = navigator.userAgent.includes("Mac") && "ontouchend" in document; if (isIOS || isIPAD) { setIosDevice(true); } }, []); React.useEffect(function () { var shouldUpdate = defaultOption && selected === "" && selecteds.length === 0; if (shouldUpdate) { handleSelect(defaultOption.title, defaultOption.value); } }, [defaultOption]); return (React__namespace.createElement("div", { className: "insect test ".concat(className) }, !!label && (React__namespace.createElement("label", { "data-iosdevice": iosDevice, className: "insect_label ".concat(labelClass), htmlFor: name }, label)), React__namespace.createElement("div", { ref: containerRef, className: "insect_wrapper ".concat(inputWrapperClass), "data-type": type, "data-icon": prefixIcon ? "prefix" : "suffix", "data-focused": type === "select" ? showDD : null, onClick: function () { type === "select" && !showSearch && setShowDD(!showDD); } }, !!prefixIcon && (React__namespace.createElement("figure", { className: "insect_icon ".concat(iconsClass) }, typeof prefixIcon === "string" ? (React__namespace.createElement("img", { className: "insect_image", src: prefixIcon })) : (prefixIcon))), type === "textarea" ? (React__namespace.createElement("textarea", { name: name, rows: rows, placeholder: placeholder, className: "insect_input ".concat(inputClass), onBlur: onBlur, onFocus: onFocus, value: inputValue, onChange: onChange || (function () { return null; }), ref: textareaRef, autoComplete: "true", "data-iosdevice": iosDevice })) : showSearch ? (React__namespace.createElement("input", { className: "insect_input ".concat(inputClass), value: formatFilterText(), onChange: handleSearch, ref: searchRef, "data-search": true, "data-iosdevice": iosDevice })) : (React__namespace.createElement("input", { name: name, className: "insect_input ".concat(inputClass), type: type, placeholder: placeholder, onChange: onChange || (function () { return null; }), onBlur: onBlur, onFocus: onFocus, value: inputValue, ref: inputRef, autoComplete: type === "select" ? "off" : "true", "data-iosdevice": iosDevice })), !!suffixIcon && (React__namespace.createElement("figure", { className: "insect_icon ".concat(iconsClass) }, typeof suffixIcon === "string" ? (React__namespace.createElement("img", { className: "insect_image", src: suffixIcon })) : (suffixIcon))), type === "select" && (React__namespace.createElement("figure", { className: "insect_icon ".concat(iconsClass), "data-icon-type": "caret" }, !dropdownIcon ? (React__namespace.createElement("svg", { width: "25", height: "25", viewBox: "0 0 25 25", fill: "#000000", xmlns: "http://www.w3.org/2000/svg", className: "insect_svg" }, React__namespace.createElement("path", { d: "M5.88822 11.207L11.4742 16.793C11.8652 17.184 12.4982 17.184 12.8882 16.793L18.4742 11.207C19.1042 10.577 18.6582 9.5 17.7672 9.5H6.59522C5.70422 9.5 5.25822 10.577 5.88822 11.207Z", fill: "" }))) : dropdownIcon && typeof dropdownIcon === "string" ? (React__namespace.createElement("img", { className: "insect_image", src: dropdownIcon })) : (dropdownIcon))), type === "select" && (React__namespace.createElement("div", { ref: ddRef, "data-open": showDD, className: "insect_dd ".concat(dropdownClass), onClick: function (e) { return !!allowMultiple && e.stopPropagation(); } }, React__namespace.createElement("ul", { className: "insect_dd-menu" }, (!options || options.length === 0 || (filteredDropdown === null || filteredDropdown === void 0 ? void 0 : filteredDropdown.length) === 0) && (React__namespace.createElement("li", { className: "insect_dd-item", "data-empty": true }, React__namespace.createElement("svg", { width: "35px", height: "35px", viewBox: "0 0 256 256", id: "Flat", xmlns: "http://www.w3.org/2000/svg" }, React__namespace.createElement("path", { fill: "#e0e0e0", d: "M108,116a8,8,0,1,1-8-8A7.99993,7.99993,0,0,1,108,116Zm48-8a8,8,0,1,0,8,8A7.99993,7.99993,0,0,0,156,108Zm64,12v96a4.00007,4.00007,0,0,1-6.5332,3.0957L186.667,197.168,159.86621,219.0957a4.00069,4.00069,0,0,1-5.06641,0L128,197.168,101.2002,219.0957a4.00069,4.00069,0,0,1-5.06641,0L69.333,197.168,42.5332,219.0957A4,4,0,0,1,36,216V120a92,92,0,0,1,184,0Zm-8,0a84,84,0,0,0-168,0v87.55908L66.7998,188.9043a4.00069,4.00069,0,0,1,5.06641,0L98.667,210.832,125.4668,188.9043a4.00025,4.00025,0,0,1,5.0664,0L157.333,210.832l26.80078-21.92773a4.00069,4.00069,0,0,1,5.06641,0L212,207.55908Z" })), "No Items")), filteredDropdown === null || filteredDropdown === void 0 ? void 0 : filteredDropdown.map(function (_a, index) { var title = _a.title, value = _a.value; return (React__namespace.createElement("li", { key: index, className: "insect_dd-item", onClick: function () { return handleSelect(title, value); }, "data-disabled": !isSelected(title) && totalSelected() === allowMultiple }, title, selected === title && (React__namespace.createElement("figure", { className: "insect_dd-item_icon ".concat(checkerClass) }, !checkmarkIcon ? (React__namespace.createElement("svg", { width: "33", height: "33", viewBox: "0 0 33 33", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "insect_svg" }, React__namespace.createElement("path", { d: "M29.8049 16.4994C29.8049 23.8327 23.8049 29.8327 16.4715 29.8327C9.13818 29.8327 3.13818 23.8327 3.13818 16.4994C3.13818 9.16608 9.13818 3.16608 16.4715 3.16608C23.8049 3.16608 29.8049 9.16608 29.8049 16.4994Z", fill: "#C8E6C9" }), React__namespace.createElement("path", { d: "M9.80469 16.5002L14.4714 21.1669L24.4714 11.1669", stroke: "#4CAF50", strokeWidth: "1.95162" }))) : checkmarkIcon && typeof checkmarkIcon === "string" ? (React__namespace.createElement("img", { className: "insect_image", src: checkmarkIcon })) : (checkmarkIcon))), isSelected(title) && (React__namespace.createElement("figure", { className: "insect_dd-item_icon ".concat(checkerClass) }, checkmarkIcon === undefined ? (React__namespace.createElement("svg", { width: "33", height: "33", viewBox: "0 0 33 33", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "insect_svg" }, React__namespace.createElement("path", { d: "M29.8049 16.4994C29.8049 23.8327 23.8049 29.8327 16.4715 29.8327C9.13818 29.8327 3.13818 23.8327 3.13818 16.4994C3.13818 9.16608 9.13818 3.16608 16.4715 3.16608C23.8049 3.16608 29.8049 9.16608 29.8049 16.4994Z", fill: "#C8E6C9" }), React__namespace.createElement("path", { d: "M9.80469 16.5002L14.4714 21.1669L24.4714 11.1669", stroke: "#4CAF50", strokeWidth: "1.95162" }))) : checkmarkIcon && typeof checkmarkIcon === "string" ? (React__namespace.createElement("img", { className: "insect_image", src: checkmarkIcon })) : (checkmarkIcon))))); }))))))); }; exports.Insect = Insect; exports["default"] = Insect; //# sourceMappingURL=index.js.map