react-search-highlight
Advanced tools
Comparing version 0.1.3 to 0.1.4
import React, { ReactNode } from 'react'; | ||
import { CHARACTER_MATCHING, STRING_MATCHING } from '../const'; | ||
import { ContextType } from '../types'; | ||
@@ -11,3 +12,10 @@ /** | ||
updateInternalContext: any; | ||
/** | ||
* Need for popover list active index keydown | ||
*/ | ||
dataLength: number; | ||
/** | ||
* Need while rendering highlighted words | ||
*/ | ||
matchingAlgorithm?: typeof CHARACTER_MATCHING | typeof STRING_MATCHING; | ||
} | ||
@@ -20,7 +28,7 @@ export declare const InternalContext: React.Context<InternalContextInitialStateType>; | ||
} | ||
export declare const Wrapper: ({ children }: Pick<WrapperProps, 'children'>) => JSX.Element; | ||
export declare const Wrapper: React.ForwardRefExoticComponent<Pick<WrapperProps, "children"> & React.RefAttributes<HTMLDivElement>>; | ||
export interface PopOverListProps extends React.OlHTMLAttributes<HTMLUListElement> { | ||
children: ReactNode; | ||
} | ||
export declare const PopOverList: React.FC<PopOverListProps>; | ||
export declare const PopOverList: React.ForwardRefExoticComponent<PopOverListProps & React.RefAttributes<HTMLUListElement>>; | ||
export interface PopOverOptionProps extends React.LiHTMLAttributes<HTMLLIElement> { | ||
@@ -27,0 +35,0 @@ children: ReactNode; |
import React from 'react'; | ||
import { CHARACTER_MATCHING, DEBOUNCE, DEFAULT, STRING_MATCHING, THROTTLE } from '../../const'; | ||
export declare const inputAlgorithms: Record<string, any>; | ||
export declare const matchingAlgorithms: Record<string, any>; | ||
export interface Props extends React.InputHTMLAttributes<HTMLInputElement> { | ||
@@ -14,2 +16,2 @@ data: any[]; | ||
} | ||
export declare const SearchBar: React.FC<Props>; | ||
export declare const SearchBar: React.ForwardRefExoticComponent<Props & React.RefAttributes<unknown>>; |
@@ -6,3 +6,4 @@ export * from "./useCharacterMatching"; | ||
export * from "./useOffScreen"; | ||
export * from "./useRefComposition"; | ||
export * from "./useStringMatching"; | ||
export * from "./useThrottle"; |
@@ -96,3 +96,3 @@ 'use strict'; | ||
return newObj[key] = obj[key].replaceAll(regex, function (match) { | ||
return "(<mark>" + match + "</mark>)"; | ||
return "<mark>" + match + "<mark>"; | ||
}); | ||
@@ -312,2 +312,18 @@ }); | ||
/** | ||
* useRefComposition combines multiple refs into a single composed ref | ||
* @param refs - Array of refs | ||
* @returns callback function to update ref | ||
*/ | ||
var useRefComposition = function useRefComposition(refs) { | ||
return function (el) { | ||
refs.forEach(function (ref) { | ||
if (ref === null) return; | ||
if (typeof ref === 'function') ref(el);else ref.current = el; | ||
}); | ||
}; | ||
}; | ||
/** | ||
* @param keys - keys to search for from available data | ||
@@ -420,4 +436,3 @@ * @returns {callback} - dispatches action to update search results after matching strings | ||
var InternalContext = /*#__PURE__*/React.createContext(InternalContextInitialState); | ||
var WrapperInner = function WrapperInner(_ref) { | ||
var WrapperInner = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef) { | ||
var children = _ref.children, | ||
@@ -441,2 +456,3 @@ isFunction = _ref.isFunction; | ||
var listRef = React.useRef(null); | ||
var composedRefs = useRefComposition([listRef, forwardedRef]); | ||
@@ -455,3 +471,3 @@ var _useOffScreen = useOffScreen(listRef), | ||
}, React__default.createElement("section", { | ||
ref: listRef, | ||
ref: composedRefs, | ||
className: "rsh-search-wrapper", | ||
@@ -466,20 +482,22 @@ | ||
}, isFunction ? children(__state) : children)); | ||
}; | ||
var Wrapper = function Wrapper(_ref2) { | ||
}); | ||
var Wrapper = /*#__PURE__*/React__default.forwardRef(function (_ref2, forwardedRef) { | ||
var children = _ref2.children; | ||
var isFunction = typeof children === 'function'; | ||
return React__default.createElement(React__default.Fragment, null, isFunction ? React__default.createElement(ReactSearchHighlightProvider, null, React__default.createElement(WrapperInner, { | ||
ref: forwardedRef, | ||
isFunction: isFunction, | ||
children: children | ||
})) : React__default.createElement(WrapperInner, { | ||
ref: forwardedRef, | ||
isFunction: isFunction, | ||
children: children | ||
})); | ||
}; | ||
var PopOverList = function PopOverList(_ref3) { | ||
}); | ||
var PopOverList = /*#__PURE__*/React__default.forwardRef(function (_ref3, forwardedRef) { | ||
var children = _ref3.children, | ||
any = _objectWithoutPropertiesLoose(_ref3, _excluded$1); | ||
var listRef = React.useRef(null); | ||
var _useReactSearchHighli = useReactSearchHighlight(), | ||
suggestions = _useReactSearchHighli.suggestions; | ||
@@ -489,7 +507,6 @@ var _React$useContext = React__default.useContext(InternalContext), | ||
listItemActiveIndex = _React$useContext.listItemActiveIndex, | ||
updateInternalContext = _React$useContext.updateInternalContext, | ||
dataLength = _React$useContext.dataLength; | ||
updateInternalContext = _React$useContext.updateInternalContext; | ||
var listItemActiveIndexArrowDown = function listItemActiveIndexArrowDown() { | ||
if (listItemActiveIndex < dataLength - 1) updateInternalContext('listItemActiveIndex', listItemActiveIndex + 1); | ||
if (listItemActiveIndex < suggestions.length - 1) updateInternalContext('listItemActiveIndex', listItemActiveIndex + 1); | ||
}; | ||
@@ -501,9 +518,10 @@ | ||
useKeyDown(listItemActiveIndexArrowDown, false, 'arrowdown', [listItemActiveIndex, dataLength]); | ||
useKeyDown(listItemActiveIndexArrowDown, false, 'arrowdown', [listItemActiveIndex, suggestions.length]); | ||
useKeyDown(listItemActiveIndexArrowUp, false, 'arrowup', [listItemActiveIndex]); | ||
return React__default.createElement(React__default.Fragment, null, isPopoverExpanded && React__default.createElement("ul", Object.assign({ | ||
ref: listRef, | ||
"data-popover-expanded": isPopoverExpanded, | ||
ref: forwardedRef, | ||
className: "rsh-search-list" | ||
}, any), children)); | ||
}; | ||
}); | ||
var PopOverOption = function PopOverOption(_ref4) { | ||
@@ -530,11 +548,20 @@ var children = _ref4.children, | ||
var PopOverOptionText = function PopOverOptionText(_ref5) { | ||
var _as; | ||
var className = _ref5.className, | ||
value = _ref5.value, | ||
as = _ref5.as, | ||
_ref5$as = _ref5.as, | ||
as = _ref5$as === void 0 ? 'h3' : _ref5$as, | ||
any = _objectWithoutPropertiesLoose(_ref5, _excluded3); | ||
var words = value == null ? void 0 : value.split(/\(([^)]+)\)/); | ||
as = (_as = as) != null ? _as : 'h3'; | ||
var _useReactSearchHighli2 = useReactSearchHighlight(), | ||
input = _useReactSearchHighli2.input; | ||
var _React$useContext3 = React__default.useContext(InternalContext), | ||
matchingAlgorithm = _React$useContext3.matchingAlgorithm; | ||
var words = value == null ? void 0 : value.split(/<mark>/); | ||
var isHighlighted = function isHighlighted(word) { | ||
return matchingAlgorithm === STRING_MATCHING ? word.toLocaleLowerCase() === input : input.includes(word.toLocaleLowerCase()); | ||
}; | ||
return React__default.createElement(Text, Object.assign({ | ||
@@ -544,9 +571,9 @@ as: as, | ||
}, any), words == null ? void 0 : words.map(function (word, index) { | ||
return word[0] === '<' ? React__default.createElement("span", { | ||
key: index, | ||
dangerouslySetInnerHTML: { | ||
__html: word | ||
} | ||
}) : React__default.createElement("span", { | ||
key: index | ||
return isHighlighted(word) ? React__default.createElement("span", { | ||
key: word + "-" + index, | ||
"data-user-value": true, | ||
"data-suggested-value": true, | ||
"data-heightlighted-value": true | ||
}, word) : React__default.createElement("span", { | ||
key: word + "-" + index | ||
}, word); | ||
@@ -606,12 +633,39 @@ })); | ||
var searchIcon = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n<svg version=\"1.1\" id=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\" style=\"enable-background:new 0 0 16 16;\" xml:space=\"preserve\">\n<style type=\"text/css\">\n\t.st0{fill:none;}\n</style>\n<title>search</title>\n<path d=\"M15,14.3L10.7,10c1.9-2.3,1.6-5.8-0.7-7.7S4.2,0.7,2.3,3S0.7,8.8,3,10.7c2,1.7,5,1.7,7,0l4.3,4.3L15,14.3z M2,6.5\n\tC2,4,4,2,6.5,2S11,4,11,6.5S9,11,6.5,11S2,9,2,6.5z\"/>\n<rect id=\"_Transparent_Rectangle_\" class=\"st0\" width=\"16\" height=\"16\"/>\n</svg>"; | ||
var SearchIcon = function SearchIcon() { | ||
return React__default.createElement("svg", { | ||
width: "18", | ||
height: "18", | ||
viewBox: "0 0 14 14", | ||
fill: "none", | ||
xmlns: "http://www.w3.org/2000/svg" | ||
}, React__default.createElement("path", { | ||
d: "M14 13.3L9.70001 9.00001C11.6 6.70001 11.3 3.20001 9.00001 1.30001C6.70001 -0.599986 3.20001 -0.299986 1.30001 2.00001C-0.599986 4.30001 -0.299986 7.80001 2.00001 9.70001C4.00001 11.4 7.00001 11.4 9.00001 9.70001L13.3 14L14 13.3ZM1.00001 5.50001C1.00001 3.00001 3.00001 1.00001 5.50001 1.00001C8.00001 1.00001 10 3.00001 10 5.50001C10 8.00001 8.00001 10 5.50001 10C3.00001 10 1.00001 8.00001 1.00001 5.50001Z", | ||
fill: "black" | ||
})); | ||
}; | ||
var _excluded$3 = ["keysToSearch", "inputAlgorithm", "matchingAlgorithm", "data", "value", "onChange", "initialValue", "PrefixIcon"]; | ||
var _excluded$3 = ["keysToSearch", "inputAlgorithm", "matchingAlgorithm", "data", "value", "inputAlgorithmTimeout", "onChange", "initialValue", "PrefixIcon"]; | ||
var inputAlgorithms = { | ||
DEBOUNCE: useDebounce, | ||
THROTTLE: useThrottle, | ||
DEFAULT: function DEFAULT(e) { | ||
return e; | ||
} | ||
}; | ||
var matchingAlgorithms = { | ||
CHARACTER_MATCHING: useCharacterMatching, | ||
STRING_MATCHING: useStringMatching | ||
}; | ||
var SearchBar = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef) { | ||
var _keysToSearch; | ||
var Input = function Input(_ref) { | ||
var keysToSearch = _ref.keysToSearch, | ||
inputAlgorithm = _ref.inputAlgorithm, | ||
matchingAlgorithm = _ref.matchingAlgorithm, | ||
_ref$inputAlgorithm = _ref.inputAlgorithm, | ||
inputAlgorithm = _ref$inputAlgorithm === void 0 ? DEBOUNCE : _ref$inputAlgorithm, | ||
_ref$matchingAlgorith = _ref.matchingAlgorithm, | ||
matchingAlgorithm = _ref$matchingAlgorith === void 0 ? CHARACTER_MATCHING : _ref$matchingAlgorith, | ||
data = _ref.data, | ||
controlledValue = _ref.value, | ||
_ref$inputAlgorithmTi = _ref.inputAlgorithmTimeout, | ||
inputAlgorithmTimeout = _ref$inputAlgorithmTi === void 0 ? 500 : _ref$inputAlgorithmTi, | ||
onChange = _ref.onChange, | ||
@@ -631,6 +685,8 @@ initialValue = _ref.initialValue, | ||
keysToSearch = (_keysToSearch = keysToSearch) != null ? _keysToSearch : Object.keys(data == null ? void 0 : data[0]); | ||
var inputRef = React.useRef(null); | ||
var composedRefs = useRefComposition([inputRef, forwardedRef]); | ||
var searchInput = controlledValue != null ? controlledValue : input; | ||
var searchTerm = inputAlgorithm(searchInput, 500); | ||
var matchingFn = matchingAlgorithm(keysToSearch); | ||
var searchTerm = inputAlgorithms[inputAlgorithm](searchInput, inputAlgorithmTimeout); | ||
var matchingFn = matchingAlgorithms[matchingAlgorithm](keysToSearch); | ||
@@ -651,4 +707,4 @@ { | ||
React.useEffect(function () { | ||
if (__internalContext) __internalContext.updateInternalContext('dataLength', data.length); | ||
}, [data]); | ||
if (__internalContext) __internalContext.updateInternalContext('matchingAlgorithm', matchingAlgorithm); | ||
}, []); | ||
@@ -677,6 +733,3 @@ var focusInput = function focusInput() { | ||
className: "rsh-input-box-logo" | ||
}, PrefixIcon ? React__default.createElement(PrefixIcon, null) : React__default.createElement("img", { | ||
src: searchIcon, | ||
width: "18px" | ||
})), React__default.createElement("input", Object.assign({ | ||
}, PrefixIcon ? React__default.createElement(PrefixIcon, null) : React__default.createElement(SearchIcon, null)), React__default.createElement("input", Object.assign({ | ||
value: controlledValue != null ? controlledValue : input, | ||
@@ -687,42 +740,6 @@ onChange: onChange != null ? onChange : handleOnChange, | ||
autoFocus: true, | ||
ref: inputRef | ||
ref: composedRefs | ||
}, any))); | ||
}; | ||
}); | ||
var _excluded$4 = ["data", "keysToSearch", "inputAlgorithmTimeout", "inputAlgorithm", "matchingAlgorithm"]; | ||
var inputAlgorithms = { | ||
DEBOUNCE: useDebounce, | ||
THROTTLE: useThrottle, | ||
DEFAULT: function DEFAULT(e) { | ||
return e; | ||
} | ||
}; | ||
var matchingAlgorithms = { | ||
CHARACTER_MATCHING: useCharacterMatching, | ||
STRING_MATCHING: useStringMatching | ||
}; | ||
var SearchBar = function SearchBar(props) { | ||
var _keysToSearch, _inputAlgorithm, _inputAlgorithmTimeou, _matchingAlgorithm; | ||
var data = props.data, | ||
keysToSearch = props.keysToSearch, | ||
inputAlgorithmTimeout = props.inputAlgorithmTimeout, | ||
_props$inputAlgorithm = props.inputAlgorithm, | ||
inputAlgorithm = _props$inputAlgorithm === void 0 ? DEBOUNCE : _props$inputAlgorithm, | ||
matchingAlgorithm = props.matchingAlgorithm, | ||
any = _objectWithoutPropertiesLoose(props, _excluded$4); | ||
keysToSearch = (_keysToSearch = keysToSearch) != null ? _keysToSearch : Object.keys(data == null ? void 0 : data[0]); | ||
inputAlgorithm = (_inputAlgorithm = inputAlgorithm) != null ? _inputAlgorithm : DEBOUNCE; | ||
inputAlgorithmTimeout = (_inputAlgorithmTimeou = inputAlgorithmTimeout) != null ? _inputAlgorithmTimeou : 500; | ||
matchingAlgorithm = (_matchingAlgorithm = matchingAlgorithm) != null ? _matchingAlgorithm : CHARACTER_MATCHING; | ||
return React__default.createElement(Input, Object.assign({ | ||
keysToSearch: keysToSearch, | ||
duration: inputAlgorithmTimeout, | ||
inputAlgorithm: inputAlgorithms[inputAlgorithm], | ||
matchingAlgorithm: matchingAlgorithms[matchingAlgorithm], | ||
data: data | ||
}, any)); | ||
}; | ||
exports.CHARACTER_MATCHING = CHARACTER_MATCHING; | ||
@@ -750,3 +767,5 @@ exports.DEBOUNCE = DEBOUNCE; | ||
exports.initialState = initialState; | ||
exports.inputAlgorithms = inputAlgorithms; | ||
exports.matchingAlgorithms = matchingAlgorithms; | ||
exports.useReactSearchHighlight = useReactSearchHighlight; | ||
//# sourceMappingURL=react-search-highlight.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("process");var e,t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e;function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function i(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)t.indexOf(n=a[r])>=0||(i[n]=e[n]);return i}!function(e,t){void 0===t&&(t={});var n=t.insertAt;if("undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],i=document.createElement("style");i.type="text/css","top"===n&&r.firstChild?r.insertBefore(i,r.firstChild):r.appendChild(i),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(document.createTextNode(e))}}(".rsh-input:focus{outline:none}.rsh-search-wrapper{position:relative}.rsh-input-box{background-color:#fff;border:1px solid transparent;border-radius:5px;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);min-width:200px}.rsh-input-box-logo{align-items:center;display:flex;height:100%;justify-content:center;margin:0;width:40px}.rsh-input{border:none;border-radius:inherit;font-size:15px;height:100%;margin:0;padding:0;width:100%}.rsh-search-list{background-color:#fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);box-sizing:border-box;max-height:500px;min-width:200px;overflow-x:scroll;overflow:scroll;padding:0 8px;position:absolute;top:40px;width:100%;z-index:12}.rsh-search-list-item{border-radius:13px;list-style:none;margin:10px 0;padding:3px 8px}.rsh-search-list-item__active{background-color:hsla(0,0%,47%,.05)}.rsh-search-list-item-text{margin:0}");var a=function(e,t){switch(t.type){case"SET_INPUT":return r({},e,{input:t.payload});case"SEARCH_DATA":return r({},e,{searchData:t.payload});case"START_LOADING":return r({},e,{isLoading:!0});case"END_LOADING":return r({},e,{isLoading:!1});case"RESET_STATE":return r({},s);default:return e}},o=function(e,t,n){return n.some((function(n){return e[n].toLowerCase().includes(t)}))},u=function(e,t,n){var i=r({},e);return n.forEach((function(n){return i[n]=e[n].replaceAll(t,(function(e){return"(<mark>"+e+"</mark>)"}))})),i},s={isLoading:!1,searchData:[],input:""},c=t.createContext(null),l=function(){return t.useContext(c)},d=function(e){var r=e.children,i=t.useReducer(a,s),o=i[0],u=i[1],l=function(){u({type:"START_LOADING"})},d=function(){u({type:"END_LOADING"})},p=function(){u({type:"RESET_STATE"})},f=0===o.searchData.length&&o.input.length>0,h=t.useMemo((function(){return{suggestions:o.searchData,isLoading:o.isLoading,input:o.input,dispatch:u,startLoading:l,endLoading:d,resetState:p,isResultsEmpty:f}}),[o]);return n.createElement(c.Provider,{value:h},r)},p=["as","children","classNames"],f=function(e){var n=e.as,a=e.children,o=e.classNames,u=i(e,p);return t.createElement(n,r({className:o},u),a)},h=function(e,n,r,i){void 0===r&&(r="k"),void 0===i&&(i=[]),t.useEffect((function(){var t=function(t){(!n||t.metaKey)&&t.key.toLowerCase()===r&&(null==e||e())};return document.addEventListener("keydown",t),function(){document.removeEventListener("keydown",t)}}),i)},m=["children"],x=["children","optionIndex"],g=["className","value","as"],E={isPopoverExpanded:!1,listItemActiveIndex:0,updateInternalContext:function(e,t){},dataLength:0},v=t.createContext(E),A=function(e){var i,a,o,u=e.children,s=e.isFunction,c=t.useState(E),d=c[0],p=c[1],f=l(),h=function(e,t){p((function(n){var i;return r({},n,((i={})[e]=t,i))}))},m=t.useRef(null),x=function(e){var n=t.useState(!1),r=n[0],i=n[1];return t.useEffect((function(){function t(t){e.current&&!e.current.contains(t.target)&&i(!1)}return document.addEventListener("mousedown",t),function(){document.removeEventListener("mousedown",t)}}),[e]),[r,i]}(m),g=x[0],A=x[1];return i=function(){h("isPopoverExpanded",g)},a=[g],o=t.useRef(!1),t.useEffect((function(){o.current?i():o.current=!0}),a),n.createElement(v.Provider,{value:r({},d,{updateInternalContext:h})},n.createElement("section",{ref:m,className:"rsh-search-wrapper",onFocusCapture:function(){return A(!0)}},s?u(f):u))},T=["as","children","className","onClick","onMouseDown","onFocusCapture"],y=function(e){var t=e.as,a=e.children,o=e.className,u=e.onClick,s=e.onFocusCapture,c=i(e,T);return n.createElement("div",{style:r({display:"flex",flexDirection:"HStack"===t?"row":"column",alignItems:"center"},c),className:o,onClick:u,onFocusCapture:s},a)},C=["keysToSearch","inputAlgorithm","matchingAlgorithm","data","value","onChange","initialValue","PrefixIcon"],S=function(e){var r=e.keysToSearch,a=e.inputAlgorithm,o=e.matchingAlgorithm,u=e.data,s=e.value,c=e.onChange,d=e.initialValue,p=e.PrefixIcon,f=i(e,C),m=t.useState(null!=d?d:""),x=m[0],g=m[1],E=l().dispatch,A=n.useContext(v),T=t.useRef(null),S=null!=s?s:x,N=a(S,500),I=o(r);t.useEffect((function(){u&&I(S,u),null==E||E({type:"SET_INPUT",payload:S})}),[N,u]),t.useEffect((function(){A&&A.updateInternalContext("dataLength",u.length)}),[u]);var _=function(){var e;return null==T||null==(e=T.current)?void 0:e.focus()};return h(_,!0),n.createElement(y,{as:"HStack",onClick:_,justifyContent:"center",className:"rsh-input-box",padding:0,height:40,cursor:"text"},n.createElement("figure",{className:"rsh-input-box-logo"},p?n.createElement(p,null):n.createElement("img",{src:'<?xml version="1.0" encoding="utf-8"?>\n\x3c!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --\x3e\n<svg version="1.1" id="icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\n\t width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">\n<style type="text/css">\n\t.st0{fill:none;}\n</style>\n<title>search</title>\n<path d="M15,14.3L10.7,10c1.9-2.3,1.6-5.8-0.7-7.7S4.2,0.7,2.3,3S0.7,8.8,3,10.7c2,1.7,5,1.7,7,0l4.3,4.3L15,14.3z M2,6.5\n\tC2,4,4,2,6.5,2S11,4,11,6.5S9,11,6.5,11S2,9,2,6.5z"/>\n<rect id="_Transparent_Rectangle_" class="st0" width="16" height="16"/>\n</svg>',width:"18px"})),n.createElement("input",Object.assign({value:null!=s?s:x,onChange:null!=c?c:function(e){return g(e.target.value.toLowerCase())},placeholder:"search here",className:"rsh-input",autoFocus:!0,ref:T},f)))},N=["data","keysToSearch","inputAlgorithmTimeout","inputAlgorithm","matchingAlgorithm"],I={DEBOUNCE:function(e,n){var r=t.useState(e),i=r[0],a=r[1];return t.useEffect((function(){var t=setTimeout((function(){a(e)}),n);return function(){clearTimeout(t)}}),[e,n]),i},THROTTLE:function(e,n){void 0===n&&(n=200);var r=t.useState(e),i=r[0],a=r[1],o=t.useRef(),u=t.useRef(null),s=t.useRef(0),c=t.useRef(null);return t.useEffect((function(){o.current?(u.current=e,s.current=!0):(a(e),o.current=setTimeout((function e(){s.current?(s.current=!1,a(u.current),o.current=setTimeout(e,n)):o.current=void 0}),n))}),[e]),c.current=function(){o.current&&clearTimeout(o.current)},t.useEffect((function(){return function(){return c.current()}}),[]),i},DEFAULT:function(e){return e}},_={CHARACTER_MATCHING:function(e){var t=l().dispatch;return function(n,i){var a=n.toLowerCase().split("");if(0!==a.length){var s=new RegExp(a.join("|"),"gi");if(Array.isArray(i)&&Array.isArray(e)&&(!(i.length>0)||Object.keys(i[0]).some((function(t){return e.includes(t)})))){var c=null==i?void 0:i.filter((function(t){return a.every((function(n){return o(t,n,e)}))})).map((function(t){return r({},t,u(t,s,e))}));null==t||t({type:"SEARCH_DATA",payload:c})}}else null==t||t({type:"SEARCH_DATA",payload:[]})}},STRING_MATCHING:function(e){var t=l().dispatch;return function(n,i){if(0!==n.length){var a=new RegExp(n,"gi");if(Array.isArray(i)&&Array.isArray(e)&&(!(i.length>0)||Object.keys(i[0]).some((function(t){return e.includes(t)})))){var s=null==i?void 0:i.filter((function(t){return o(t,n,e)})).map((function(t){return r({},t,u(t,a,e))}));null==t||t({type:"SEARCH_DATA",payload:s})}}else null==t||t({type:"SEARCH_DATA",payload:[]})}}};exports.CHARACTER_MATCHING="CHARACTER_MATCHING",exports.DEBOUNCE="DEBOUNCE",exports.DEFAULT="DEFAULT",exports.END_LOADING="END_LOADING",exports.InternalContext=v,exports.Modal=function(e){var t=e.isOpen,r=e.onClose;return n.createElement(n.Fragment,null,(null==t||t)&&n.createElement("div",{onClick:null!=r?r:void 0,className:"rsh-modal-dialog",style:{backgroundColor:"rgba(220,220,220,0.5)",position:"fixed",top:0,right:0,bottom:0,left:0,zIndex:1e3}},n.createElement("div",{className:"rsh-modal-dialog-box-wrapper",style:{maxWidth:400,margin:"auto",padding:5}},e.children)))},exports.POPOVER_EXPANDED="POPOVER_EXPANDED",exports.PopOverList=function(e){var r=e.children,a=i(e,m),o=t.useRef(null),u=n.useContext(v),s=u.isPopoverExpanded,c=u.listItemActiveIndex,l=u.updateInternalContext,d=u.dataLength;return h((function(){c<d-1&&l("listItemActiveIndex",c+1)}),!1,"arrowdown",[c,d]),h((function(){c>0&&l("listItemActiveIndex",c-1)}),!1,"arrowup",[c]),n.createElement(n.Fragment,null,s&&n.createElement("ul",Object.assign({ref:o,className:"rsh-search-list"},a),r))},exports.PopOverOption=function(e){var t=e.children,r=e.optionIndex,a=i(e,x),o=n.useContext(v),u=o.updateInternalContext;return n.createElement("li",Object.assign({onMouseEnter:function(){u("listItemActiveIndex",r)},className:"rsh-search-list-item "+(o.listItemActiveIndex===r&&"rsh-search-list-item__active")},a),t)},exports.PopOverOptionText=function(e){var t,r=e.className,a=e.value,o=e.as,u=i(e,g),s=null==a?void 0:a.split(/\(([^)]+)\)/);return o=null!=(t=o)?t:"h3",n.createElement(f,Object.assign({as:o,classNames:r+" rsh-search-list-item-text"},u),null==s?void 0:s.map((function(e,t){return"<"===e[0]?n.createElement("span",{key:t,dangerouslySetInnerHTML:{__html:e}}):n.createElement("span",{key:t},e)})))},exports.RESET_STATE="RESET_STATE",exports.ReactSearchHighlightProvider=d,exports.SEARCH_DATA="SEARCH_DATA",exports.SET_INPUT="SET_INPUT",exports.START_LOADING="START_LOADING",exports.STRING_MATCHING="STRING_MATCHING",exports.SearchBar=function(e){var t,r,a,o,u=e.data,s=e.keysToSearch,c=e.inputAlgorithmTimeout,l=e.inputAlgorithm,d=void 0===l?"DEBOUNCE":l,p=e.matchingAlgorithm,f=i(e,N);return s=null!=(t=s)?t:Object.keys(null==u?void 0:u[0]),d=null!=(r=d)?r:"DEBOUNCE",c=null!=(a=c)?a:500,p=null!=(o=p)?o:"CHARACTER_MATCHING",n.createElement(S,Object.assign({keysToSearch:s,duration:c,inputAlgorithm:I[d],matchingAlgorithm:_[p],data:u},f))},exports.THROTTLE="THROTTLE",exports.Wrapper=function(e){var t=e.children,r="function"==typeof t;return n.createElement(n.Fragment,null,r?n.createElement(d,null,n.createElement(A,{isFunction:r,children:t})):n.createElement(A,{isFunction:r,children:t}))},exports.__DEV__=!1,exports.context=c,exports.initialState=s,exports.useReactSearchHighlight=l; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("process");var e,t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e;function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function o(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t.indexOf(n=a[r])>=0||(o[n]=e[n]);return o}!function(e,t){void 0===t&&(t={});var n=t.insertAt;if("undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===n&&r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}(".rsh-input:focus{outline:none}.rsh-search-wrapper{position:relative}.rsh-input-box{background-color:#fff;border:1px solid transparent;border-radius:5px;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);min-width:200px}.rsh-input-box-logo{align-items:center;display:flex;height:100%;justify-content:center;margin:0;width:40px}.rsh-input{border:none;border-radius:inherit;font-size:15px;height:100%;margin:0;padding:0;width:100%}.rsh-search-list{background-color:#fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);box-sizing:border-box;max-height:500px;min-width:200px;overflow-x:scroll;overflow:scroll;padding:0 8px;position:absolute;top:40px;width:100%;z-index:12}.rsh-search-list-item{border-radius:13px;list-style:none;margin:10px 0;padding:3px 8px}.rsh-search-list-item__active{background-color:hsla(0,0%,47%,.05)}.rsh-search-list-item-text{margin:0}[data-heightlighted-value=true]{background-color:#ff0}");var a=function(e,t){switch(t.type){case"SET_INPUT":return r({},e,{input:t.payload});case"SEARCH_DATA":return r({},e,{searchData:t.payload});case"START_LOADING":return r({},e,{isLoading:!0});case"END_LOADING":return r({},e,{isLoading:!1});case"RESET_STATE":return r({},s);default:return e}},i=function(e,t,n){return n.some((function(n){return e[n].toLowerCase().includes(t)}))},u=function(e,t,n){var o=r({},e);return n.forEach((function(n){return o[n]=e[n].replaceAll(t,(function(e){return"<mark>"+e+"<mark>"}))})),o},s={isLoading:!1,searchData:[],input:""},c=t.createContext(null),l=function(){return t.useContext(c)},d=function(e){var r=e.children,o=t.useReducer(a,s),i=o[0],u=o[1],l=function(){u({type:"START_LOADING"})},d=function(){u({type:"END_LOADING"})},p=function(){u({type:"RESET_STATE"})},f=0===i.searchData.length&&i.input.length>0,h=t.useMemo((function(){return{suggestions:i.searchData,isLoading:i.isLoading,input:i.input,dispatch:u,startLoading:l,endLoading:d,resetState:p,isResultsEmpty:f}}),[i]);return n.createElement(c.Provider,{value:h},r)},p=["as","children","classNames"],f=function(e){var n=e.as,a=e.children,i=e.classNames,u=o(e,p);return t.createElement(n,r({className:i},u),a)},h=function(e,n,r,o){void 0===r&&(r="k"),void 0===o&&(o=[]),t.useEffect((function(){var t=function(t){(!n||t.metaKey)&&t.key.toLowerCase()===r&&(null==e||e())};return document.addEventListener("keydown",t),function(){document.removeEventListener("keydown",t)}}),o)},m=function(e){return function(t){e.forEach((function(e){null!==e&&("function"==typeof e?e(t):e.current=t)}))}},x=["children"],g=["children","optionIndex"],E=["className","value","as"],v={isPopoverExpanded:!1,listItemActiveIndex:0,updateInternalContext:function(e,t){},dataLength:0},A=t.createContext(v),T=n.forwardRef((function(e,o){var a,i,u,s=e.children,c=e.isFunction,d=t.useState(v),p=d[0],f=d[1],h=l(),x=function(e,t){f((function(n){var o;return r({},n,((o={})[e]=t,o))}))},g=t.useRef(null),E=m([g,o]),T=function(e){var n=t.useState(!1),r=n[0],o=n[1];return t.useEffect((function(){function t(t){e.current&&!e.current.contains(t.target)&&o(!1)}return document.addEventListener("mousedown",t),function(){document.removeEventListener("mousedown",t)}}),[e]),[r,o]}(g),C=T[0],y=T[1];return a=function(){x("isPopoverExpanded",C)},i=[C],u=t.useRef(!1),t.useEffect((function(){u.current?a():u.current=!0}),i),n.createElement(A.Provider,{value:r({},p,{updateInternalContext:x})},n.createElement("section",{ref:E,className:"rsh-search-wrapper",onFocusCapture:function(){return y(!0)}},c?s(h):s))})),C=n.forwardRef((function(e,t){var r=e.children,o="function"==typeof r;return n.createElement(n.Fragment,null,o?n.createElement(d,null,n.createElement(T,{ref:t,isFunction:o,children:r})):n.createElement(T,{ref:t,isFunction:o,children:r}))})),y=n.forwardRef((function(e,t){var r=e.children,a=o(e,x),i=l().suggestions,u=n.useContext(A),s=u.isPopoverExpanded,c=u.listItemActiveIndex,d=u.updateInternalContext;return h((function(){c<i.length-1&&d("listItemActiveIndex",c+1)}),!1,"arrowdown",[c,i.length]),h((function(){c>0&&d("listItemActiveIndex",c-1)}),!1,"arrowup",[c]),n.createElement(n.Fragment,null,s&&n.createElement("ul",Object.assign({"data-popover-expanded":s,ref:t,className:"rsh-search-list"},a),r))})),N=["as","children","className","onClick","onMouseDown","onFocusCapture"],R=function(e){var t=e.as,a=e.children,i=e.className,u=e.onClick,s=e.onFocusCapture,c=o(e,N);return n.createElement("div",{style:r({display:"flex",flexDirection:"HStack"===t?"row":"column",alignItems:"center"},c),className:i,onClick:u,onFocusCapture:s},a)},I=function(){return n.createElement("svg",{width:"18",height:"18",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg"},n.createElement("path",{d:"M14 13.3L9.70001 9.00001C11.6 6.70001 11.3 3.20001 9.00001 1.30001C6.70001 -0.599986 3.20001 -0.299986 1.30001 2.00001C-0.599986 4.30001 -0.299986 7.80001 2.00001 9.70001C4.00001 11.4 7.00001 11.4 9.00001 9.70001L13.3 14L14 13.3ZM1.00001 5.50001C1.00001 3.00001 3.00001 1.00001 5.50001 1.00001C8.00001 1.00001 10 3.00001 10 5.50001C10 8.00001 8.00001 10 5.50001 10C3.00001 10 1.00001 8.00001 1.00001 5.50001Z",fill:"black"}))},S=["keysToSearch","inputAlgorithm","matchingAlgorithm","data","value","inputAlgorithmTimeout","onChange","initialValue","PrefixIcon"],_={DEBOUNCE:function(e,n){var r=t.useState(e),o=r[0],a=r[1];return t.useEffect((function(){var t=setTimeout((function(){a(e)}),n);return function(){clearTimeout(t)}}),[e,n]),o},THROTTLE:function(e,n){void 0===n&&(n=200);var r=t.useState(e),o=r[0],a=r[1],i=t.useRef(),u=t.useRef(null),s=t.useRef(0),c=t.useRef(null);return t.useEffect((function(){i.current?(u.current=e,s.current=!0):(a(e),i.current=setTimeout((function e(){s.current?(s.current=!1,a(u.current),i.current=setTimeout(e,n)):i.current=void 0}),n))}),[e]),c.current=function(){i.current&&clearTimeout(i.current)},t.useEffect((function(){return function(){return c.current()}}),[]),o},DEFAULT:function(e){return e}},b={CHARACTER_MATCHING:function(e){var t=l().dispatch;return function(n,o){var a=n.toLowerCase().split("");if(0!==a.length){var s=new RegExp(a.join("|"),"gi");if(Array.isArray(o)&&Array.isArray(e)&&(!(o.length>0)||Object.keys(o[0]).some((function(t){return e.includes(t)})))){var c=null==o?void 0:o.filter((function(t){return a.every((function(n){return i(t,n,e)}))})).map((function(t){return r({},t,u(t,s,e))}));null==t||t({type:"SEARCH_DATA",payload:c})}}else null==t||t({type:"SEARCH_DATA",payload:[]})}},STRING_MATCHING:function(e){var t=l().dispatch;return function(n,o){if(0!==n.length){var a=new RegExp(n,"gi");if(Array.isArray(o)&&Array.isArray(e)&&(!(o.length>0)||Object.keys(o[0]).some((function(t){return e.includes(t)})))){var s=null==o?void 0:o.filter((function(t){return i(t,n,e)})).map((function(t){return r({},t,u(t,a,e))}));null==t||t({type:"SEARCH_DATA",payload:s})}}else null==t||t({type:"SEARCH_DATA",payload:[]})}}},w=n.forwardRef((function(e,r){var a,i=e.keysToSearch,u=e.inputAlgorithm,s=void 0===u?"DEBOUNCE":u,c=e.matchingAlgorithm,d=void 0===c?"CHARACTER_MATCHING":c,p=e.data,f=e.value,x=e.inputAlgorithmTimeout,g=void 0===x?500:x,E=e.onChange,v=e.initialValue,T=e.PrefixIcon,C=o(e,S),y=t.useState(null!=v?v:""),N=y[0],w=y[1],O=l().dispatch,L=n.useContext(A);i=null!=(a=i)?a:Object.keys(null==p?void 0:p[0]);var D=t.useRef(null),k=m([D,r]),H=null!=f?f:N,P=_[s](H,g),G=b[d](i);t.useEffect((function(){p&&G(H,p),null==O||O({type:"SET_INPUT",payload:H})}),[P,p]),t.useEffect((function(){L&&L.updateInternalContext("matchingAlgorithm",d)}),[]);var j=function(){var e;return null==D||null==(e=D.current)?void 0:e.focus()};return h(j,!0),n.createElement(R,{as:"HStack",onClick:j,justifyContent:"center",className:"rsh-input-box",padding:0,height:40,cursor:"text"},n.createElement("figure",{className:"rsh-input-box-logo"},n.createElement(T||I,null)),n.createElement("input",Object.assign({value:null!=f?f:N,onChange:null!=E?E:function(e){return w(e.target.value.toLowerCase())},placeholder:"search here",className:"rsh-input",autoFocus:!0,ref:k},C)))}));exports.CHARACTER_MATCHING="CHARACTER_MATCHING",exports.DEBOUNCE="DEBOUNCE",exports.DEFAULT="DEFAULT",exports.END_LOADING="END_LOADING",exports.InternalContext=A,exports.Modal=function(e){var t=e.isOpen,r=e.onClose;return n.createElement(n.Fragment,null,(null==t||t)&&n.createElement("div",{onClick:null!=r?r:void 0,className:"rsh-modal-dialog",style:{backgroundColor:"rgba(220,220,220,0.5)",position:"fixed",top:0,right:0,bottom:0,left:0,zIndex:1e3}},n.createElement("div",{className:"rsh-modal-dialog-box-wrapper",style:{maxWidth:400,margin:"auto",padding:5}},e.children)))},exports.POPOVER_EXPANDED="POPOVER_EXPANDED",exports.PopOverList=y,exports.PopOverOption=function(e){var t=e.children,r=e.optionIndex,a=o(e,g),i=n.useContext(A),u=i.updateInternalContext;return n.createElement("li",Object.assign({onMouseEnter:function(){u("listItemActiveIndex",r)},className:"rsh-search-list-item "+(i.listItemActiveIndex===r&&"rsh-search-list-item__active")},a),t)},exports.PopOverOptionText=function(e){var t=e.className,r=e.value,a=e.as,i=void 0===a?"h3":a,u=o(e,E),s=l().input,c=n.useContext(A).matchingAlgorithm,d=null==r?void 0:r.split(/<mark>/);return n.createElement(f,Object.assign({as:i,classNames:t+" rsh-search-list-item-text"},u),null==d?void 0:d.map((function(e,t){return function(e){return"STRING_MATCHING"===c?e.toLocaleLowerCase()===s:s.includes(e.toLocaleLowerCase())}(e)?n.createElement("span",{key:e+"-"+t,"data-user-value":!0,"data-suggested-value":!0,"data-heightlighted-value":!0},e):n.createElement("span",{key:e+"-"+t},e)})))},exports.RESET_STATE="RESET_STATE",exports.ReactSearchHighlightProvider=d,exports.SEARCH_DATA="SEARCH_DATA",exports.SET_INPUT="SET_INPUT",exports.START_LOADING="START_LOADING",exports.STRING_MATCHING="STRING_MATCHING",exports.SearchBar=w,exports.THROTTLE="THROTTLE",exports.Wrapper=C,exports.__DEV__=!1,exports.context=c,exports.initialState=s,exports.inputAlgorithms=_,exports.matchingAlgorithms=b,exports.useReactSearchHighlight=l; | ||
//# sourceMappingURL=react-search-highlight.cjs.production.min.js.map |
@@ -31,3 +31,3 @@ import process from 'process'; | ||
var css_248z = ".rsh-input:focus{outline:none}.rsh-search-wrapper{position:relative}.rsh-input-box{background-color:#fff;border:1px solid transparent;border-radius:5px;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);min-width:200px}.rsh-input-box-logo{align-items:center;display:flex;height:100%;justify-content:center;margin:0;width:40px}.rsh-input{border:none;border-radius:inherit;font-size:15px;height:100%;margin:0;padding:0;width:100%}.rsh-search-list{background-color:#fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);box-sizing:border-box;max-height:500px;min-width:200px;overflow-x:scroll;overflow:scroll;padding:0 8px;position:absolute;top:40px;width:100%;z-index:12}.rsh-search-list-item{border-radius:13px;list-style:none;margin:10px 0;padding:3px 8px}.rsh-search-list-item__active{background-color:hsla(0,0%,47%,.05)}.rsh-search-list-item-text{margin:0}"; | ||
var css_248z = ".rsh-input:focus{outline:none}.rsh-search-wrapper{position:relative}.rsh-input-box{background-color:#fff;border:1px solid transparent;border-radius:5px;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);min-width:200px}.rsh-input-box-logo{align-items:center;display:flex;height:100%;justify-content:center;margin:0;width:40px}.rsh-input{border:none;border-radius:inherit;font-size:15px;height:100%;margin:0;padding:0;width:100%}.rsh-search-list{background-color:#fff;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);box-sizing:border-box;max-height:500px;min-width:200px;overflow-x:scroll;overflow:scroll;padding:0 8px;position:absolute;top:40px;width:100%;z-index:12}.rsh-search-list-item{border-radius:13px;list-style:none;margin:10px 0;padding:3px 8px}.rsh-search-list-item__active{background-color:hsla(0,0%,47%,.05)}.rsh-search-list-item-text{margin:0}[data-heightlighted-value=true]{background-color:#ff0}"; | ||
styleInject(css_248z); | ||
@@ -120,3 +120,3 @@ | ||
return newObj[key] = obj[key].replaceAll(regex, function (match) { | ||
return "(<mark>" + match + "</mark>)"; | ||
return "<mark>" + match + "<mark>"; | ||
}); | ||
@@ -336,2 +336,18 @@ }); | ||
/** | ||
* useRefComposition combines multiple refs into a single composed ref | ||
* @param refs - Array of refs | ||
* @returns callback function to update ref | ||
*/ | ||
var useRefComposition = function useRefComposition(refs) { | ||
return function (el) { | ||
refs.forEach(function (ref) { | ||
if (ref === null) return; | ||
if (typeof ref === 'function') ref(el);else ref.current = el; | ||
}); | ||
}; | ||
}; | ||
/** | ||
* @param keys - keys to search for from available data | ||
@@ -444,4 +460,3 @@ * @returns {callback} - dispatches action to update search results after matching strings | ||
var InternalContext = /*#__PURE__*/createContext(InternalContextInitialState); | ||
var WrapperInner = function WrapperInner(_ref) { | ||
var WrapperInner = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) { | ||
var children = _ref.children, | ||
@@ -465,2 +480,3 @@ isFunction = _ref.isFunction; | ||
var listRef = useRef(null); | ||
var composedRefs = useRefComposition([listRef, forwardedRef]); | ||
@@ -479,3 +495,3 @@ var _useOffScreen = useOffScreen(listRef), | ||
}, React.createElement("section", { | ||
ref: listRef, | ||
ref: composedRefs, | ||
className: "rsh-search-wrapper", | ||
@@ -490,20 +506,22 @@ | ||
}, isFunction ? children(__state) : children)); | ||
}; | ||
var Wrapper = function Wrapper(_ref2) { | ||
}); | ||
var Wrapper = /*#__PURE__*/React.forwardRef(function (_ref2, forwardedRef) { | ||
var children = _ref2.children; | ||
var isFunction = typeof children === 'function'; | ||
return React.createElement(React.Fragment, null, isFunction ? React.createElement(ReactSearchHighlightProvider, null, React.createElement(WrapperInner, { | ||
ref: forwardedRef, | ||
isFunction: isFunction, | ||
children: children | ||
})) : React.createElement(WrapperInner, { | ||
ref: forwardedRef, | ||
isFunction: isFunction, | ||
children: children | ||
})); | ||
}; | ||
var PopOverList = function PopOverList(_ref3) { | ||
}); | ||
var PopOverList = /*#__PURE__*/React.forwardRef(function (_ref3, forwardedRef) { | ||
var children = _ref3.children, | ||
any = _objectWithoutPropertiesLoose(_ref3, _excluded$1); | ||
var listRef = useRef(null); | ||
var _useReactSearchHighli = useReactSearchHighlight(), | ||
suggestions = _useReactSearchHighli.suggestions; | ||
@@ -513,7 +531,6 @@ var _React$useContext = React.useContext(InternalContext), | ||
listItemActiveIndex = _React$useContext.listItemActiveIndex, | ||
updateInternalContext = _React$useContext.updateInternalContext, | ||
dataLength = _React$useContext.dataLength; | ||
updateInternalContext = _React$useContext.updateInternalContext; | ||
var listItemActiveIndexArrowDown = function listItemActiveIndexArrowDown() { | ||
if (listItemActiveIndex < dataLength - 1) updateInternalContext('listItemActiveIndex', listItemActiveIndex + 1); | ||
if (listItemActiveIndex < suggestions.length - 1) updateInternalContext('listItemActiveIndex', listItemActiveIndex + 1); | ||
}; | ||
@@ -525,9 +542,10 @@ | ||
useKeyDown(listItemActiveIndexArrowDown, false, 'arrowdown', [listItemActiveIndex, dataLength]); | ||
useKeyDown(listItemActiveIndexArrowDown, false, 'arrowdown', [listItemActiveIndex, suggestions.length]); | ||
useKeyDown(listItemActiveIndexArrowUp, false, 'arrowup', [listItemActiveIndex]); | ||
return React.createElement(React.Fragment, null, isPopoverExpanded && React.createElement("ul", Object.assign({ | ||
ref: listRef, | ||
"data-popover-expanded": isPopoverExpanded, | ||
ref: forwardedRef, | ||
className: "rsh-search-list" | ||
}, any), children)); | ||
}; | ||
}); | ||
var PopOverOption = function PopOverOption(_ref4) { | ||
@@ -554,11 +572,20 @@ var children = _ref4.children, | ||
var PopOverOptionText = function PopOverOptionText(_ref5) { | ||
var _as; | ||
var className = _ref5.className, | ||
value = _ref5.value, | ||
as = _ref5.as, | ||
_ref5$as = _ref5.as, | ||
as = _ref5$as === void 0 ? 'h3' : _ref5$as, | ||
any = _objectWithoutPropertiesLoose(_ref5, _excluded3); | ||
var words = value == null ? void 0 : value.split(/\(([^)]+)\)/); | ||
as = (_as = as) != null ? _as : 'h3'; | ||
var _useReactSearchHighli2 = useReactSearchHighlight(), | ||
input = _useReactSearchHighli2.input; | ||
var _React$useContext3 = React.useContext(InternalContext), | ||
matchingAlgorithm = _React$useContext3.matchingAlgorithm; | ||
var words = value == null ? void 0 : value.split(/<mark>/); | ||
var isHighlighted = function isHighlighted(word) { | ||
return matchingAlgorithm === STRING_MATCHING ? word.toLocaleLowerCase() === input : input.includes(word.toLocaleLowerCase()); | ||
}; | ||
return React.createElement(Text, Object.assign({ | ||
@@ -568,9 +595,9 @@ as: as, | ||
}, any), words == null ? void 0 : words.map(function (word, index) { | ||
return word[0] === '<' ? React.createElement("span", { | ||
key: index, | ||
dangerouslySetInnerHTML: { | ||
__html: word | ||
} | ||
}) : React.createElement("span", { | ||
key: index | ||
return isHighlighted(word) ? React.createElement("span", { | ||
key: word + "-" + index, | ||
"data-user-value": true, | ||
"data-suggested-value": true, | ||
"data-heightlighted-value": true | ||
}, word) : React.createElement("span", { | ||
key: word + "-" + index | ||
}, word); | ||
@@ -630,12 +657,39 @@ })); | ||
var searchIcon = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n<svg version=\"1.1\" id=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\" style=\"enable-background:new 0 0 16 16;\" xml:space=\"preserve\">\n<style type=\"text/css\">\n\t.st0{fill:none;}\n</style>\n<title>search</title>\n<path d=\"M15,14.3L10.7,10c1.9-2.3,1.6-5.8-0.7-7.7S4.2,0.7,2.3,3S0.7,8.8,3,10.7c2,1.7,5,1.7,7,0l4.3,4.3L15,14.3z M2,6.5\n\tC2,4,4,2,6.5,2S11,4,11,6.5S9,11,6.5,11S2,9,2,6.5z\"/>\n<rect id=\"_Transparent_Rectangle_\" class=\"st0\" width=\"16\" height=\"16\"/>\n</svg>"; | ||
var SearchIcon = function SearchIcon() { | ||
return React.createElement("svg", { | ||
width: "18", | ||
height: "18", | ||
viewBox: "0 0 14 14", | ||
fill: "none", | ||
xmlns: "http://www.w3.org/2000/svg" | ||
}, React.createElement("path", { | ||
d: "M14 13.3L9.70001 9.00001C11.6 6.70001 11.3 3.20001 9.00001 1.30001C6.70001 -0.599986 3.20001 -0.299986 1.30001 2.00001C-0.599986 4.30001 -0.299986 7.80001 2.00001 9.70001C4.00001 11.4 7.00001 11.4 9.00001 9.70001L13.3 14L14 13.3ZM1.00001 5.50001C1.00001 3.00001 3.00001 1.00001 5.50001 1.00001C8.00001 1.00001 10 3.00001 10 5.50001C10 8.00001 8.00001 10 5.50001 10C3.00001 10 1.00001 8.00001 1.00001 5.50001Z", | ||
fill: "black" | ||
})); | ||
}; | ||
var _excluded$3 = ["keysToSearch", "inputAlgorithm", "matchingAlgorithm", "data", "value", "onChange", "initialValue", "PrefixIcon"]; | ||
var _excluded$3 = ["keysToSearch", "inputAlgorithm", "matchingAlgorithm", "data", "value", "inputAlgorithmTimeout", "onChange", "initialValue", "PrefixIcon"]; | ||
var inputAlgorithms = { | ||
DEBOUNCE: useDebounce, | ||
THROTTLE: useThrottle, | ||
DEFAULT: function DEFAULT(e) { | ||
return e; | ||
} | ||
}; | ||
var matchingAlgorithms = { | ||
CHARACTER_MATCHING: useCharacterMatching, | ||
STRING_MATCHING: useStringMatching | ||
}; | ||
var SearchBar = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) { | ||
var _keysToSearch; | ||
var Input = function Input(_ref) { | ||
var keysToSearch = _ref.keysToSearch, | ||
inputAlgorithm = _ref.inputAlgorithm, | ||
matchingAlgorithm = _ref.matchingAlgorithm, | ||
_ref$inputAlgorithm = _ref.inputAlgorithm, | ||
inputAlgorithm = _ref$inputAlgorithm === void 0 ? DEBOUNCE : _ref$inputAlgorithm, | ||
_ref$matchingAlgorith = _ref.matchingAlgorithm, | ||
matchingAlgorithm = _ref$matchingAlgorith === void 0 ? CHARACTER_MATCHING : _ref$matchingAlgorith, | ||
data = _ref.data, | ||
controlledValue = _ref.value, | ||
_ref$inputAlgorithmTi = _ref.inputAlgorithmTimeout, | ||
inputAlgorithmTimeout = _ref$inputAlgorithmTi === void 0 ? 500 : _ref$inputAlgorithmTi, | ||
onChange = _ref.onChange, | ||
@@ -655,6 +709,8 @@ initialValue = _ref.initialValue, | ||
keysToSearch = (_keysToSearch = keysToSearch) != null ? _keysToSearch : Object.keys(data == null ? void 0 : data[0]); | ||
var inputRef = useRef(null); | ||
var composedRefs = useRefComposition([inputRef, forwardedRef]); | ||
var searchInput = controlledValue != null ? controlledValue : input; | ||
var searchTerm = inputAlgorithm(searchInput, 500); | ||
var matchingFn = matchingAlgorithm(keysToSearch); | ||
var searchTerm = inputAlgorithms[inputAlgorithm](searchInput, inputAlgorithmTimeout); | ||
var matchingFn = matchingAlgorithms[matchingAlgorithm](keysToSearch); | ||
@@ -675,4 +731,4 @@ if (__DEV__) { | ||
useEffect(function () { | ||
if (__internalContext) __internalContext.updateInternalContext('dataLength', data.length); | ||
}, [data]); | ||
if (__internalContext) __internalContext.updateInternalContext('matchingAlgorithm', matchingAlgorithm); | ||
}, []); | ||
@@ -701,6 +757,3 @@ var focusInput = function focusInput() { | ||
className: "rsh-input-box-logo" | ||
}, PrefixIcon ? React.createElement(PrefixIcon, null) : React.createElement("img", { | ||
src: searchIcon, | ||
width: "18px" | ||
})), React.createElement("input", Object.assign({ | ||
}, PrefixIcon ? React.createElement(PrefixIcon, null) : React.createElement(SearchIcon, null)), React.createElement("input", Object.assign({ | ||
value: controlledValue != null ? controlledValue : input, | ||
@@ -711,43 +764,7 @@ onChange: onChange != null ? onChange : handleOnChange, | ||
autoFocus: true, | ||
ref: inputRef | ||
ref: composedRefs | ||
}, any))); | ||
}; | ||
}); | ||
var _excluded$4 = ["data", "keysToSearch", "inputAlgorithmTimeout", "inputAlgorithm", "matchingAlgorithm"]; | ||
var inputAlgorithms = { | ||
DEBOUNCE: useDebounce, | ||
THROTTLE: useThrottle, | ||
DEFAULT: function DEFAULT(e) { | ||
return e; | ||
} | ||
}; | ||
var matchingAlgorithms = { | ||
CHARACTER_MATCHING: useCharacterMatching, | ||
STRING_MATCHING: useStringMatching | ||
}; | ||
var SearchBar = function SearchBar(props) { | ||
var _keysToSearch, _inputAlgorithm, _inputAlgorithmTimeou, _matchingAlgorithm; | ||
var data = props.data, | ||
keysToSearch = props.keysToSearch, | ||
inputAlgorithmTimeout = props.inputAlgorithmTimeout, | ||
_props$inputAlgorithm = props.inputAlgorithm, | ||
inputAlgorithm = _props$inputAlgorithm === void 0 ? DEBOUNCE : _props$inputAlgorithm, | ||
matchingAlgorithm = props.matchingAlgorithm, | ||
any = _objectWithoutPropertiesLoose(props, _excluded$4); | ||
keysToSearch = (_keysToSearch = keysToSearch) != null ? _keysToSearch : Object.keys(data == null ? void 0 : data[0]); | ||
inputAlgorithm = (_inputAlgorithm = inputAlgorithm) != null ? _inputAlgorithm : DEBOUNCE; | ||
inputAlgorithmTimeout = (_inputAlgorithmTimeou = inputAlgorithmTimeout) != null ? _inputAlgorithmTimeou : 500; | ||
matchingAlgorithm = (_matchingAlgorithm = matchingAlgorithm) != null ? _matchingAlgorithm : CHARACTER_MATCHING; | ||
return React.createElement(Input, Object.assign({ | ||
keysToSearch: keysToSearch, | ||
duration: inputAlgorithmTimeout, | ||
inputAlgorithm: inputAlgorithms[inputAlgorithm], | ||
matchingAlgorithm: matchingAlgorithms[matchingAlgorithm], | ||
data: data | ||
}, any)); | ||
}; | ||
export { CHARACTER_MATCHING, DEBOUNCE, DEFAULT, END_LOADING, InternalContext, Modal, POPOVER_EXPANDED, PopOverList, PopOverOption, PopOverOptionText, RESET_STATE, ReactSearchHighlightProvider, SEARCH_DATA, SET_INPUT, START_LOADING, STRING_MATCHING, SearchBar, THROTTLE, Wrapper, __DEV__, context, initialState, useReactSearchHighlight }; | ||
export { CHARACTER_MATCHING, DEBOUNCE, DEFAULT, END_LOADING, InternalContext, Modal, POPOVER_EXPANDED, PopOverList, PopOverOption, PopOverOptionText, RESET_STATE, ReactSearchHighlightProvider, SEARCH_DATA, SET_INPUT, START_LOADING, STRING_MATCHING, SearchBar, THROTTLE, Wrapper, __DEV__, context, initialState, inputAlgorithms, matchingAlgorithms, useReactSearchHighlight }; | ||
//# sourceMappingURL=react-search-highlight.esm.js.map |
export declare const isMatch: (obj: any, char: any, keys: string[]) => boolean; | ||
export declare const replaceAll: (obj: any, regex: RegExp, keys: string[]) => any; | ||
export declare const replaceAllSingle: (value: any, regex: RegExp) => any; | ||
export declare const isResultsNotFound: (searchData: any[], searchInput: string) => boolean; |
{ | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"license": "MIT", | ||
@@ -4,0 +4,0 @@ "main": "dist/index.js", |
316
README.md
@@ -1,181 +0,241 @@ | ||
# TSDX React w/ Storybook User Guide | ||
# react-search-highlight | ||
Congrats! You just saved yourself hours of work by bootstrapping this project with TSDX. Let’s get you oriented with what’s here and how to use it. | ||
<img src="https://raw.githubusercontent.com/abusayid693/react-search-highlight/main/resources/logo.svg" width="50px" height="50px"> | ||
> This TSDX setup is meant for developing React component libraries (not apps!) that can be published to NPM. If you’re looking to build a React-based app, you should use `create-react-app`, `razzle`, `nextjs`, `gatsby`, or `react-static`. | ||
react-search-highlight is a light weight react package to highlight static/dynamic search for auto completion | ||
> If you’re new to TypeScript and React, checkout [this handy cheatsheet](https://github.com/sw-yx/react-typescript-cheatsheet/) | ||
<div> | ||
<img src="https://img.shields.io/npm/v/react-search-highlight"> | ||
<img src="https://img.shields.io/npm/l/react-search-highlight"> | ||
<img src="https://img.shields.io/node/v-lts/react-search-highlight"> | ||
<img src="https://img.shields.io/github/languages/top/abusayid693/react-search-highlight"> | ||
</div> | ||
## Commands | ||
## Installation | ||
TSDX scaffolds your new library inside `/src`, and also sets up a [Parcel-based](https://parceljs.org) playground for it inside `/example`. | ||
install it using npm or yarn to include it in your own React project | ||
The recommended workflow is to run TSDX in one terminal: | ||
You will also need to import css modules in root your project before using it. `dist/react-search-highlight.cjs.development.css` | ||
```bash | ||
npm start # or yarn start | ||
npm install react-search-highlight | ||
``` | ||
This builds to `/dist` and runs the project in watch mode so any edits you save inside `src` causes a rebuild to `/dist`. | ||
or: | ||
Then run either Storybook or the example playground: | ||
### Storybook | ||
Run inside another terminal: | ||
```bash | ||
yarn storybook | ||
yarn add react-search-highlight | ||
``` | ||
This loads the stories from `./stories`. | ||
## Usage | ||
> NOTE: Stories should reference the components as if using the library, similar to the example playground. This means importing from the root project directory. This has been aliased in the tsconfig and the storybook webpack config as a helper. | ||
You can either use the hook: | ||
### Example | ||
```tsx static | ||
import { | ||
PopOverList, | ||
PopOverOption, | ||
PopOverOptionText, | ||
Props, | ||
ReactSearchHighlightProvider, | ||
SearchBar, | ||
STRING_MATCHING, | ||
useReactSearchHighlight, | ||
Wrapper | ||
} from 'react-search-highlight'; | ||
import 'react-search-highlight/dist/react-search-highlight.cjs.development.css'; | ||
Then run the example inside another: | ||
import TEST_DATA from '../data.json'; | ||
```bash | ||
cd example | ||
npm i # or yarn to install dependencies | ||
npm start # or yarn start | ||
const Template = () => { | ||
const {suggestions, isResultsEmpty} = useReactSearchHighlight(); | ||
return ( | ||
<Wrapper> | ||
<SearchBar | ||
data={TEST_DATA} // need to provide data here | ||
keysToSearch={['heading', 'title']} // keys to search from data object | ||
placeholder="search docs" | ||
matchingAlgorithm={STRING_MATCHING} | ||
ref={ref} | ||
/> | ||
<PopOverList> | ||
{suggestions?.map((item, index) => ( | ||
<PopOverOption | ||
optionIndex={index} | ||
key={index} | ||
onClick={() => alert(index)} | ||
> | ||
⚡️ | ||
<PopOverOptionText as="h3" value={item.heading} /> | ||
<PopOverOptionText as="h5" value={item.title} /> | ||
</PopOverOption> | ||
))} | ||
{isResultsEmpty && <h3>No results found</h3>} | ||
</PopOverList> | ||
</Wrapper> | ||
); | ||
}; | ||
export const Custom = () => { | ||
return ( | ||
<ReactSearchHighlightProvider> | ||
<Template /> | ||
</ReactSearchHighlightProvider> | ||
); | ||
}; | ||
``` | ||
The default example imports and live reloads whatever is in `/dist`, so if you are seeing an out of date component, make sure TSDX is running in watch mode like we recommend above. **No symlinking required**, we use [Parcel's aliasing](https://parceljs.org/module_resolution.html#aliases). | ||
Or with the wrapper component | ||
To do a one-off build, use `npm run build` or `yarn build`. | ||
```tsx | ||
import { | ||
PopOverList, | ||
PopOverOption, | ||
PopOverOptionText, | ||
Props, | ||
SearchBar, | ||
Wrapper | ||
} from 'react-search-highlight'; | ||
import 'react-search-highlight/dist/react-search-highlight.cjs.development.css'; | ||
To run tests, use `npm test` or `yarn test`. | ||
import TEST_DATA from '../data.json'; | ||
## Configuration | ||
export const Default = args => { | ||
return ( | ||
<Wrapper> | ||
{({suggestions}) => { | ||
return ( | ||
<> | ||
<SearchBar | ||
data={TEST_DATA} // need to provide data here | ||
keysToSearch={['heading', 'title']} // keys to search from data object | ||
placeholder="search docs" | ||
/> | ||
<PopOverList> | ||
{suggestions?.map((item, index) => ( | ||
<PopOverOption | ||
optionIndex={index} | ||
key={index} | ||
onClick={() => alert(index)} | ||
> | ||
⚡️ | ||
<PopOverOptionText as="h3" value={item.heading} /> | ||
<PopOverOptionText as="h5" value={item.title} /> | ||
</PopOverOption> | ||
))} | ||
</PopOverList> | ||
</> | ||
); | ||
}} | ||
</Wrapper> | ||
); | ||
}; | ||
``` | ||
Code quality is set up for you with `prettier`, `husky`, and `lint-staged`. Adjust the respective fields in `package.json` accordingly. | ||
If you want to use it with modal | ||
### Jest | ||
```tsx static | ||
import {Modal} from 'react-search-highlight'; | ||
Jest tests are set up to run with `npm test` or `yarn test`. | ||
export const WithModal = () => { | ||
return ( | ||
<div> | ||
<h1>Modal is open</h1> | ||
<Modal> | ||
<Default /> | ||
</Modal> | ||
</div> | ||
); | ||
}; | ||
``` | ||
### Bundle analysis | ||
🔨 API | ||
`useReactSearchHighlight` can be used with `ReactSearchHighlightProvider` and it can be used throughout the component to access the context values. Note that whenever you are using it you must wrap the entire component using `ReactSearchHighlightProvider`. | ||
Calculates the real cost of your library using [size-limit](https://github.com/ai/size-limit) with `npm run size` and visulize it with `npm run analyze`. | ||
```tsx static | ||
const { | ||
suggestions, | ||
isLoading, | ||
input, | ||
startLoading, | ||
endLoading, | ||
isResultsEmpty, | ||
resetState | ||
} = useReactSearchHighlight(); | ||
``` | ||
#### Setup Files | ||
You can also access these values using wrapper component | ||
This is the folder structure we set up for you: | ||
```txt | ||
/example | ||
index.html | ||
index.tsx # test your component here in a demo app | ||
package.json | ||
tsconfig.json | ||
/src | ||
index.tsx # EDIT THIS | ||
/test | ||
blah.test.tsx # EDIT THIS | ||
/stories | ||
Thing.stories.tsx # EDIT THIS | ||
/.storybook | ||
main.js | ||
preview.js | ||
.gitignore | ||
package.json | ||
README.md # EDIT THIS | ||
tsconfig.json | ||
```tsx static | ||
<Wrapper> | ||
{({suggestions, isLoading, input, startLoading, endLoading, isResultsEmpty, resetState}) => { | ||
return ( | ||
..... | ||
); | ||
}} | ||
</Wrapper> | ||
``` | ||
#### React Testing Library | ||
### `<SearchBar/>` Props: | ||
We do not set up `react-testing-library` for you yet, we welcome contributions and documentation on this. | ||
```tsx | ||
// Data to perform search operation | ||
data: any[]; | ||
### Rollup | ||
// Determines which keys to search from the data object | ||
keysToSearch?: string[]; | ||
TSDX uses [Rollup](https://rollupjs.org) as a bundler and generates multiple rollup configs for various module formats and build settings. See [Optimizations](#optimizations) for details. | ||
// Determines input box behaviour it accepts three values DEBOUNCE, THROTTLE or DEFAULT | ||
inputAlgorithm?: typeof DEBOUNCE | typeof THROTTLE | typeof DEFAULT; | ||
### TypeScript | ||
// Optional: Determines the input algorithm timeout for debounce and throttle | ||
inputAlgorithmTimeout?: number; | ||
`tsconfig.json` is set up to interpret `dom` and `esnext` types, as well as `react` for `jsx`. Adjust according to your needs. | ||
// Determines matching algorithm to search over data, it accepts two values CHARACTER_MATCHING or STRING_MATCHING | ||
// CHARACTER_MATCHING matches each character from the data to highlight it | ||
// STRING_MATCHING matches each word from the data to highlight it | ||
matchingAlgorithm?: typeof CHARACTER_MATCHING | typeof STRING_MATCHING; | ||
## Continuous Integration | ||
// Optional: input value, it is recommended not to pass any in general case | ||
value?: string; | ||
### GitHub Actions | ||
// Optional: input value onChange event handler | ||
onChange?: (e:React.ChangeEvent<HTMLInputElement>) => void | ||
Two actions are added by default: | ||
// Optional: Determines initial input value | ||
initialValue?: string | ||
- `main` which installs deps w/ cache, lints, tests, and builds on all pushes against a Node and OS matrix | ||
- `size` which comments cost comparison of your library on every pull request using [size-limit](https://github.com/ai/size-limit) | ||
// Optional: It can be used to change search bar icon | ||
PrefixIcon?: React.FC | ||
``` | ||
## Optimizations | ||
### `<PopOverOption/>` Props: | ||
Please see the main `tsdx` [optimizations docs](https://github.com/palmerhq/tsdx#optimizations). In particular, know that you can take advantage of development-only optimizations: | ||
```ts | ||
// React element node | ||
children: ReactNode; | ||
// Determines the navigation index used for internal list navigation | ||
optionIndex: number; | ||
```js | ||
// ./types/index.d.ts | ||
declare var __DEV__: boolean; | ||
// inside your code... | ||
if (__DEV__) { | ||
console.log('foo'); | ||
} | ||
``` | ||
You can also choose to install and use [invariant](https://github.com/palmerhq/tsdx#invariant) and [warning](https://github.com/palmerhq/tsdx#warning) functions. | ||
### `<PopOverOptionText/>` Props: | ||
## Module Formats | ||
```ts | ||
// Determines text value to render with highlight | ||
value: string; | ||
CJS, ESModules, and UMD module formats are supported. | ||
The appropriate paths are configured in `package.json` and `dist/index.js` accordingly. Please report if any issues are found. | ||
## Deploying the Example Playground | ||
The Playground is just a simple [Parcel](https://parceljs.org) app, you can deploy it anywhere you would normally deploy that. Here are some guidelines for **manually** deploying with the Netlify CLI (`npm i -g netlify-cli`): | ||
```bash | ||
cd example # if not already in the example folder | ||
npm run build # builds to dist | ||
netlify deploy # deploy the dist folder | ||
// Determine type of html element ex: p, h1, h2 | ||
as: string; | ||
``` | ||
Alternatively, if you already have a git repo connected, you can set up continuous deployment with Netlify: | ||
### 🐛 Bug Reporting | ||
`The Library is in developing stage` | ||
- Feel free to Open an [issue on GitHub](https://github.com/Abusayid693/react-search-highlight/issues) to request any additional features you might need for your use case. | ||
- Connect with me on [LinkedIn](https://www.linkedin.com/in/rehan-choudhury-66842a164/). I'd love ❤️️ to hear where you are using this library. | ||
```bash | ||
netlify init | ||
# build command: yarn build && cd example && yarn && yarn build | ||
# directory to deploy: example/dist | ||
# pick yes for netlify.toml | ||
``` | ||
## Named Exports | ||
### 📜 License | ||
Per Palmer Group guidelines, [always use named exports.](https://github.com/palmerhq/typescript#exports) Code split inside your React app instead of your React library. | ||
## Including Styles | ||
There are many ways to ship styles, including with CSS-in-JS. TSDX has no opinion on this, configure how you like. | ||
For vanilla CSS, you can include it at the root directory and add it to the `files` section in your `package.json`, so that it can be imported separately by your users and run through their bundler's loader. | ||
## Publishing to NPM | ||
We recommend using [np](https://github.com/sindresorhus/np). | ||
## Usage with Lerna | ||
When creating a new package with TSDX within a project set up with Lerna, you might encounter a `Cannot resolve dependency` error when trying to run the `example` project. To fix that you will need to make changes to the `package.json` file _inside the `example` directory_. | ||
The problem is that due to the nature of how dependencies are installed in Lerna projects, the aliases in the example project's `package.json` might not point to the right place, as those dependencies might have been installed in the root of your Lerna project. | ||
Change the `alias` to point to where those packages are actually installed. This depends on the directory structure of your Lerna project, so the actual path might be different from the diff below. | ||
```diff | ||
"alias": { | ||
- "react": "../node_modules/react", | ||
- "react-dom": "../node_modules/react-dom" | ||
+ "react": "../../../node_modules/react", | ||
+ "react-dom": "../../../node_modules/react-dom" | ||
}, | ||
``` | ||
An alternative to fixing this problem would be to remove aliases altogether and define the dependencies referenced as aliases as dev dependencies instead. [However, that might cause other problems.](https://github.com/palmerhq/tsdx/issues/64) | ||
This software is open source, licensed under the [MIT License](./LICENSE). |
@@ -6,3 +6,4 @@ export * from "./useCharacterMatching"; | ||
export * from "./useOffScreen"; | ||
export * from "./useRefComposition"; | ||
export * from "./useStringMatching"; | ||
export * from "./useThrottle"; |
@@ -55,5 +55,4 @@ import { SEARCH_DATA, __DEV__ } from '../const'; | ||
}); | ||
dispatch?.({type: SEARCH_DATA, payload: newArr}); | ||
}; | ||
}; |
@@ -42,3 +42,2 @@ import { SEARCH_DATA, __DEV__ } from '../const'; | ||
} | ||
const newArr = data | ||
@@ -53,5 +52,5 @@ ?.filter((single: any) => isMatch(single, input, keys)) | ||
}); | ||
dispatch?.({type: SEARCH_DATA, payload: newArr}); | ||
}; | ||
}; |
@@ -11,3 +11,3 @@ export const isMatch = (obj: any, char: any, keys: string[]) => { | ||
regex, | ||
(match: any) => `(<mark>${match}</mark>)` | ||
(match: any) => `<mark>${match}<mark>` | ||
)) | ||
@@ -18,6 +18,8 @@ ); | ||
export const replaceAllSingle = (value: any, regex: RegExp) => { | ||
return value.replaceAll(regex, (match: any) => `<mark>${match}<mark>`); | ||
}; | ||
export const isResultsNotFound = (searchData: any[], searchInput: string) =>{ | ||
return searchData.length === 0 && searchInput.length > 0 | ||
} | ||
export const isResultsNotFound = (searchData: any[], searchInput: string) => { | ||
return searchData.length === 0 && searchInput.length > 0; | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
234693
55
2399
241