UNPKG

@geneui/components

Version:

The Gene UI components library designed for BI tools

893 lines (878 loc) 36.8 kB
import { _ as _extends } from '../_rollupPluginBabelHelpers-e8fb2e5c.js'; import React__default, { useRef, useState, useCallback, useEffect, useMemo } from 'react'; import PropTypes from 'prop-types'; import { c as classnames } from '../index-031ff73c.js'; import { a as dayjs } from '../dateValidation-67caec66.js'; import { h as advancedSearchConfig } from '../configs-00612ce0.js'; import useDebounce from '../hooks/useDebounce.js'; import { n as noop } from '../index-a0e4e333.js'; import useKeyDown from '../hooks/useKeyDown.js'; import useClickOutside from '../hooks/useClickOutside.js'; import { P as PopoverV2 } from '../index-08898b29.js'; import ExtendedInput from '../ExtendedInput/index.js'; import CustomScrollbar from '../Scrollbar/index.js'; import LinkButton from '../LinkButton/index.js'; import { u as useEllipsisDetection } from '../useEllipsisDetection-4d997d5d.js'; import Icon from '../Icon/index.js'; import Checkbox from '../Checkbox/index.js'; import { T as Tooltip } from '../index-6d7e99cd.js'; import SkeletonLoader from '../SkeletonLoader/index.js'; import Badge from '../Badge/index.js'; import Empty from '../Empty/index.js'; import 'react-dom'; import Button from '../Button/index.js'; import { s as styleInject } from '../style-inject.es-746bb8ed.js'; import '../_commonjsHelpers-24198af3.js'; import '../index-122432cd.js'; import '../hooks/useDeviceType.js'; import '../hooks/useWindowSize.js'; import '../GeneUIProvider/index.js'; import '../debounce-4419bc2f.js'; import '../SuggestionList/index.js'; import '../config-1053d64d.js'; import '../callAfterDelay-7272faca.js'; import '../tslib.es6-f211516f.js'; import '../checkboxRadioSwitcher-5b69d7bd.js'; import '../guid-8ddf77b3.js'; function ListElementWithCheckbox(_ref) { let { item, onSelect } = _ref; const { checked, icon, name } = item; const checkboxRef = useRef(null); const [isFocused, setIsFocused] = useState(false); const nameRef = useRef(null); const isNameTruncated = useEllipsisDetection(nameRef); // Handle blur event to clear focus state const handleBlur = useCallback(() => setIsFocused(false), []); // Handle Focus event to add focus state const handleFocus = useCallback(() => setIsFocused(true), []); return /*#__PURE__*/React__default.createElement("li", { className: classnames('listElementWithCheckbox', { 'listElementWithCheckbox-hover': isFocused }) }, /*#__PURE__*/React__default.createElement("label", { className: "listElementWithCheckbox__label" }, item.hasOwnProperty('checked') && /*#__PURE__*/React__default.createElement(Checkbox, { ref: checkboxRef, checked: checked, onChange: () => { onSelect(item); }, className: "listElementWithCheckbox__checkbox", onBlur: handleBlur, onFocus: handleFocus }), icon && /*#__PURE__*/React__default.createElement(Icon, { type: icon, className: "listElementWithCheckbox__icon" }), name && /*#__PURE__*/React__default.createElement(Tooltip, { text: name, isVisible: isNameTruncated }, /*#__PURE__*/React__default.createElement("span", { className: "listElementWithCheckbox__name ellipsis-text", ref: nameRef }, name)))); } ListElementWithCheckbox.defaultProps = { onSelect: noop, item: { checked: false } }; ListElementWithCheckbox.propTypes = { item: PropTypes.shape({ name: PropTypes.string, value: PropTypes.string, checked: PropTypes.bool, icon: PropTypes.string }) }; function SkeletonSet(_ref) { let { count, searchResult } = _ref; return searchResult ? /*#__PURE__*/React__default.createElement("ul", { className: "skeleton" }, Array(count || 1).fill('').map((_, i) => /*#__PURE__*/React__default.createElement("li", { className: "skeleton__searchElement", key: i }, /*#__PURE__*/React__default.createElement(SkeletonLoader, { duration: +"".concat(2, ".0", i), width: "100%", isBusy: true })))) : /*#__PURE__*/React__default.createElement("ul", null, Array(count || 1).fill('').map((_, i) => /*#__PURE__*/React__default.createElement("li", { className: "skeleton__filter", key: i }, /*#__PURE__*/React__default.createElement(SkeletonLoader, { duration: 2, height: "23px", width: "23px", isBusy: true }), /*#__PURE__*/React__default.createElement("span", { style: { width: '10px' } }), /*#__PURE__*/React__default.createElement(SkeletonLoader, { duration: +"".concat(2, ".0", i), height: "23px", width: "".concat(Math.floor(Math.random() * 51) + 50, "%"), isBusy: true })))); } SkeletonSet.defaultProps = {}; SkeletonSet.propTypes = {}; function FilterList(_ref) { let { data, skeletonCount, onSelect } = _ref; const { data: filterData, isLoading, onShowMoreClick, sectionNameText, hasActiveShowMore, showMoreText } = data; const listRef = useRef(null); const scrollbarRef = useRef(null); const [ableToScroll, setAbleToScroll] = useState(false); const [dataLengthSnapshots, setDataLengthSnapshots] = useState([]); const [elementTopToScroll, setElementTopToScroll] = useState(0); const onShowMoreHandler = useCallback(e => { onShowMoreClick(e); setAbleToScroll(true); }, []); useEffect(() => { setDataLengthSnapshots(prev => [...prev, filterData === null || filterData === void 0 ? void 0 : filterData.length]); }, [filterData === null || filterData === void 0 ? void 0 : filterData.length]); useEffect(() => { var _listRef$current, _listRef$current$chil; const scrollToElementTop = +(listRef === null || listRef === void 0 ? void 0 : (_listRef$current = listRef.current) === null || _listRef$current === void 0 ? void 0 : (_listRef$current$chil = _listRef$current.children[dataLengthSnapshots[(dataLengthSnapshots === null || dataLengthSnapshots === void 0 ? void 0 : dataLengthSnapshots.length) - 1] - 1]) === null || _listRef$current$chil === void 0 ? void 0 : _listRef$current$chil.offsetTop); if (!isLoading && ableToScroll) { setElementTopToScroll(scrollToElementTop); setAbleToScroll(false); } }, [isLoading]); return /*#__PURE__*/React__default.createElement("div", { className: "filterList__filter" }, /*#__PURE__*/React__default.createElement(CustomScrollbar, { autoHeightMax: 500, className: "filterList__scrollbar", style: { height: '100%' }, ref: scrollbarRef, scrollTop: elementTopToScroll, withSmoothScroll: true }, /*#__PURE__*/React__default.createElement("h6", { className: "filterList__filterHeader" }, sectionNameText), /*#__PURE__*/React__default.createElement("ul", { className: "filterList__filterList", ref: listRef }, isLoading ? /*#__PURE__*/React__default.createElement(SkeletonSet, { count: skeletonCount }) : filterData === null || filterData === void 0 ? void 0 : filterData.map((item, index) => /*#__PURE__*/React__default.createElement(ListElementWithCheckbox, { key: index, onSelect: onSelect, item: item })), hasActiveShowMore && /*#__PURE__*/React__default.createElement("li", { className: "filterList__showMoreLi" }, /*#__PURE__*/React__default.createElement(LinkButton, { tabIndex: 0, ariaLabel: showMoreText, onClick: onShowMoreHandler, className: "filterList__showMoreLink" }, showMoreText))))); } FilterList.defaultProps = { data: { data: [] }, onSelect: noop, skeletonCount: 5, showMoreIsLoading: false }; FilterList.propTypes = { /** * data structure for secondary filter */ data: PropTypes.shape({ sectionNameText: PropTypes.string, onChange: PropTypes.func, hasActiveShowMore: PropTypes.bool, showMoreText: PropTypes.string, showMoreIsLoading: PropTypes.bool, onShowMoreClick: PropTypes.func, isLoading: PropTypes.bool, data: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, value: PropTypes.string, checked: PropTypes.bool, icon: PropTypes.string, id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) })) }), skeleton: PropTypes.element, onSelect: PropTypes.func, skeletonCount: PropTypes.number }; function SearchResultRow(_ref) { let { element } = _ref; const { icon, id, title, name, date, actions } = element; const [isFocused, setIsFocused] = useState(false); const [focusedIndex, setFocusedIndex] = useState(null); const titleRef = useRef(null); const isTitleTruncated = useEllipsisDetection(titleRef); const nameRef = useRef(null); const isNameTruncated = useEllipsisDetection(nameRef); // Handle blur event to clear focus state const handleBlur = useCallback(() => { setFocusedIndex(null); setIsFocused(false); }, [element]); // Handle Focus event to add focus state const handleFocus = useCallback(index => { setFocusedIndex(index); setIsFocused(true); }, [element]); return /*#__PURE__*/React__default.createElement("li", { className: classnames('searchResultRow', { 'searchResultRow-hover': isFocused }) }, icon && /*#__PURE__*/React__default.createElement(Icon, { type: element.icon, className: "searchResultRow__icon" }), /*#__PURE__*/React__default.createElement("div", { className: "searchResultRow__info" }, (id || title) && /*#__PURE__*/React__default.createElement("div", { className: "searchResultRow__titleWrapper" }, id && /*#__PURE__*/React__default.createElement("span", { className: "searchResultRow__id" }, id), title && /*#__PURE__*/React__default.createElement(Tooltip, { text: title, isVisible: isTitleTruncated }, /*#__PURE__*/React__default.createElement("span", { className: "searchResultRow__title ellipsis-text", ref: titleRef }, title))), (name || date) && /*#__PURE__*/React__default.createElement("div", { className: "searchResultRow__nameWrapper" }, name && /*#__PURE__*/React__default.createElement(Tooltip, { text: name, isVisible: isNameTruncated }, /*#__PURE__*/React__default.createElement("span", { className: "searchResultRow__name ellipsis-text", ref: nameRef }, name)), name && date && /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-dot", className: "searchResultRow__dateSeparator" }), date && /*#__PURE__*/React__default.createElement("div", { className: "searchResultRow__dateWrapper" }, date.labelText && /*#__PURE__*/React__default.createElement("span", { className: "searchResultRow__dateText" }, date.labelText), date.date && /*#__PURE__*/React__default.createElement("span", { className: "searchResultRow__date" }, date.date)))), /*#__PURE__*/React__default.createElement("div", { className: classnames('searchResultRow__actions', { 'searchResultRow__actions-hover': isFocused }) }, actions === null || actions === void 0 ? void 0 : actions.map((action, index) => /*#__PURE__*/React__default.createElement(Tooltip, { key: index, text: action === null || action === void 0 ? void 0 : action.description, isVisible: !!(action !== null && action !== void 0 && action.description), alwaysShow: !!(action !== null && action !== void 0 && action.description) && index === focusedIndex }, /*#__PURE__*/React__default.createElement(Button, { tabIndex: 0, size: "medium", icon: action.icon, onBlur: handleBlur, appearance: "minimal", onFocus: () => { handleFocus(index); }, cornerRadius: "smooth", onClick: () => action === null || action === void 0 ? void 0 : action.onClick(element), className: "searchResultRow__action", ariaLabel: action.name || action.icon }))))); } SearchResultRow.defaultProps = { element: {} }; SearchResultRow.propTypes = { element: PropTypes.shape({ icon: PropTypes.string, id: PropTypes.string, title: PropTypes.string, type: PropTypes.string, name: PropTypes.string, date: PropTypes.shape({ labelText: PropTypes.string, date: PropTypes.oneOfType([PropTypes.instanceOf(dayjs), PropTypes.instanceOf(Date), PropTypes.string, PropTypes.number]) }), actions: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, icon: PropTypes.string.isRequired, onClick: PropTypes.func, description: PropTypes.string })) }) }; function SearchResult(_ref) { let { data, totalCount, noDataText, initialData, showMoreText, totalCountMax, totalCountText, onShowMoreClick, isSearchLoading, showMoreIsLoading, hasActiveShowMore, initialDataDescription } = _ref; const listRef = useRef(null); const scrollbarRef = useRef(null); const [ableToScroll, setAbleToScroll] = useState(false); const [dataLengthSnapshots, setDataLengthSnapshots] = useState([]); const [elementTopToScroll, setElementTopToScroll] = useState(0); const onShowMoreHandler = useCallback(e => { onShowMoreClick(e); setAbleToScroll(true); }, []); useEffect(() => { setDataLengthSnapshots(prev => [...prev, data.length]); }, [data.length]); useEffect(() => { var _listRef$current, _listRef$current$chil; // Formula for getting the top of the element and adding 29px for showing showMore link and half of the last visible row. const scrollToElementTop = +(listRef === null || listRef === void 0 ? void 0 : (_listRef$current = listRef.current) === null || _listRef$current === void 0 ? void 0 : (_listRef$current$chil = _listRef$current.children[dataLengthSnapshots[dataLengthSnapshots.length - 2] - 1]) === null || _listRef$current$chil === void 0 ? void 0 : _listRef$current$chil.offsetTop) + 29; if (!isSearchLoading && ableToScroll) { setElementTopToScroll(scrollToElementTop); setAbleToScroll(false); } }, [isSearchLoading]); return /*#__PURE__*/React__default.createElement("div", { className: "searchResult" }, isSearchLoading && /*#__PURE__*/React__default.createElement(SkeletonSet, { searchResult: true, count: 8 }), /*#__PURE__*/React__default.createElement(CustomScrollbar, { autoHeightMax: 500, className: classnames('searchResult__scrollbar', { 'searchResult__scrollbar-loading': isSearchLoading }), ref: scrollbarRef, scrollTop: elementTopToScroll, withSmoothScroll: true }, /*#__PURE__*/React__default.createElement("div", { className: "searchResult__header" }, /*#__PURE__*/React__default.createElement("span", { className: "searchResult__text" }, totalCount > 0 && totalCountText || initialData.length > 0 && initialDataDescription), totalCount > 0 && /*#__PURE__*/React__default.createElement(Badge, { className: "searchResult__badge", count: totalCount, maxCount: totalCountMax, size: "default", color: "primary" })), (data === null || data === void 0 ? void 0 : data.length) > 0 || initialData.length > 0 ? /*#__PURE__*/React__default.createElement("ul", { className: "searchResult__list", role: "navigation", ref: listRef }, initialData.length > 0 ? initialData.map((elem, index) => /*#__PURE__*/React__default.createElement(SearchResultRow, { key: index, element: elem })) : data === null || data === void 0 ? void 0 : data.map((elem, index) => /*#__PURE__*/React__default.createElement(SearchResultRow, { key: index, element: elem })), hasActiveShowMore && /*#__PURE__*/React__default.createElement("li", { className: "searchResult__showMoreLi" }, /*#__PURE__*/React__default.createElement(LinkButton, { tabIndex: 0, ariaLabel: showMoreText, onClick: onShowMoreHandler, className: "searchResult__showMoreLink" }, showMoreText))) : /*#__PURE__*/React__default.createElement(Empty, { appearance: "without-circles", title: noDataText, type: "search", className: "searchResult__empty" }))); } SearchResult.defaultProps = { initialDataDescription: 'initial data description', isSearchLoading: false, showMoreIsLoading: false }; SearchResult.propTypes = { /** * total count of data to show in badge */ totalCount: PropTypes.number, /** * text for no data to display */ noDataText: PropTypes.string, /** * If search field is empty, will show initialData for example (Recently modified data). */ initialData: PropTypes.arrayOf(PropTypes.shape({ icon: PropTypes.string, id: PropTypes.string, title: PropTypes.string, type: PropTypes.string, name: PropTypes.string, date: PropTypes.shape({ labelText: PropTypes.string, date: PropTypes.oneOfType([PropTypes.instanceOf(dayjs), PropTypes.instanceOf(Date), PropTypes.string, PropTypes.number]) }), actions: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, icon: PropTypes.string.isRequired, onClick: PropTypes.func, description: PropTypes.string })) })), /** * text for link under search result */ showMoreText: PropTypes.string, /** * total max count of data to show totalCountMax+ in badge */ totalCountMax: PropTypes.number, /** * label text for badge component */ totalCountText: PropTypes.string, /** * Fires an event when clicked on link under search result */ onShowMoreClick: PropTypes.func, /** * To control showMore loading state */ showMoreIsLoading: PropTypes.bool, /** * search loading state */ isSearchLoading: PropTypes.bool, /** * if hasActive hasActiveShowMore is true you will see show more link under search result */ hasActiveShowMore: PropTypes.bool, /** * If search field is empty, initialDataDescription is describing witch data is showing by default for example (Recently modified data). */ initialDataDescription: PropTypes.string, /** * data structure * */ data: PropTypes.arrayOf(PropTypes.shape({ icon: PropTypes.string, id: PropTypes.string, title: PropTypes.string, type: PropTypes.string, name: PropTypes.string, date: PropTypes.shape({ labelText: PropTypes.string, date: PropTypes.oneOfType([PropTypes.instanceOf(dayjs), PropTypes.instanceOf(Date), PropTypes.string, PropTypes.number]) }), actions: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, icon: PropTypes.string.isRequired, onClick: PropTypes.func, description: PropTypes.string })) })) }; function Content(_ref) { let { data, totalCount, noDataText, initialData, showMoreText, totalCountMax, totalCountText, isSearchLoading, onShowMoreClick, hasActiveShowMore, primaryFilterData, secondaryFilterData, initialDataDescription } = _ref; const [clonedPrimaryFilterData, setClonedPrimaryFilterData] = useState({ ...primaryFilterData }); const [clonedSecondaryFilterData, setClonedSecondaryFilterData] = useState({ ...secondaryFilterData }); useEffect(() => setClonedPrimaryFilterData({ ...primaryFilterData }), [primaryFilterData]); useEffect(() => setClonedSecondaryFilterData({ ...secondaryFilterData }), [secondaryFilterData]); const newFilterData = useCallback((clonedData, selectedElement) => ({ ...clonedData, data: clonedData === null || clonedData === void 0 ? void 0 : clonedData.data.map(elem => { if (elem.id === selectedElement.id) { elem.checked = !elem.checked; } return elem; }) }), []); const handleSelectPrimary = useCallback(selectedElement => { const newPrimaryFilterData = newFilterData(clonedPrimaryFilterData, selectedElement); setClonedPrimaryFilterData(newPrimaryFilterData); primaryFilterData.onChange(newPrimaryFilterData.data); }, [clonedPrimaryFilterData]); const handleSelectSecondary = useCallback(selectedElement => { const newSecondaryFilterData = newFilterData(clonedSecondaryFilterData, selectedElement); setClonedSecondaryFilterData(newSecondaryFilterData); secondaryFilterData.onChange(newSecondaryFilterData.data); }, [clonedSecondaryFilterData.data]); const skeletonCount = useMemo(() => primaryFilterData && secondaryFilterData ? 5 : 11, [primaryFilterData, secondaryFilterData]); return /*#__PURE__*/React__default.createElement("div", { className: "advancedSearch__content" }, /*#__PURE__*/React__default.createElement("div", { className: classnames('advancedSearch__searchResult', { 'advancedSearch__searchResult-border': primaryFilterData || secondaryFilterData }) }, /*#__PURE__*/React__default.createElement(SearchResult, { data: data, noDataText: noDataText, totalCount: totalCount, initialData: initialData, showMoreText: showMoreText, totalCountMax: totalCountMax, totalCountText: totalCountText, onShowMoreClick: onShowMoreClick, isSearchLoading: isSearchLoading, hasActiveShowMore: hasActiveShowMore, initialDataDescription: initialDataDescription })), (primaryFilterData || secondaryFilterData) && /*#__PURE__*/React__default.createElement("div", { className: "advancedSearch__filters" }, primaryFilterData && /*#__PURE__*/React__default.createElement(FilterList, { data: primaryFilterData, skeletonCount: skeletonCount, onSelect: handleSelectPrimary }), secondaryFilterData && primaryFilterData && /*#__PURE__*/React__default.createElement("div", { className: "advancedSearch__divider" }), secondaryFilterData && /*#__PURE__*/React__default.createElement(FilterList, { data: secondaryFilterData, skeletonCount: skeletonCount, onSelect: handleSelectSecondary }))); } Content.defaultProps = {}; Content.propTypes = {}; var css_248z = "[data-gene-ui-version=\"2.16.5\"] .advancedSearch{margin-left:auto;margin-right:0;min-height:3.6rem;min-width:10rem;position:relative;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}[data-gene-ui-version=\"2.16.5\"] .advancedSearch-left{margin-left:0;margin-right:auto}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__wrapper{color:rgba(var(--background-sc-rgb),.75);left:auto;max-width:var(--advanced-search-width);position:absolute;right:0;top:0;width:100vw}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__wrapper-left{left:0;right:auto}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__popover{min-height:50rem;width:var(--advanced-search-width)}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__content{color:rgba(var(--background-sc-rgb),.75);display:flex;height:52rem;justify-content:space-between;max-height:50rem!important}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__searchResult{flex-grow:3;height:auto;max-height:100%}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__searchResult-border{border-left:none;border-right:1px solid rgba(var(--background-sc-rgb),.3)}[data-gene-ui-version=\"2.16.5\"] [dir=rtl] .advancedSearch__searchResult-border{border-left:1px solid rgba(var(--background-sc-rgb),.3);border-right:none}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__filters{width:27rem}[data-gene-ui-version=\"2.16.5\"] .advancedSearch__divider{border-bottom:1px solid rgba(var(--background-sc-rgb),.3)}[data-gene-ui-version=\"2.16.5\"] .filterList__filter{height:50%;min-height:50%;padding:.8rem 0;padding-inline-end:0;width:100%}[data-gene-ui-version=\"2.16.5\"] .filterList__filterHeader{font-size:1.2rem;padding:.8rem}[data-gene-ui-version=\"2.16.5\"] .filterList__filterList{display:flex;flex-direction:column}[data-gene-ui-version=\"2.16.5\"] .filterList__showMoreLi{margin:.8rem}[data-gene-ui-version=\"2.16.5\"] .filterList__showMoreLink{padding:.4rem .8rem}[data-gene-ui-version=\"2.16.5\"] .listElementWithCheckbox{align-items:center;display:flex;flex-wrap:nowrap;height:4rem;padding:0 1.6rem}[data-gene-ui-version=\"2.16.5\"] .listElementWithCheckbox-hover,[data-gene-ui-version=\"2.16.5\"] .listElementWithCheckbox:hover{background:rgba(var(--background-sc-rgb),.03)}[data-gene-ui-version=\"2.16.5\"] .listElementWithCheckbox__label{align-items:center;cursor:pointer;display:flex;-webkit-user-select:none;user-select:none;width:100%}[data-gene-ui-version=\"2.16.5\"] .listElementWithCheckbox__icon,[data-gene-ui-version=\"2.16.5\"] .listElementWithCheckbox__name{margin-inline-start:.8rem}[data-gene-ui-version=\"2.16.5\"] .searchResult{height:100%;padding:.8rem 0;padding-inline-end:0;position:relative}[data-gene-ui-version=\"2.16.5\"] .searchResult__scrollbar{height:100%}[data-gene-ui-version=\"2.16.5\"] .searchResult__scrollbar-loading{visibility:hidden}[data-gene-ui-version=\"2.16.5\"] .searchResult__header{align-items:center;display:flex;justify-content:flex-start;padding:.8rem;width:100%}[data-gene-ui-version=\"2.16.5\"] .searchResult__list{width:100%}[data-gene-ui-version=\"2.16.5\"] .searchResult__text{font-size:1.2rem}[data-gene-ui-version=\"2.16.5\"] .searchResult__badge{margin-inline-start:.8rem}[data-gene-ui-version=\"2.16.5\"] .searchResult__showMoreLi{margin:.8rem;padding:.8rem 0;padding-inline-start:.8rem}[data-gene-ui-version=\"2.16.5\"] .searchResult__showMoreLink{padding:.4rem}[data-gene-ui-version=\"2.16.5\"] .searchResult__empty{height:calc(100% - 5.5rem)}[data-gene-ui-version=\"2.16.5\"] .searchResultRow{align-items:center;display:flex;height:4.5rem;justify-content:space-between;margin:.4rem 0;max-width:100%;padding:.4rem .8rem;width:100%}[data-gene-ui-version=\"2.16.5\"] .searchResultRow-hover,[data-gene-ui-version=\"2.16.5\"] .searchResultRow:hover{background:rgba(var(--background-sc-rgb),.03)}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__icon{padding:0 .8rem}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__info{display:flex;flex-direction:column;flex-grow:2;height:100%;justify-content:space-between;overflow:hidden;padding-inline-start:.8rem;width:100%}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__titleWrapper{align-items:center;display:flex;font-weight:600}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__id{color:rgba(var(--background-sc-rgb),.6);margin-inline-end:.8rem}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__title{color:var(--background-sc-rgb)}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__nameWrapper{align-items:center;color:rgba(var(--background-sc-rgb),.6);display:flex;flex-wrap:nowrap}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__name{font-size:1.2rem;white-space:nowrap}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__dateSeparator{font-size:1.2rem;padding-top:.3rem}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__dateWrapper{align-items:center;display:flex;font-size:1rem;padding-top:.3rem}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__dateText{font-style:italic;margin-inline-end:.4rem}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__actions{display:flex;height:100%}[data-gene-ui-version=\"2.16.5\"] .searchResultRow__action{color:var(--hero);cursor:pointer;margin:0 .4rem}[data-gene-ui-version=\"2.16.5\"] .skeleton{height:100%;left:0;position:absolute;top:0;width:100%}[data-gene-ui-version=\"2.16.5\"] .skeleton__filter{align-items:center;display:flex;flex-wrap:nowrap;height:4rem;padding:0 .8rem}[data-gene-ui-version=\"2.16.5\"] .skeleton__searchElement{align-items:center;display:flex;height:44px;margin:1.5rem .8rem;padding-inline-end:.8rem}"; styleInject(css_248z); function AdvancedSearch(_ref) { let { data, isOpen, position, onSearch, totalCount, noDataText, initialData, showMoreText, totalCountMax, totalCountText, onOutsideClick, onShowMoreClick, isSearchLoading, openedInputWidth, closedInputWidth, hasActiveShowMore, primaryFilterData, secondaryFilterData, extendedInputConfigs, initialDataDescription } = _ref; const parentRef = useRef(null); const searchRef = useRef(null); const [popoverOpen, setPopoverOpen] = useState(false); const [initialDataState, setInitialDataState] = useState([]); const [searchValue, setSearchValue] = useState(null); const debouncedSearchValue = useDebounce(searchValue, 300); const isOpenControlled = useMemo(() => isOpen !== undefined, [isOpen]); useEffect(() => { if (debouncedSearchValue === null) return; onSearch(debouncedSearchValue); }, [debouncedSearchValue]); const openPopoverHandler = e => { e && (e.currentTarget.onFocus = true); if (!popoverOpen) setPopoverOpen(true); }; const closePopoverHandler = useCallback(() => setPopoverOpen(false), []); useKeyDown(e => { var _searchRef$current; switch (e.key) { case 'Escape': (searchRef === null || searchRef === void 0 ? void 0 : searchRef.current) && (searchRef === null || searchRef === void 0 ? void 0 : (_searchRef$current = searchRef.current) === null || _searchRef$current === void 0 ? void 0 : _searchRef$current.blur()); closePopoverHandler(); break; } }, [close, focus, blur, popoverOpen], parentRef, ['Escape']); // initial data setter useEffect(() => { setInitialDataState((debouncedSearchValue === null || debouncedSearchValue === void 0 ? void 0 : debouncedSearchValue.length) > 0 ? [] : initialData); }, [debouncedSearchValue]); const inputAndPopoverWidthVariable = useMemo(() => ({ '--advanced-search-width': (isOpenControlled ? isOpen : popoverOpen) ? "".concat(openedInputWidth, "vw") : closedInputWidth }), [popoverOpen, isOpenControlled, isOpen, openedInputWidth, closedInputWidth]); const handleOutsideClick = useClickOutside(onOutsideClick); return /*#__PURE__*/React__default.createElement("div", { className: classnames('advancedSearch', { 'advancedSearch-left': position === advancedSearchConfig.positions.left }), ref: handleOutsideClick }, /*#__PURE__*/React__default.createElement("div", { className: classnames('advancedSearch__wrapper', { 'advancedSearch__wrapper-left': position === advancedSearchConfig.positions.left }), style: inputAndPopoverWidthVariable, ref: parentRef }, /*#__PURE__*/React__default.createElement(PopoverV2, { position: "bottom", screenType: "desktop", isOpen: isOpenControlled ? isOpen : popoverOpen, scrollbarNeeded: false, extendTargetWidth: false, className: "advancedSearch__popover", onClickOutside: closePopoverHandler, containerParent: parentRef === null || parentRef === void 0 ? void 0 : parentRef.current, Content: /*#__PURE__*/React__default.createElement(Content, { data: data, noDataText: noDataText, totalCount: totalCount, showMoreText: showMoreText, totalCountMax: totalCountMax, initialData: initialDataState, totalCountText: totalCountText, onShowMoreClick: onShowMoreClick, isSearchLoading: isSearchLoading, primaryFilterData: primaryFilterData, hasActiveShowMore: hasActiveShowMore, secondaryFilterData: secondaryFilterData, initialDataDescription: initialDataDescription }) }, /*#__PURE__*/React__default.createElement(ExtendedInput, _extends({ canClear: true, clickableIcon: true, ref: searchRef, value: searchValue, description: false, icon: "bc-icon-search", flexibility: "content-size", onChange: _ref2 => { let { target } = _ref2; return setSearchValue(target.value); }, onClick: openPopoverHandler, onFocus: openPopoverHandler, placeholder: "Advanced Search", className: "advancedSearch__extendedInput" }, extendedInputConfigs)))), /*#__PURE__*/React__default.createElement("div", { "data-comment": "for-popover-accessibility-to-close", tabIndex: "0", style: { height: 0, width: 0, opacity: 0 }, onFocus: closePopoverHandler })); } AdvancedSearch.propTypes = { /** * Position of the AdvancedSearch component. * If set to 'right', it will stretch from right to left, and if set to 'left', it will stretch from left to right. * By default, the component stretches from right to left. */ position: PropTypes.oneOf(Object.values(advancedSearchConfig.positions)), /** * Width of closed AdvancedSearch input. * if you set number it will be px, or you can set string for Example 20vw */ closedInputWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** * Width of opened AdvancedSearch input. * It can be only with a number and it will be converted to vw(viewport's width), which is equal to viewport % */ openedInputWidth: PropTypes.number, /** * See ExtendedInput components docs */ extendedInputConfigs: PropTypes.shape({ ...ExtendedInput.propTypes }), /** * data structure for primary filter */ primaryFilterData: PropTypes.shape({ sectionNameText: PropTypes.string, onChange: PropTypes.func, hasActiveShowMore: PropTypes.bool, showMoreText: PropTypes.string, showMoreIsLoading: PropTypes.bool, onShowMoreClick: PropTypes.func, isLoading: PropTypes.bool, data: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, value: PropTypes.string, checked: PropTypes.bool, icon: PropTypes.string, id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) })) }), /** * data structure for secondary filter */ secondaryFilterData: PropTypes.shape({ sectionNameText: PropTypes.string, onChange: PropTypes.func, hasActiveShowMore: PropTypes.bool, showMoreText: PropTypes.string, showMoreIsLoading: PropTypes.bool, onShowMoreClick: PropTypes.func, isLoading: PropTypes.bool, data: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, value: PropTypes.string, checked: PropTypes.bool, icon: PropTypes.string, id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) })) }), /** * Fires event when a user clicks outside from the component. */ onSearch: PropTypes.func, /** * Fires event when user clicks on outside of component. */ onOutsideClick: PropTypes.func, /** * If search field is empty, initialDataDescription is describing witch data is showing by default for example (Recently modified data). */ initialDataDescription: PropTypes.string, /** * If search field is empty, will show initialData for example (Recently modified data). */ initialData: PropTypes.arrayOf(PropTypes.shape({ icon: PropTypes.string, id: PropTypes.string, title: PropTypes.string, type: PropTypes.string, name: PropTypes.string, date: PropTypes.shape({ labelText: PropTypes.string, date: PropTypes.oneOfType([PropTypes.instanceOf(dayjs), PropTypes.instanceOf(Date), PropTypes.string, PropTypes.number]) }), actions: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, icon: PropTypes.string.isRequired, onClick: PropTypes.func, description: PropTypes.string })) })), /** * if hasActive hasActiveShowMore is true you will see show more link under search result */ hasActiveShowMore: PropTypes.bool, /** * text for link under search result */ showMoreText: PropTypes.string, /** * To control showMore loading state */ showMoreIsLoading: PropTypes.bool, /** * Fires an event when clicked on link under search result */ onShowMoreClick: PropTypes.func, /** * search loading state */ isSearchLoading: PropTypes.bool, /** * total count of data to show in badge */ totalCount: PropTypes.number, /** * total max count of data to show totalCountMax+ in badge */ totalCountMax: PropTypes.number, /** * label text for badge component */ totalCountText: PropTypes.string, /** * data structure * */ data: PropTypes.arrayOf(PropTypes.shape({ icon: PropTypes.string, id: PropTypes.string, title: PropTypes.string, type: PropTypes.string, name: PropTypes.string, date: PropTypes.shape({ labelText: PropTypes.string, date: PropTypes.oneOfType([PropTypes.instanceOf(dayjs), PropTypes.instanceOf(Date), PropTypes.string, PropTypes.number]) }), actions: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, icon: PropTypes.string.isRequired, onClick: PropTypes.func, description: PropTypes.string })) })), /** * text for no data to display */ noDataText: PropTypes.string, /** * A boolean prop to control the popover's open and close state. */ isOpen: PropTypes.bool }; AdvancedSearch.defaultProps = { onSearch: noop, openedInputWidth: 65, onShowMoreClick: noop, onOutsideClick: noop, closedInputWidth: '200px', hasActiveShowMore: false, showMoreIsLoading: false, showMoreText: 'Show more', noDataText: 'No Data to Display', position: advancedSearchConfig.positions.right, initialDataDescription: 'initial data description' }; export { AdvancedSearch as default };