analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
269 lines (254 loc) • 11.1 kB
JavaScript
;Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
var _chunk76VXVNA2js = require('./chunk-76VXVNA2.js');
// src/components/Search/Search.tsx
var _X = require('@phosphor-icons/react/dist/csr/X');
var _MagnifyingGlass = require('@phosphor-icons/react/dist/csr/MagnifyingGlass');
var _react = require('react');
var _jsxruntime = require('react/jsx-runtime');
var filterOptions = (options, query) => {
if (!query || query.length < 1) return [];
return options.filter(
(option) => option.toLowerCase().includes(query.toLowerCase())
);
};
var updateInputValue = (value, ref, onChange) => {
if (!onChange) return;
if (ref && "current" in ref && ref.current) {
ref.current.value = value;
const event = new Event("input", { bubbles: true });
Object.defineProperty(event, "target", {
writable: false,
value: ref.current
});
onChange(event);
} else {
const event = {
target: { value },
currentTarget: { value }
};
onChange(event);
}
};
var Search = _react.forwardRef.call(void 0,
({
options = [],
onSelect,
onSearch,
showDropdown: controlledShowDropdown,
onDropdownChange,
dropdownMaxHeight = 240,
noResultsText = "Nenhum resultado encontrado",
className = "",
containerClassName = "",
disabled,
readOnly,
id,
onClear,
value,
onChange,
placeholder = "Buscar...",
onKeyDown: userOnKeyDown,
debounceMs = 0,
...props
}, ref) => {
const [dropdownOpen, setDropdownOpen] = _react.useState.call(void 0, false);
const [forceClose, setForceClose] = _react.useState.call(void 0, false);
const justSelectedRef = _react.useRef.call(void 0, false);
const dropdownStore = _react.useRef.call(void 0, _chunk76VXVNA2js.createDropdownStore.call(void 0, )).current;
const dropdownRef = _react.useRef.call(void 0, null);
const inputElRef = _react.useRef.call(void 0, null);
const debounceTimer = _react.useRef.call(void 0, null);
_react.useEffect.call(void 0, () => {
return () => {
if (debounceTimer.current) clearTimeout(debounceTimer.current);
};
}, []);
const filteredOptions = _react.useMemo.call(void 0, () => {
if (!options.length) {
return [];
}
const filtered = filterOptions(options, value || "");
return filtered;
}, [options, value]);
const showDropdown = !forceClose && (_nullishCoalesce(controlledShowDropdown, () => ( (dropdownOpen && value && String(value).length > 0))));
const setOpenAndNotify = (open) => {
setDropdownOpen(open);
dropdownStore.setState({ open });
_optionalChain([onDropdownChange, 'optionalCall', _ => _(open)]);
};
_react.useEffect.call(void 0, () => {
if (justSelectedRef.current) {
justSelectedRef.current = false;
return;
}
if (forceClose) {
setOpenAndNotify(false);
return;
}
const shouldShow = Boolean(value && String(value).length > 0);
setOpenAndNotify(shouldShow);
}, [value, forceClose, onDropdownChange, dropdownStore]);
const handleSelectOption = (option) => {
justSelectedRef.current = true;
setForceClose(true);
_optionalChain([onSelect, 'optionalCall', _2 => _2(option)]);
setOpenAndNotify(false);
updateInputValue(option, ref, onChange);
};
_react.useEffect.call(void 0, () => {
const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setOpenAndNotify(false);
}
};
if (showDropdown) {
document.addEventListener("click", handleClickOutside);
}
return () => {
document.removeEventListener("click", handleClickOutside);
};
}, [showDropdown, dropdownStore, onDropdownChange]);
const generatedId = _react.useId.call(void 0, );
const inputId = _nullishCoalesce(id, () => ( `search-${generatedId}`));
const dropdownId = `${inputId}-dropdown`;
const handleClear = () => {
if (debounceTimer.current) {
clearTimeout(debounceTimer.current);
debounceTimer.current = null;
}
if (onClear) {
onClear();
} else {
updateInputValue("", ref, onChange);
}
};
const handleClearClick = (e) => {
e.preventDefault();
e.stopPropagation();
handleClear();
};
const handleSearchIconClick = (e) => {
e.preventDefault();
e.stopPropagation();
setTimeout(() => {
_optionalChain([inputElRef, 'access', _3 => _3.current, 'optionalAccess', _4 => _4.focus, 'call', _5 => _5()]);
}, 0);
};
const handleInputChange = (e) => {
setForceClose(false);
_optionalChain([onChange, 'optionalCall', _6 => _6(e)]);
if (debounceMs > 0) {
if (debounceTimer.current) clearTimeout(debounceTimer.current);
const value2 = e.target.value;
debounceTimer.current = setTimeout(() => {
_optionalChain([onSearch, 'optionalCall', _7 => _7(value2)]);
}, debounceMs);
} else {
_optionalChain([onSearch, 'optionalCall', _8 => _8(e.target.value)]);
}
};
const handleKeyDown = (e) => {
_optionalChain([userOnKeyDown, 'optionalCall', _9 => _9(e)]);
if (e.defaultPrevented) return;
if (e.key === "Enter") {
e.preventDefault();
if (showDropdown && filteredOptions.length > 0) {
handleSelectOption(filteredOptions[0]);
} else if (value) {
_optionalChain([onSearch, 'optionalCall', _10 => _10(String(value))]);
setForceClose(true);
setOpenAndNotify(false);
}
}
};
const getInputStateClasses = (disabled2, readOnly2) => {
if (disabled2) return "cursor-not-allowed opacity-40";
if (readOnly2) return "cursor-default focus:outline-none !text-text-900";
return "hover:border-border-400";
};
const hasValue = String(_nullishCoalesce(value, () => ( ""))).length > 0;
const showClearButton = hasValue && !disabled && !readOnly;
const showSearchIcon = !hasValue && !disabled && !readOnly;
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"div",
{
ref: dropdownRef,
className: `w-full max-w-lg md:w-[488px] ${containerClassName}`,
children: [
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative flex items-center", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"input",
{
ref: (node) => {
if (ref) {
if (typeof ref === "function") ref(node);
else
ref.current = node;
}
inputElRef.current = node;
},
id: inputId,
type: "text",
className: `w-full py-0 px-4 pr-10 font-normal text-text-900 focus:outline-primary-950 border rounded-full bg-background focus:bg-primary-50 border-border-300 focus:border-2 focus:border-primary-950 h-10 placeholder:text-text-600 ${getInputStateClasses(disabled, readOnly)} ${className}`,
value,
onChange: handleInputChange,
onKeyDown: handleKeyDown,
disabled,
readOnly,
placeholder,
"aria-expanded": showDropdown ? "true" : void 0,
"aria-haspopup": options.length > 0 ? "listbox" : void 0,
"aria-controls": showDropdown ? dropdownId : void 0,
"aria-autocomplete": "list",
role: options.length > 0 ? "combobox" : void 0,
...props
}
),
showClearButton && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"button",
{
type: "button",
className: "p-0 border-0 bg-transparent cursor-pointer",
onMouseDown: handleClearClick,
"aria-label": "Limpar busca",
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _X.XIcon, {}) })
}
) }),
showSearchIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"button",
{
type: "button",
className: "p-0 border-0 bg-transparent cursor-pointer",
onMouseDown: handleSearchIconClick,
"aria-label": "Buscar",
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "w-6 h-6 text-text-800 flex items-center justify-center hover:text-text-600 transition-colors", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _MagnifyingGlass.MagnifyingGlassIcon, {}) })
}
) })
] }),
showDropdown && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk76VXVNA2js.DropdownMenu_default, { open: showDropdown, onOpenChange: setDropdownOpen, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunk76VXVNA2js.DropdownMenuContent,
{
id: dropdownId,
className: "w-full mt-1",
style: { maxHeight: dropdownMaxHeight },
align: "start",
children: filteredOptions.length > 0 ? filteredOptions.map((option) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunk76VXVNA2js.DropdownMenuItem,
{
onClick: () => handleSelectOption(option),
className: "text-text-700 text-base leading-6 cursor-pointer",
children: option
},
option
)) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-3 py-3 text-text-700 text-base", children: noResultsText })
}
) })
]
}
);
}
);
Search.displayName = "Search";
var Search_default = Search;
exports.Search_default = Search_default;
//# sourceMappingURL=chunk-5PEPG6VS.js.map