@quicksilver0218/react-tokenized-input 0.1.10 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useRef,useCallback,useMemo,useState,memo,useEffect}from"react";function SuggestionComponent({displayText:e,hover:t,onMouseEnter:n,onMouseDown:r,onSelect:o}){return _jsx("button",{onClick:o,onMouseEnter:n,onMouseDown:r,style:{cursor:"pointer",border:"none",padding:".5em 1em",backgroundColor:t?"#333":"#1a1a1a",color:"white"},children:e})}let SuggestionListComponent=memo(({ref:e,children:t})=>_jsx("div",{ref:e,style:{display:"flex",flexDirection:"column",width:"min-content",maxHeight:"10em",overflow:"auto"},children:t})),defaultTrigger=/^@([^@]*)$/;function scrollToChild(e,t){e.scrollTop<t.offsetTop+t.offsetHeight-e.clientHeight?e.scrollTop=t.offsetTop+t.offsetHeight-e.clientHeight:e.scrollTop>t.offsetTop&&(e.scrollTop=t.offsetTop)}export default function TokenizedInput({tokens:y,setTokens:x,data:v,lists:b,suggestionListComponent:
|
|
1
|
+
import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useRef,useCallback,useMemo,useState,memo,useEffect}from"react";function SuggestionComponent({displayText:e,hover:t,onMouseEnter:n,onMouseDown:r,onSelect:o}){return _jsx("button",{onClick:o,onMouseEnter:n,onMouseDown:r,style:{cursor:"pointer",border:"none",padding:".5em 1em",backgroundColor:t?"#333":"#1a1a1a",color:"white"},children:e})}let SuggestionListComponent=memo(({ref:e,children:t})=>_jsx("div",{ref:e,style:{display:"flex",flexDirection:"column",width:"min-content",maxHeight:"10em",overflow:"auto"},children:t})),defaultTrigger=/^@([^@]*)$/;function scrollToChild(e,t){e.scrollTop<t.offsetTop+t.offsetHeight-e.clientHeight?e.scrollTop=t.offsetTop+t.offsetHeight-e.clientHeight:e.scrollTop>t.offsetTop&&(e.scrollTop=t.offsetTop)}export default function TokenizedInput({tokens:y,setTokens:x,data:v,lists:b,suggestionListComponent:H=SuggestionListComponent,suggestionComponent:$=SuggestionComponent,multiline:t,caseSensitive:k,missingDataText:g="{missing}",missingDataStyle:F={color:"red",textDecoration:"red wavy underline"},style:e,onCopy:I,onCut:n,onPaste:r,onKeyDown:o,onScroll:s,onClick:i,onBlur:l,onChange:a,...c}){let u=useRef(null),[p,m]=useState([]),w=useRef(-1),S=useRef({tokenIndex:-1,caretPos:-1}),[f,C]=useState(0),T=useRef(!1),h=useCallback((e,t,n,r,o,s,i)=>{let l;var a=t[t.length-1],r=("string"==typeof a?(l=a,t[t.length-1]+=r,1===t.length&&(l=e+l)):(r&&t.push(r),l=""),"string"==typeof t[0]?t[0]=e+t[0]:e&&t.unshift(e),y.toSpliced(s,i-s,...t));"string"==typeof a&&"string"==typeof r[s+t.length]&&(r[s+t.length-1]+=r[s+t.length],r.splice(s+t.length,1)),"string"==typeof r[s]&&"string"==typeof r[s-1]&&(1===t.length&&(l=r[s-1]+l),r[s-1]+=r[s],r.splice(s,1),s--);let c=s+t.length-1;r[s]||(r.splice(s,1),c--),x(r);var u,g=[];for(u of b){var p,f=u.trigger??defaultTrigger,h=[];for(i=0;i<l.length;i++)h.push(l.substring(i).match(f));for(p of u.items)for(i=0;i<l.length;i++)if(h[i]){var d=v[p].displayText;if(k){if(d.startsWith(h[i][1])){g.push({key:p,startPos:i});break}}else if(d.toLowerCase().startsWith(h[i][1].toLowerCase())){g.push({key:p,startPos:i});break}}}m(g),C(0),T.current=!1,w.current=o+n,S.current={tokenIndex:c,caretPos:l.length}},[y,x,v,b,k,m,C]),d=useCallback(a=>{a.preventDefault?.();var c=a.target;if("deleteByDrag"!==a.inputType&&"insertFromDrop"!==a.inputType){let t=c.selectionStart,n=c.selectionEnd,e,r=(null===a.data?(e="",t===n&&("deleteContentBackward"===a.inputType?t--:"deleteContentForward"===a.inputType&&n++)):e=a.data,0),o=-1,s,i="",l="";for(s=0;s<y.length;s++){var u=y[s];let e;if(e=("string"==typeof u?u:v[u.key]?.displayText??g).length,-1===o&&r+e>t&&(o=s,i=c.value.substring(r,t)),r>=n){l=c.value.substring(n,r);break}r+=e}s===y.length&&(l=c.value.substring(n)),-1===o&&(o=y.length),h(i,[e],e.length,l,t,o,s)}},[y,v,g,h]),D=(useEffect(()=>{let e=u.current;return e?.addEventListener("beforeinput",d),()=>{e?.removeEventListener("beforeinput",d)}},[d]),useCallback(e=>{e.preventDefault();var t=e.target,r=t.selectionStart,o=t.selectionEnd;if(r!==o){var s,i=[];let t=0,n=0;for(s of y){let e;var l=(e="string"==typeof s?s:v[s.key]?.displayText??g).length;if(n<r)n+l>r&&(e=e.substring(r-n,Math.min(l,o-n)),i.push(e),t+=e.length);else{if(!(n<o))break;n+l<=o?"string"==typeof s&&"string"==typeof i[i.length-1]?i[i.length-1]+=s:i.push(s):(e=e.substring(0,o-n),"string"==typeof i[i.length-1]?i[i.length-1]+=e:i.push(e)),t+=e.length}n+=l}e.clipboardData.setData("application/json",JSON.stringify({tokens:i,length:t}))}},[y,v,g]));var A=useCallback(e=>{n?.(e),D(e),d({data:"",target:e.target})},[n,D,d]),B=useCallback(e=>{r?.(e);var i,t=e.clipboardData.getData("application/json");if(t)try{if((i=JSON.parse(t)).tokens&&i.length){e.preventDefault();var l=e.target,a=l.selectionStart,c=l.selectionEnd;let t=0,n=-1,r,o="",s="";for(r=0;r<y.length;r++){var u=y[r];let e;if(e=("string"==typeof u?u:v[u.key]?.displayText??g).length,-1===n&&t+e>a&&(n=r,o=l.value.substring(t,a)),t>=c){s=l.value.substring(c,t);break}t+=e}r===y.length&&(s=l.value.substring(c)),-1===n&&(n=y.length),h(o,i.tokens,i.length,s,a,n,r)}}catch{}},[r,y,v,g,h]);let j=useCallback(n=>{let{tokenIndex:r,caretPos:o}=S.current;x(e=>{var t=e.concat(),e=e[r];return t[r]=e.substring(o),t[r]||t.splice(r,1),t.splice(r,0,{key:n.key}),n.startPos&&t.splice(r,0,e.substring(0,n.startPos)),t}),u.current.focus();var e=v[n.key]?.displayText||g;w.current=u.current.selectionStart-o+n.startPos+e.length,m([]),T.current=!1},[x,v,g,m]),E=useRef(null),_=useRef(null);var N=useCallback(e=>{if(o?.(e),p.length)switch(e.key){case"ArrowUp":C(e=>{e=e?e-1:p.length-1;return scrollToChild(_.current,_.current.children[e]),e}),e.preventDefault();break;case"ArrowDown":C(e=>{e=e===p.length-1?0:e+1;return scrollToChild(_.current,_.current.children[e]),e}),e.preventDefault();break;case"ArrowLeft":case"ArrowRight":m([]),T.current=!1;break;case"Escape":m([]),T.current=!1,e.preventDefault();break;case"Enter":j(p[f]),e.preventDefault()}},[o,p,f,C,m,j]),K=useCallback(e=>{s?.(e),E.current.scrollLeft=e.currentTarget.scrollLeft,E.current.scrollTop=e.currentTarget.scrollTop},[s]),O=useCallback(e=>{i?.(e),m([]),T.current=!1},[i,m]),V=useCallback(e=>{T.current||(l?.(e),m([]))},[l,m]);let[W,J]=useState(null),L=useRef(null),P=useCallback(()=>{var e,t;L.current&&W&&(e=W.getBoundingClientRect(),t=L.current.getBoundingClientRect(),e.left+t.width<=window.innerWidth?L.current.style.left=e.left+"px":L.current.style.left=e.right-t.width+"px",e.top+t.height<=window.innerHeight?L.current.style.top=e.bottom+"px":L.current.style.top=e.top-t.height+"px")},[W]),{borderWidth:R,boxSizing:U,fontFamily:q,fontSize:G,fontStretch:Q,fontWidth:X,fontStyle:Y,fontVariant:Z,fontWeight:ee,letterSpacing:te,lineHeight:ne,overflowWrap:re,padding:oe,textAlign:se,textDecoration:ie,textIndent:le,textTransform:ae,whiteSpace:ce,wordSpacing:ue}=(P(),useEffect(()=>(window.addEventListener("resize",P,!0),window.addEventListener("scroll",P,!0),()=>{window.removeEventListener("resize",P,!0),window.removeEventListener("scroll",P,!0)}),[P]),u.current?getComputedStyle(u.current):{});var ge=E.current?getComputedStyle(E.current).color:void 0;let{position:pe,left:fe,top:he,right:de,bottom:ye,inset:xe,display:ve,width:z,height:M,color:be,...ke}=useMemo(()=>e||{},[e]);useEffect(()=>{if(u.current){let e=new ResizeObserver(()=>{var e=E.current?.style;e&&(e.width=`calc(${u.current?.clientWidth||0}px + ${R} * 2)`,e.height=`calc(${u.current?.clientHeight||0}px + ${R} * 2)`)});return e.observe(u.current),()=>e.disconnect()}},[R]);var me=useCallback(e=>_jsx(t?"textarea":"input",{...e}),[t]),we=useMemo(()=>{if(!y.length)return!1;var e=y[y.length-1];let t;return t="string"==typeof e?e:v[e.key]?.displayText||g,/\s$/.test(t)},[y,v,g]),Se=useMemo(()=>y.map(e=>"string"==typeof e?e:v[e.key]?.displayText||g).join(""),[y,v,g]);return useEffect(()=>{var e;u.current&&(a?.({target:u.current}),-1!==w.current)&&(e=w.current,u.current.setSelectionRange(e,e),w.current=-1)},[a,Se]),_jsx("div",{style:{position:pe,left:fe,top:he,right:de,bottom:ye,inset:xe,display:ve||"inline-block",width:z,height:M},children:_jsxs("div",{style:{position:"relative"},children:[_jsx(me,{...c,ref:u,value:Se,onChange:()=>{},onCopy:e=>{I?.(e),D(e)},onCut:A,onPaste:B,onKeyDown:N,onScroll:K,onClick:O,onBlur:V,style:{fontFamily:"inherit",fontSize:"inherit",fontStretch:"inherit",fontStyle:"inherit",fontVariant:"inherit",fontWeight:"inherit",display:"block",boxSizing:"border-box",color:"transparent",caretColor:ge,width:z,height:M,...ke}}),_jsxs("div",{ref:E,className:c.className,style:{borderWidth:R,boxSizing:U,fontFamily:q,fontSize:G,fontStretch:Q,fontWidth:X,fontStyle:Y,fontVariant:Z,fontWeight:ee,letterSpacing:te,lineHeight:ne,overflowWrap:re,padding:oe,textAlign:se,textDecoration:ie,textIndent:le,textTransform:ae,whiteSpace:ce,wordSpacing:ue,...ke,color:be,pointerEvents:"none",position:"absolute",width:`calc(${u.current?.clientWidth||0}px + ${R} * 2)`,height:`calc(${u.current?.clientHeight||0}px + ${R} * 2)`,inset:0,borderStyle:"solid",borderColor:"transparent",background:"none",overflow:"hidden",textWrap:"nowrap"},children:[y.map((e,t)=>"string"==typeof e?t===S.current.tokenIndex?_jsxs("span",{children:[e.substring(0,S.current.caretPos),_jsx("span",{ref:e=>J(e)}),e.substring(S.current.caretPos)]},t):_jsx("span",{children:e},t):(e=v[e.key],_jsx("span",e?{style:e.style,children:e.displayText}:{style:F,children:g},t))),we&&_jsx(_Fragment,{children:" "})]}),0!==p.length&&_jsx("div",{ref:L,style:{position:"fixed",zIndex:1},children:_jsx(H,{ref:_,children:p.map((e,t)=>{var n=v[e.key];return _jsx($,{tokenKey:e.key,displayText:n.displayText,suggestionProps:n.suggestionProps,hover:f===t,onMouseEnter:()=>C(t),onMouseDown:()=>{T.current=!0},onSelect:()=>j(e)},e.key)})})})]})})}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quicksilver0218/react-tokenized-input",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "A React input field component that tokenizes and autocompletes the input.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist",
|
|
@@ -23,19 +23,19 @@
|
|
|
23
23
|
},
|
|
24
24
|
"license": "Apache-2.0",
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@eslint/js": "^9.
|
|
27
|
-
"@types/react": "^19.
|
|
28
|
-
"@types/react-dom": "^19.
|
|
29
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
30
|
-
"@typescript-eslint/parser": "^8.
|
|
31
|
-
"eslint": "^9.
|
|
32
|
-
"eslint-plugin-react": "^7.37.
|
|
33
|
-
"eslint-plugin-react-hooks": "^
|
|
34
|
-
"eslint-plugin-react-refresh": "^0.
|
|
35
|
-
"react": "^19.
|
|
36
|
-
"rimraf": "^6.
|
|
37
|
-
"typescript": "^5.
|
|
38
|
-
"typescript-eslint": "^8.
|
|
26
|
+
"@eslint/js": "^9.39.2",
|
|
27
|
+
"@types/react": "^19.2.13",
|
|
28
|
+
"@types/react-dom": "^19.2.3",
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
30
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
31
|
+
"eslint": "^9.39.2",
|
|
32
|
+
"eslint-plugin-react": "^7.37.5",
|
|
33
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
34
|
+
"eslint-plugin-react-refresh": "^0.5.0",
|
|
35
|
+
"react": "^19.2.4",
|
|
36
|
+
"rimraf": "^6.1.2",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"typescript-eslint": "^8.54.0",
|
|
39
39
|
"uglify-js": "^3.19.3"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|