react-mail-chips
Version:
🍟 A simple react component for managing and displaying multiple email addresses as chips.
3 lines (2 loc) • 7.65 kB
JavaScript
import{jsxs as e,jsx as n}from"react/jsx-runtime";import{useState as r,useRef as t,useEffect as i,useCallback as o}from"react";function a(e,n,r){if(r||2===arguments.length)for(var t,i=0,o=n.length;i<o;i++)!t&&i in n||(t||(t=Array.prototype.slice.call(n,0,i)),t[i]=n[i]);return e.concat(t||Array.prototype.slice.call(n))}function l(e,n){void 0===n&&(n={});var r=n.insertAt;if(e&&"undefined"!=typeof document){var t=document.head||document.getElementsByTagName("head")[0],i=document.createElement("style");i.type="text/css","top"===r&&t.firstChild?t.insertBefore(i,t.firstChild):t.appendChild(i),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(document.createTextNode(e))}}"function"==typeof SuppressedError&&SuppressedError;l(".react-mail-chips > .chip {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n padding: 0.25rem 0.25rem 0.25rem 0.5rem;\r\n border-radius: 4px;\r\n background-color: #f1f1f1;\r\n color: #333;\r\n font-size: 12px;\r\n font-weight: 600;\r\n cursor: pointer;\r\n transition: background-color 0.3s;\r\n}\r\n\r\n.react-mail-chips > .chip:hover {\r\n background-color: #e1e1e1;\r\n}\r\n\r\n.react-mail-chips > .chip > .remove-chip-btn {\r\n border: none;\r\n display: flex;\r\n align-items: center;\r\n}\r\n");var c=function(r){var t=r.content,i=r.className,o=r.deleteByIndex;return e("span",{className:"chip ".concat(i),children:[t,n("span",{className:"remove-chip-btn",onClick:o,children:n("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",style:{width:"14px",height:"14px"},children:n("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18 18 6M6 6l12 12"})})})]})};l('.react-mail-chips > .chip-input-container {\r\n display: flex;\r\n flex-basis: 200px;\r\n flex-direction: column;\r\n padding: 0.25rem 0rem;\r\n font-size: 14px;\r\n flex: 1 1;\r\n -webkit-box-flex: 1;\r\n overflow: hidden;\r\n}\r\n\r\n.react-mail-chips .chip-input {\r\n font-family: "Roboto", sans-serif;\r\n outline: none;\r\n border: none;\r\n box-shadow: none;\r\n padding: 0;\r\n margin: 0;\r\n font-size: 14px;\r\n flex: 1 1;\r\n}\r\n\r\n.react-mail-chips .chip-input-content {\r\n font-family: "Roboto", sans-serif;\r\n align-self: flex-start;\r\n white-space: pre;\r\n font-size: 14px;\r\n height: 0;\r\n visibility: hidden;\r\n}\r\n');var s=function(e){return/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(e)},d=function(e,n){return n.includes(e)},u=function(o){var l=o.emails,c=o.setEmails,u=o.inputContainerClassName,p=o.inputValue,m=o.inputRef,f=o.setInputValue,h=o.delimiters,v=o.onKeyDown,x=r(0),g=x[0],w=x[1],y=t(null);i((function(){y.current&&w(y.current.clientWidth)}),[p]);return e("div",{className:"chip-input-container ".concat(u),style:{flexBasis:g?g+2:0},children:[n("input",{ref:m,className:"chip-input",type:"text",onKeyUp:function(e){if(h.includes(e.key)){var n=p.trim();s(n)&&(d(n,l)||(c(a(a([],l,!0),[n],!1)),f("")),m.current&&(m.current.value=""))}else"Backspace"===e.key&&0===p.length?c(l.slice(0,l.length-1)):f(e.target.value)},onKeyDown:v,onBlur:function(){s(p)&&(d(p,l)||(c(a(a([],l,!0),[p],!1)),f("")),m.current&&(m.current.value=""))},onPaste:function(e){e.preventDefault();var n=e.clipboardData.getData("text"),r=p+n;if(s(r.trim())&&!d(r.trim(),l))return c(a(a([],l,!0),[r.trim()],!1)),void(m.current.value="");var t=n.split(/[\s,;]+/).map((function(e){return e.trim()})).filter((function(e){return e&&s(e)&&!d(e,l)}));t.length>0?(c(a(a([],l,!0),t,!0)),f("")):m.current.value=r}}),n("span",{ref:y,className:"chip-input-content",children:p})]})};l(".react-mail-chips .email-recommendations-list {\r\n min-width: max-content;\r\n}\r\n\r\n.react-mail-chips .email-recommendation-item {\r\n padding: 8px 12px;\r\n cursor: pointer;\r\n}\r\n\r\n.react-mail-chips .email-recommendation-item:hover,\r\n.react-mail-chips .email-recommendation-item.selected {\r\n background-color: #f5f5f5;\r\n}\r\n");var p=function(e){var r=e.recommendations,o=e.selectedIndex,a=e.onSelect,l=e.onMouseEnter,c=t(null);return i((function(){if(o>=0&&c.current){var e=c.current.children[o];e&&e.scrollIntoView({block:"nearest"})}}),[o]),0===r.length?null:n("div",{className:"email-recommendations-list",ref:c,children:r.map((function(e,r){return n("div",{className:"email-recommendation-item ".concat(r===o?"selected":""),onMouseDown:function(n){n.preventDefault(),a(e)},onMouseEnter:function(){return l(r)},children:e},e)}))})};l('.react-mail-chips {\r\n display: flex;\r\n position: relative;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n padding: 0.25rem 0.5rem;\r\n border: 1px solid #d9d9d9;\r\n border-radius: 4px;\r\n width: 100%;\r\n max-width: 100%;\r\n font-size: 14px;\r\n row-gap: 0.5rem;\r\n column-gap: 0.5rem;\r\n font-family: "Roboto", sans-serif;\r\n}\r\n\r\n.react-mail-chips .placeholder {\r\n position: absolute;\r\n top: 50%;\r\n left: 0.5rem;\r\n transform: translateY(-50%);\r\n color: #999;\r\n font-size: 14px;\r\n pointer-events: none;\r\n}\r\n\r\n.react-mail-chips > .email-recommendations {\r\n position: absolute;\r\n width: 280px;\r\n max-height: 160px;\r\n overflow: auto;\r\n background-color: #fff;\r\n border: 1px solid #ddd;\r\n border-radius: 4px;\r\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);\r\n z-index: 10;\r\n padding: 4px 0;\r\n}');var m=-24,f=28,h=function(l){var s=l.emails,h=l.setEmails,v=l.className,x=void 0===v?"":v,g=l.chipClassName,w=void 0===g?"":g,y=l.inputContainerClassName,b=void 0===y?"":y,k=l.placeholder,C=void 0===k?"":k,N=l.delimiters,D=void 0===N?["Enter",",",";"]:N,E=l.recommendedEmails,I=void 0===E?[]:E,R=r(""),z=R[0],B=R[1],S=r(null),A=S[0],K=S[1],M=t(null),V=t(null),L=r(!1),T=L[0],Z=L[1],j=r([]),U=j[0],W=j[1],P=function(e){var n=e.showRecommendations,t=e.filteredRecommendations,i=e.onSelect,o=e.onClose,a=r(-1),l=a[0],c=a[1];return{selectedIndex:l,setSelectedIndex:c,handleKeyDown:function(e){if(n)switch(e.key){case"ArrowDown":e.preventDefault(),c((function(e){return e<t.length-1?e+1:e}));break;case"ArrowUp":e.preventDefault(),c((function(e){return e>0?e-1:e}));break;case"Enter":e.preventDefault(),l>=0&&l<t.length&&i(t[l]);break;case"Escape":e.preventDefault(),o()}}}}({showRecommendations:T,filteredRecommendations:U,onSelect:H,onClose:function(){Z(!1),$(-1)}}),Y=P.selectedIndex,$=P.setSelectedIndex,_=P.handleKeyDown,q=o((function(e){h(s.filter((function(n,r){return r!==e})))}),[s,h]),F=o((function(){var e;if(M.current&&z&&(null==I?void 0:I.length)){var n=M.current.getBoundingClientRect(),r=null===(e=V.current)||void 0===e?void 0:e.getBoundingClientRect();K(n&&r?{left:n.left-r.left+m,top:n.top-r.top+f}:n)}}),[z,I]),G=o((function(){if(z&&(null==I?void 0:I.length)){var e=I.filter((function(e){return e.toLowerCase().includes(z.toLowerCase())&&!d(e,s)})).slice(0,5);W(e),Z(e.length>0),$(-1)}else Z(!1)}),[z,I,s,$]);function H(e){e&&!d(e,s)&&(h(a(a([],s,!0),[e],!1)),B(""),M.current&&(M.current.value=""),Z(!1),$(-1))}i((function(){F(),G()}),[F,G]);var J=0===z.length&&0===s.length&&C.length>0;return e("div",{className:"react-mail-chips ".concat(x),ref:V,children:[J&&n("span",{className:"placeholder",children:C}),s.map((function(e,r){return n(c,{content:e,className:w,deleteByIndex:function(e){e.preventDefault(),q(r)}},e)})),T&&A&&n("div",{className:"email-recommendations",style:{left:"".concat(A.left,"px"),top:"".concat(A.top,"px")},children:n(p,{recommendations:U,selectedIndex:Y,onSelect:H,onMouseEnter:$})}),n(u,{emails:s,setEmails:h,inputValue:z,inputRef:M,setInputValue:B,inputContainerClassName:b,delimiters:D,onKeyDown:_})]})};export{h as ReactMailChips};
//# sourceMappingURL=index.js.map