handlebars-editor-react 0.1.1 → 0.1.3
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.cjs +3 -3
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +3 -3
- package/dist/styles.css +155 -79
- package/package.json +17 -16
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var react=require('react'),
|
|
2
|
-
`);P.setInput(r);try{for(let t=P.lex();t!==P.EOF;t=P.lex()){let c=me[t]||"UNKNOWN",n=P.yylloc;a.push({type:c,text:P.yytext,start:J(e,n.first_line,n.first_column),end:J(e,n.last_line,n.last_column)});}}catch{}return a}function xe(r,a){let e=r[a-1],t=r[a+1];return e&&(e.type==="OPEN_BLOCK"||e.type==="OPEN_INVERSE"||e.type==="OPEN_INVERSE_CHAIN"||e.type==="OPEN_ENDBLOCK")?"block-keyword":e?.type==="OPEN_PARTIAL"||e?.type==="OPEN_PARTIAL_BLOCK"||e?.type==="OPEN_SEXPR"?"helper":e?.type==="OPEN"||e?.type==="OPEN_UNESCAPED"?t&&(t.type==="ID"||t.type==="SEP"||t.type==="STRING"||t.type==="NUMBER"||t.type==="BOOLEAN"||t.type==="DATA"||t.type==="OPEN_SEXPR")?"helper":"variable":e?.type==="EQUALS"?"hash-value":e?.type==="ID"?t?.type==="EQUALS"?"hash-key":"helper-arg":e?.type==="DATA"||e?.type==="SEP"?"helper-arg":e?.type==="OPEN_BLOCK_PARAMS"?"block-param":"variable"}function ye(r,a){let e=[],t=0;for(let c=0;c<a.length;c++){let n=a[c];n.start>t&&e.push({type:"text",value:r.slice(t,n.start),start:t,end:n.start});let b=ge[n.type]||"text";if(n.type==="ID"&&(b=xe(a,c)),n.type==="DATA"){let d=a[c+1];if(d?.type==="ID"&&d.start===n.end){e.push({type:"data-var",value:r.slice(n.start,d.end),start:n.start,end:d.end}),t=d.end,c++;continue}}e.push({type:b,value:r.slice(n.start,n.end),start:n.start,end:n.end}),t=n.end;}return t<r.length&&e.push({type:"text",value:r.slice(t),start:t,end:r.length}),e}function L(r){if(!r)return [];let a=Ee(r);return ye(r,a).filter(e=>e.value.length>0)}var Z=new Set(["if","unless","each","with","lookup","log","this","else"]),M=new Set(["each","with"]);function K(r){return Z.has(r)||r.startsWith("@")}var ee=V__default.default.Parser,O=ee.lexer,Oe=ee.terminals_;function Ne(r){let a=new Map,e=r;for(;e.length>0;){let t=ke(e,a);if(t===e.length)break;let c=e.slice(t),n=c.search(/\{\{/);if(n===-1)break;e=c.slice(n);}return Array.from(a.values())}function ke(r,a){O.setInput(r),O.conditionStack=["INITIAL"];let e=0,t=false,c=null,n=[],b=[];function d(i,l){let f=[];for(let o=l;o<i.length;o++)if(i[o].name==="ID")f.push(i[o].text);else if(i[o].name!=="SEP")break;return f}function x(i,l,f){a.has(l)||a.set(l,{name:i,path:l,type:f?"block":l.includes(".")?"nested":"simple",blockType:f});}function _(){if(n.length===0)return;let i=0;if(n[i]?.name==="DATA")return;let l=n[i].text;if(c==="block"){let f=b.some(o=>M.has(o.helper));if(M.has(l)){for(i++;i<n.length&&n[i].name!=="ID";)i++;if(i<n.length){let o=d(n,i);o.length>0&&!K(o[0])&&!f&&x(o[0],o.join("."),l),b.push({helper:l,context:o[0]||""});}}else if(Z.has(l)){for(i++;i<n.length&&n[i].name!=="ID";)i++;if(i<n.length){let o=d(n,i);o.length>0&&!K(o[0])&&!f&&x(o[0],o.join("."),l);}b.push({helper:l,context:""});}else b.push({helper:l,context:""});}else if(c==="endblock")b.length>0&&b.pop();else {let f=b.some(o=>M.has(o.helper));if(!K(l)&&!f){let o=d(n,i);o.length>0&&x(o[0],o.join("."));}}}try{for(let i=O.lex();i!==O.EOF;i=O.lex()){let l=Oe[i],f=O.yytext;if(e=O.yylloc?.last_column??e,!(l==="OPEN_RAW_BLOCK"||l==="CLOSE_RAW_BLOCK"||l==="END_RAW_BLOCK")){if(l==="OPEN"||l==="OPEN_UNESCAPED"){t=!0,c="mustache",n=[];continue}if(l==="OPEN_BLOCK"||l==="OPEN_INVERSE"||l==="OPEN_INVERSE_CHAIN"){t=!0,c="block",n=[];continue}if(l==="OPEN_ENDBLOCK"){t=!0,c="endblock",n=[];continue}if(l==="CLOSE"||l==="CLOSE_UNESCAPED"){_(),t=!1,n=[];continue}t&&n.push({name:l,text:f});}}return r.length}catch{return e}}function U(r){let a=Ne(r),e=[...new Set(a.map(t=>t.name))];return {variables:a,rootVariables:e}}function Pe(r,a,e){if(!a)return r;let t=e?.helpers?V__default.default.create():V__default.default;if(e?.helpers)for(let[c,n]of Object.entries(e.helpers))t.registerHelper(c,n);return t.compile(r)(a)}var Se=["#if","#each","#with","#unless","/if","/each","/with","/unless","else"];function re({value:r,onChange:a,placeholder:e="Enter template...",readOnly:t=false,className:c="",style:n,theme:b,customHelpers:d=[],autocomplete:x=true,minHeight:_=100}){let i=react.useRef(null),l=react.useRef(null),f=react.useRef(null),[o,y]=react.useState({isOpen:false,options:[],selectedIndex:0,triggerStart:0,filterText:""}),[R,se]=react.useState({top:0,left:0}),z=react.useMemo(()=>U(r).rootVariables,[r]),F=react.useMemo(()=>[...Se,...d,...z],[d,z]),$=react.useMemo(()=>L(r),[r]),oe=react.useMemo(()=>r?$.map(s=>s.type==="text"?s.value:jsxRuntime.jsx("span",{className:`hbs-token-${s.type}`,children:s.value},s.start)):jsxRuntime.jsx("span",{className:"hbs-editor-placeholder",children:e}),[$,r,e]),ae=react.useCallback(s=>{let p=s.target.value;if(a?.(p),!x||t)return;let h=s.target.selectionStart,m=p.slice(0,h).match(/\{\{([#/]?\w*)$/);if(m){let g=m[1]||"",E=h-g.length,N=F.filter(w=>w.toLowerCase().startsWith(g.toLowerCase()));if(N.length>0){y({isOpen:true,options:N,selectedIndex:0,triggerStart:E,filterText:g});return}}y(g=>({...g,isOpen:false}));},[a,x,t,F]),v=react.useCallback(s=>{let p=i.current;if(!p)return;let{triggerStart:h}=o,u=s,m=s.length;if(s.startsWith("#")){let E=s.slice(1);u=`${s} }}{{/${E}}}`,m=s.length+1;}else !s.startsWith("/")&&s!=="else"?(u=`${s}}}`,m=u.length):(u=`${s}}}`,m=u.length);p.focus(),p.setSelectionRange(h,p.selectionStart),document.execCommand("insertText",false,u);let g=h+m;p.setSelectionRange(g,g),a?.(p.value),y(E=>({...E,isOpen:false}));},[a,o]),le=react.useCallback(s=>{let{scrollTop:p,scrollLeft:h}=s.currentTarget;l.current&&(l.current.scrollTop=p,l.current.scrollLeft=h),se({top:p,left:h});},[]),ie=react.useCallback(s=>{if(!o.isOpen)return;let{options:p,selectedIndex:h}=o;switch(s.key){case "ArrowDown":s.preventDefault(),y(u=>({...u,selectedIndex:Math.min(h+1,p.length-1)}));break;case "ArrowUp":s.preventDefault(),y(u=>({...u,selectedIndex:Math.max(h-1,0)}));break;case "Enter":case "Tab":s.preventDefault(),p[h]&&v(p[h]);break;case "Escape":s.preventDefault(),y(u=>({...u,isOpen:false}));break}},[o,v]),I=react.useMemo(()=>{if(!o.isOpen||!i.current)return {top:0,left:0,maxHeight:192,openUpward:false,visible:false};let s=i.current,{triggerStart:p}=o,u=r.slice(0,p).split(`
|
|
3
|
-
`),
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var react=require('react'),ne=require('handlebars'),reactDom=require('react-dom'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ne__default=/*#__PURE__*/_interopDefault(ne);var ce=ne__default.default.Parser,H=ce.lexer,Te=ce.terminals_,Ne=new Set(["OPEN_BLOCK","OPEN_INVERSE","OPEN_INVERSE_CHAIN","OPEN_ENDBLOCK"]),Ce=new Set(["OPEN","OPEN_UNESCAPED"]),Re=new Set(["OPEN_PARTIAL","OPEN_PARTIAL_BLOCK"]),Ie=new Set(["OPEN","OPEN_UNESCAPED","OPEN_BLOCK","OPEN_INVERSE","OPEN_INVERSE_CHAIN","OPEN_ENDBLOCK","OPEN_PARTIAL","OPEN_PARTIAL_BLOCK"]),Le=new Set(["CLOSE","CLOSE_UNESCAPED","CLOSE_RAW_BLOCK","END_RAW_BLOCK"]),_e=new Set(["ID","STRING","NUMBER","BOOLEAN","DATA","OPEN_SEXPR","UNDEFINED","NULL"]),pe=t=>Ne.has(t),ue=t=>Ce.has(t),fe=t=>Re.has(t),ve=t=>Ie.has(t),we=t=>Le.has(t),De=t=>_e.has(t),Be={CONTENT:"text",COMMENT:"comment",OPEN:"brace",CLOSE:"brace",OPEN_UNESCAPED:"brace",CLOSE_UNESCAPED:"brace",OPEN_RAW_BLOCK:"brace",CLOSE_RAW_BLOCK:"brace",END_RAW_BLOCK:"brace",OPEN_BLOCK:"brace",OPEN_INVERSE:"brace",OPEN_INVERSE_CHAIN:"brace",OPEN_ENDBLOCK:"brace",OPEN_PARTIAL:"brace",OPEN_PARTIAL_BLOCK:"brace",OPEN_SEXPR:"subexpr-paren",CLOSE_SEXPR:"subexpr-paren",OPEN_BLOCK_PARAMS:"block-keyword",CLOSE_BLOCK_PARAMS:"block-keyword",INVERSE:"block-keyword",ID:"variable",STRING:"literal",NUMBER:"literal",BOOLEAN:"literal",UNDEFINED:"literal",NULL:"literal",DATA:"data-var",SEP:"brace",EQUALS:"brace"};function le(t,n,o){let e=0;for(let r=0;r<n-1&&r<t.length;r++)e+=t[r].length+1;return e+o}function He(t){let n=[],o=t.split(`
|
|
2
|
+
`);H.setInput(t);try{for(let e=H.lex();e!==H.EOF;e=H.lex()){let r=Te[e]||"UNKNOWN",s=H.yylloc;n.push({type:r,text:H.yytext,start:le(o,s.first_line,s.first_column),end:le(o,s.last_line,s.last_column)});}}catch{}return n}function Me(t){return t.map(n=>n.type==="ID"&&n.text==="."?{...n,type:"SEP"}:n.type==="ID"&&n.text==="="?{...n,type:"EQUALS"}:n)}function Ve(t){let n=[],o=null,e=false,r=false,s=0;for(let l=0;l<t.length;l++){let i=t[l],d=t[l-1];ve(i.type)?(pe(i.type)?o=i.type==="OPEN_ENDBLOCK"?"block-close":"block-open":fe(i.type)?o="partial":ue(i.type)&&(o="mustache"),r=false,s=0):we(i.type)&&(o=null,r=false,s=0),i.type==="OPEN_BLOCK_PARAMS"?e=true:i.type==="CLOSE_BLOCK_PARAMS"&&(e=false),i.type==="SEP"?s++:i.type==="ID"&&d?.type!=="SEP"&&d?.type!=="DATA"&&(s=0);let O=false;if(i.type==="ID"){if(s===0)O=r;else for(let k=l-1;k>=0;k--)if(t[k].type==="ID"&&n[k]?.context.pathRootAfterHelper!==void 0){let x=t[k-1];if(x?.type!=="SEP"&&x?.type!=="DATA"){O=n[k].context.pathRootAfterHelper;break}}}n.push({...i,context:{type:o,isInBlockParams:e,pathRootAfterHelper:O}}),i.type==="ID"&&s===0&&!e&&d?.type!=="EQUALS"&&d?.type!=="DATA"&&(r=true);}return n}function Ke(t,n,o){let{context:e}=t;return t.text==="this"?"data-var":e.isInBlockParams?"block-param":o?.type==="EQUALS"?"hash-key":n?.type==="EQUALS"?"hash-value":n?.type==="DATA"?"data-var":n?.type==="SEP"?e.pathRootAfterHelper?"helper-arg":"variable-path":Ue(t,n,o)}function Ue(t,n,o){let{context:e}=t;return e.type==="block-open"||e.type==="block-close"?pe(n?.type??"")?"block-keyword":"helper-arg":e.type==="partial"?fe(n?.type??"")?"helper":"helper-arg":n?.type==="OPEN_SEXPR"?"helper":e.type==="mustache"?ue(n?.type??"")?o?.type==="SEP"?"variable":o&&De(o.type)?"helper":"variable":"helper-arg":"variable"}function We(t){return t.map((n,o)=>{let e=t[o-1],r=t[o+1],s;return n.type==="ID"?s=Ke(n,e,r):s=Be[n.type]||"text",{token:n,highlightType:s}})}function ze(t,n){let o=[],e=0;for(let r=0;r<n.length;r++){let{token:s,highlightType:l}=n[r];if(s.start>e&&o.push({type:"text",value:t.slice(e,s.start),start:e,end:s.start}),s.type==="DATA"){let i=n[r+1];if(i?.token.type==="ID"&&i.token.start===s.end){o.push({type:"data-var",value:t.slice(s.start,i.token.end),start:s.start,end:i.token.end}),e=i.token.end,r++;continue}}o.push({type:l,value:t.slice(s.start,s.end),start:s.start,end:s.end}),e=s.end;}return e<t.length&&o.push({type:"text",value:t.slice(e),start:e,end:t.length}),o}function M(t){if(!t)return [];let n=He(t),o=Me(n),e=Ve(o),r=We(e);return ze(t,r).filter(l=>l.value.length>0)}var J=["if","unless","each","with"],de=new Set([...J,"lookup","log","this","else"]),he=new Set(["each","with"]),$e=new Set(["ID","STRING","NUMBER","BOOLEAN","DATA","OPEN_SEXPR"]),me=ne__default.default.Parser,D=me.lexer,Fe=me.terminals_;function j(t){return de.has(t)||t.startsWith("@")}function Xe(t){return $e.has(t.name)}function q(t,n){let o=[],e=true;for(let r=n;r<t.length;r++){let s=t[r];if(s.name==="EQUALS")break;if(s.name==="ID"){if(!e||t[r+1]?.name==="EQUALS")break;o.push(s.text),e=false;}else if(s.name==="SEP")e=true;else break}return o}function Qe(t,n,o,e){return {name:t,path:n,type:o?"block":n.includes(".")||e?"nested":"simple",blockType:o,context:e}}function Ge(t){let n=[],o=null;for(let e of t)he.has(e.helper)&&e.context&&(o||(o=e.context),n.push(e.helper==="each"?`${e.context}[]`:e.context));return n.length===0||!o?null:{root:o,prefix:`${n.join(".")}.`}}function je(t){let n=[],o=t;for(;o.length>0;){let e=qe(o);if(n.push(...e.expressions),e.consumed===o.length)break;let r=o.slice(e.consumed),s=r.search(/\{\{/);if(s===-1)break;o=r.slice(s);}return {expressions:n}}function qe(t){D.setInput(t),D.conditionStack=["INITIAL"];let n=[],o=0,e=false,r=null,s=[];try{for(let l=D.lex();l!==D.EOF;l=D.lex()){let i=Fe[l],d=D.yytext;if(o=D.yylloc?.last_column??o,!(i==="OPEN_RAW_BLOCK"||i==="CLOSE_RAW_BLOCK"||i==="END_RAW_BLOCK")){if(i==="OPEN"||i==="OPEN_UNESCAPED"){e=!0,r="mustache",s=[];continue}if(i==="OPEN_PARTIAL"||i==="OPEN_PARTIAL_BLOCK"){e=!0,r="partial",s=[];continue}if(i==="OPEN_BLOCK"||i==="OPEN_INVERSE"||i==="OPEN_INVERSE_CHAIN"){e=!0,r="block",s=[];continue}if(i==="OPEN_ENDBLOCK"){e=!0,r="endblock",s=[];continue}if(i==="CLOSE"||i==="CLOSE_UNESCAPED"){if(r){let O=s[0]?.text??null;n.push({type:r,tokens:[...s],helperName:O});}e=!1,s=[];continue}e&&s.push({name:i,text:d});}}return {expressions:n,consumed:t.length}}catch{return {expressions:n,consumed:o}}}function Ye(t,n,o){let e=t.tokens;if(e.length===0||e[0]?.name==="DATA")return;let r=e[0]?.text;if(j(r))F(e,1,n,o);else {let s=q(e,0);if(s.length>0){let i=s.length*2-1,d=e[i];d&&Xe(d)?F(e,i,n,o):Y(s,n,o);}}}function Je(t,n,o){let e=t.tokens,r=e[0]?.text;if(he.has(r)){if(e[1]?.name==="OPEN_SEXPR")return F(e,1,n,o),{helper:r,context:""};{let s=1;for(;s<e.length&&e[s].name!=="ID";)s++;if(s<e.length){let l=q(e,s);return l.length>0&&!j(l[0])&&Y(l,n,o,r),{helper:r,context:l[0]||""}}return {helper:r,context:""}}}else if(de.has(r)){if(e[1]?.name==="OPEN_SEXPR")F(e,1,n,o);else {let s=1;for(;s<e.length&&e[s].name!=="ID";)s++;if(s<e.length){let l=q(e,s);l.length>0&&!j(l[0])&&Y(l,n,o,r);}}return {helper:r,context:""}}return {helper:r,context:""}}function Ze(t,n,o){let e=t.tokens,r=1;for(;r<e.length&&(e[r].name==="SEP"||e[r].name==="ID")&&!(e[r].name==="ID"&&e[r-1]?.name!=="SEP");)r++;F(e,r,n,o);}function F(t,n,o,e){for(let r=n;r<t.length;r++){let s=t[r];if(!(s.name==="OPEN_SEXPR"||s.name==="CLOSE_SEXPR")&&s.name!=="DATA"&&t[r-1]?.name!=="DATA"&&s.name!=="EQUALS"&&!(s.name==="ID"&&t[r+1]?.name==="EQUALS")&&s.name==="ID"&&!j(s.text)){if(t[r-1]?.name==="OPEN_SEXPR")continue;let i=q(t,r);i.length>0&&(Y(i,o,e),r+=i.length*2-2);}}}function Y(t,n,o,e){let r=t[0],s=n.contextPrefix&&n.rootContext?{prefix:n.contextPrefix,root:n.rootContext}:null,l,i;s?(l=s.prefix+t.join("."),i=s.root):(l=t.join("."),i=void 0),o.has(l)||o.set(l,Qe(r,l,e,i));}function et(t,n){return n.type==="endblock"&&t.length>0?t.slice(0,-1):t}function tt(t){let n=new Map,o=[];for(let e of t){let r=Ge(o),s={contextPrefix:r?.prefix??null,rootContext:r?.root??null};if(e.type==="mustache")Ye(e,s,n);else if(e.type==="block"){let l=Je(e,s,n);o=[...o,l];}else e.type==="partial"?Ze(e,s,n):e.type==="endblock"&&(o=et(o,e));}return Array.from(n.values())}function oe(t){let{expressions:n}=je(t),o=tt(n),e=[...new Set(o.filter(r=>!r.context).map(r=>r.name))];return {variables:o,rootVariables:e}}function nt(t,n,o){if(!n)return t;let e=o?.helpers?ne__default.default.create():ne__default.default;if(o?.helpers)for(let[r,s]of Object.entries(o.helpers))e.registerHelper(r,s);return e.compile(t)(n)}var ot=["direction","boxSizing","width","height","overflowX","overflowY","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderStyle","paddingTop","paddingRight","paddingBottom","paddingLeft","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","fontSizeAdjust","lineHeight","fontFamily","textAlign","textTransform","textIndent","textDecoration","letterSpacing","wordSpacing","tabSize","MozTabSize","whiteSpace","wordWrap","wordBreak","overflowWrap"];function be(t,n){let o=getComputedStyle(t),e=document.createElement("div");e.id="hbs-caret-mirror",document.body.appendChild(e);let r=e.style;r.position="absolute",r.visibility="hidden",r.whiteSpace="pre-wrap",r.wordWrap="break-word";for(let x of ot)r[x]=o[x];r.width=`${t.clientWidth}px`,r.height="auto",r.overflow="hidden";let s=t.value.substring(0,n);e.textContent=s;let l=document.createElement("span");l.textContent="\u200B",e.appendChild(l);let i=t.value.substring(n);i&&e.appendChild(document.createTextNode(i));let d=l.getBoundingClientRect(),O=e.getBoundingClientRect(),k={top:d.top-O.top,left:d.left-O.left,height:parseFloat(o.lineHeight)||parseFloat(o.fontSize)*1.2};return document.body.removeChild(e),k}var at=160,se=200,X=10,it=["--hbs-color-text","--hbs-color-border","--hbs-color-placeholder","--hbs-color-focus-ring","--hbs-color-autocomplete-bg","--hbs-color-autocomplete-selected"];function Ee({textareaRef:t,containerRef:n,triggerPosition:o,isOpen:e,children:r,listboxId:s}){let[l,i]=react.useState({top:void 0,bottom:void 0,left:0,maxHeight:se,visible:false}),[d,O]=react.useState({});react.useEffect(()=>{if(!e||!n.current)return;let E=getComputedStyle(n.current),P={};for(let c of it){let u=E.getPropertyValue(c).trim();u&&(P[c]=u);}O(P);},[e,n]);let k=react.useCallback(()=>{let E=t.current;if(!E||!e){i(m=>({...m,visible:false}));return}let P=E.getBoundingClientRect(),c=be(E,o),u=E.scrollTop,S=E.scrollLeft,N=P.top+c.top-u,V=P.left+c.left-S,g=c.height,K=window.innerHeight,ee=window.innerWidth,R=K-N-g-X,Q=N-X,te=R<120&&Q>R,w,U,W;te?(W=Math.min(se,Math.max(80,Q)),U=K-N+X,w=void 0):(W=Math.min(se,Math.max(80,R)),w=N+g,U=void 0);let z=V,G=ee-at-X;z>G&&(z=Math.max(X,G));let a=c.top-u>=0&&c.top-u<E.clientHeight,p=c.left-S>=0&&c.left-S<E.clientWidth;i({top:w,bottom:U,left:z,maxHeight:W,visible:a&&p});},[t,o,e]);if(react.useEffect(()=>{k();},[k]),react.useEffect(()=>{if(!e)return;let E=()=>{k();};return window.addEventListener("scroll",E,true),window.addEventListener("resize",E),()=>{window.removeEventListener("scroll",E,true),window.removeEventListener("resize",E);}},[e,k]),!e||!l.visible)return null;let x={top:l.top,bottom:l.bottom,left:l.left,maxHeight:l.maxHeight,...d};return reactDom.createPortal(jsxRuntime.jsx("div",{id:s,role:"listbox","aria-label":"Autocomplete suggestions",className:"hbs-autocomplete-portal",style:x,children:r}),document.body)}var ut=["this","@index","@first","@last","@key"],ft=["@root"];function dt(t,n){if(!n)return "prefix";let o=t.toLowerCase(),e=n.toLowerCase();return o===e?"exact":o.startsWith(e)?"prefix":o.includes(e)?"partial":"none"}function ht(t,n,o,e,r){let s=[],l=new Set,i=r.lastIndexOf("."),d=i!==-1;d?r.slice(0,i+1):"";let k=d?r.slice(i+1):r,x=(c,u)=>{if(l.has(c))return;let S=dt(c,k);S!=="none"&&(l.add(c),s.push({option:{value:c,type:u},matchType:S}));};if(d){let c=r.slice(0,i).replace(/\[\]$/,"");n.forEach(u=>{let S=u.path.replace(/\[\]/g,"");if(S.startsWith(`${c}.`)){let V=S.slice(c.length+1).split(".")[0];x(V,"variable");}});}else {if(!o){for(let u of J)x(`#${u}`,"block-open");for(let u of J)x(`/${u}`,"block-close");x("else","block-close");}for(let u of t)x(u,"helper");if(e){if(e.isEach)for(let u of ut)x(u,"data-var");for(let u of e.blockParams)x(u,"variable");for(let u of ft)x(u,"data-var");}let c=new Set;for(let u of n){let S=u.path.split(".")[0].replace("[]","");c.add(S);}for(let u of c)x(u,"variable");}let E={"data-var":0,variable:1,helper:2,"block-open":3,"block-close":4},P={exact:0,prefix:1,partial:2,none:3};return s.sort((c,u)=>{let S=P[c.matchType]-P[u.matchType];if(S!==0)return S;let N=E[c.option.type]-E[u.option.type];return N!==0?N:c.option.value.localeCompare(u.option.value)}),s.map(c=>c.option)}function mt(t,n){let o=t.slice(0,n),e=[],r=/\{\{#(each|with)\s+([^\s}]+)(?:\s+as\s*\|([^|]+)\|)?|\{\{\/(each|with)\}\}/g;for(let s of o.matchAll(r))if(s[1]){let l=s[1],i=s[2],O=(s[3]||"").split(/\s+/).filter(Boolean);e.push({type:l,variable:i,blockParams:O,isEach:l==="each"});}else if(s[4]){let l=s[4];for(let i=e.length-1;i>=0;i--)if(e[i].type===l){e.splice(i,1);break}}return e.length>0?e[e.length-1]:null}function bt(t,n){let o=t.slice(0,n),e=o.lastIndexOf("{{!--");if(e!==-1&&o.slice(e).indexOf("--}}")===-1)return true;let r=o.lastIndexOf("{{!");if(r!==-1){let s=o.slice(r);if(!s.startsWith("{{!--")&&s.indexOf("}}")===-1)return true}return false}function xt(t,n){let o=t.slice(0,n),e=t.slice(n),r=o.lastIndexOf("{{");if(r===-1||o.slice(r).includes("}}"))return false;let l=e.indexOf("}}");return l===-1?false:!e.slice(0,l).includes("{{")}function ye({value:t,onChange:n,placeholder:o="Enter template...",readOnly:e=false,className:r="",style:s,theme:l,customHelpers:i=[],autocomplete:d=true,minHeight:O=100}){let k=react.useRef(null),x=react.useRef(null),E=react.useRef(null),P=react.useId(),[c,u]=react.useState({isOpen:false,options:[],selectedIndex:0,triggerStart:0,filterText:"",isRaw:false,contextPath:null}),S=react.useMemo(()=>oe(t).variables.map(p=>({path:p.path,context:p.context})),[t]),N=react.useMemo(()=>M(t),[t]),V=react.useMemo(()=>t?N.map(a=>a.type==="text"?a.value:jsxRuntime.jsx("span",{className:`hbs-token-${a.type}`,children:a.value},a.start)):jsxRuntime.jsx("span",{className:"hbs-editor-placeholder",children:o}),[N,t,o]),g=react.useCallback(()=>{u(a=>({...a,isOpen:false}));},[]),K=react.useCallback((a,p)=>{if(!d||e){g();return}if(bt(a,p)||xt(a,p)){g();return}let m=a.slice(0,p).match(/(\{\{\{?)([#/]?[\w.@]*)$/);if(!m){g();return}let y=m[1],f=m[2]||"",C=p-f.length,b=y==="{{{";if(f.includes("}")){g();return}let T=mt(a,p),A=ht(i,S,b,T,f);if(A.length===0){g();return}u({isOpen:true,options:A,selectedIndex:0,triggerStart:C,filterText:f,isRaw:b,contextPath:T});},[d,e,i,S,g]),ee=react.useCallback(a=>{let p=a.target.value;n?.(p),K(p,a.target.selectionStart);},[n,K]),R=react.useCallback(a=>{let p=x.current;if(!p)return;let{triggerStart:h,filterText:m,isRaw:y}=c,f=y?"}}}":"}}",C=m.lastIndexOf("."),b=C!==-1?m.slice(0,C+1):"",T,A;if(a.type==="block-open"&&!y){let I=a.value.slice(1);T=`${a.value} }}{{/${I}}}`,A=a.value.length+1;}else a.type!=="block-close"&&a.value!=="else"?(T=`${b}${a.value}${f}`,A=T.length):(T=`${a.value}${f}`,A=T.length);p.focus(),p.setSelectionRange(h,p.selectionStart),document.execCommand("insertText",false,T);let B=h+A;p.setSelectionRange(B,B),n?.(p.value),g();},[c,n,g]),Q=react.useCallback(a=>{let{scrollTop:p,scrollLeft:h}=a.currentTarget;E.current&&(E.current.scrollTop=p,E.current.scrollLeft=h);},[]),te=react.useCallback(a=>{document.querySelector(".hbs-autocomplete-portal")?.contains(a.relatedTarget)||g();},[g]),w=react.useCallback(()=>{let a=x.current;if(!a||!c.isOpen)return;let p=a.selectionStart;t.slice(0,p).match(/(\{\{\{?)([#/]?[\w.@]*)$/)||g();},[c.isOpen,t,g]),U=react.useCallback(a=>{let p=a.currentTarget;if(a.key==="Tab"){if(c.isOpen){a.preventDefault();let C=c.options[c.selectedIndex];C&&R(C);return}a.preventDefault();let{selectionStart:f}=p;if(a.shiftKey){let b=t.slice(0,f).lastIndexOf(`
|
|
3
|
+
`)+1,A=t.slice(b,f).match(/^(\t| {2})/);if(A){let B=A[1].length,I=t.slice(0,b)+t.slice(b+B);n?.(I);let L=Math.max(b,f-B);setTimeout(()=>p.setSelectionRange(L,L),0);}}else document.execCommand("insertText",false," "),n?.(p.value);return}if((a.metaKey||a.ctrlKey)&&(a.key==="z"||a.key==="y")||!c.isOpen)return;let{options:h,selectedIndex:m}=c,y=8;switch(a.key){case "ArrowDown":a.preventDefault(),u(f=>({...f,selectedIndex:Math.min(m+1,h.length-1)}));break;case "ArrowUp":a.preventDefault(),u(f=>({...f,selectedIndex:Math.max(m-1,0)}));break;case "Home":a.preventDefault(),u(f=>({...f,selectedIndex:0}));break;case "End":a.preventDefault(),u(f=>({...f,selectedIndex:h.length-1}));break;case "PageDown":a.preventDefault(),u(f=>({...f,selectedIndex:Math.min(m+y,h.length-1)}));break;case "PageUp":a.preventDefault(),u(f=>({...f,selectedIndex:Math.max(m-y,0)}));break;case "Enter":a.preventDefault(),h[m]&&R(h[m]);break;case "Escape":a.preventDefault(),g();break;case "ArrowLeft":case "ArrowRight":setTimeout(()=>w(),0);break}},[c,R,g,w,t,n]),W=react.useMemo(()=>{if(!l)return {};let a={},p={variable:"--hbs-color-variable",variablePath:"--hbs-color-variable-path",blockKeyword:"--hbs-color-block-keyword",blockParam:"--hbs-color-block-param",helper:"--hbs-color-helper",helperArg:"--hbs-color-helper-arg",hashKey:"--hbs-color-hash-key",hashValue:"--hbs-color-hash-value",literal:"--hbs-color-literal",dataVar:"--hbs-color-data-var",subexprParen:"--hbs-color-subexpr-paren",comment:"--hbs-color-comment",raw:"--hbs-color-raw",brace:"--hbs-color-brace",text:"--hbs-color-text",background:"--hbs-color-background",caret:"--hbs-color-caret",border:"--hbs-color-border",placeholder:"--hbs-color-placeholder"};for(let[h,m]of Object.entries(p)){let y=l[h];y&&(a[m]=y);}return a},[l]);react.useEffect(()=>{if(!c.isOpen)return;let a=document.querySelector(".hbs-autocomplete-portal");if(!a)return;let h=a.querySelectorAll(".hbs-autocomplete-item")[c.selectedIndex];h&&h.scrollIntoView({block:"nearest"});},[c.selectedIndex,c.isOpen]),react.useEffect(()=>{if(!c.isOpen)return;let a=k.current,p=m=>{let y=m.target;document.querySelector(".hbs-autocomplete-portal")?.contains(y)||a&&!a.contains(y)&&g();},h=m=>{let y=m.target;document.querySelector(".hbs-autocomplete-portal")?.contains(y)||a?.contains(y)&&y!==x.current&&g();};return document.addEventListener("mousedown",p),a?.addEventListener("mousedown",h),()=>{document.removeEventListener("mousedown",p),a?.removeEventListener("mousedown",h);}},[c.isOpen,g]);let z=react.useCallback((a,p)=>{let{filterText:h,selectedIndex:m}=c,y=p===m,f=h.lastIndexOf("."),C=f!==-1?h.slice(f+1):h,b=a.value;(a.type==="block-open"&&b.startsWith("#")||a.type==="block-close"&&b.startsWith("/")||a.type==="data-var"&&b.startsWith("@"))&&(b=b.slice(1));let T,A=C.toLowerCase().replace(/^[#/@]/,""),I=b.toLowerCase().indexOf(A);if(A.length>0&&I!==-1){let $=b.slice(0,I),Se=b.slice(I,I+A.length),Ae=b.slice(I+A.length);T=jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[$,jsxRuntime.jsx("span",{className:"hbs-autocomplete-match",children:Se}),Ae]});}else T=b;let L="";switch(a.type){case "block-open":L="#";break;case "block-close":L="/";break;case "data-var":L="@";break;case "helper":L="\u0192";break;case "variable":L="\xB7";break}let Oe=jsxRuntime.jsx("span",{className:"hbs-autocomplete-type",children:L});return jsxRuntime.jsxs("button",{id:`${P}-option-${p}`,type:"button",role:"option","aria-selected":y,className:`hbs-autocomplete-item hbs-autocomplete-${a.type} ${y?"hbs-selected":""}`,onMouseDown:$=>{$.preventDefault(),R(a);},onMouseEnter:()=>u($=>({...$,selectedIndex:p})),children:[Oe,jsxRuntime.jsx("span",{className:"hbs-autocomplete-value",children:T})]},a.value)},[c,R,P]),G=["hbs-editor",e?"hbs-readonly":"",r].filter(Boolean).join(" ");return jsxRuntime.jsxs("div",{ref:k,className:G,style:{...W,minHeight:typeof O=="number"?`${O}px`:O,...s},children:[jsxRuntime.jsx("div",{ref:E,className:"hbs-editor-highlight",children:V}),jsxRuntime.jsx("textarea",{ref:x,className:"hbs-editor-textarea",value:t,onChange:ee,onKeyDown:U,onScroll:Q,onBlur:te,onSelect:w,placeholder:"",readOnly:e,spellCheck:false,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",role:"combobox","aria-haspopup":"listbox","aria-expanded":d&&c.isOpen,"aria-controls":P,"aria-activedescendant":d&&c.isOpen&&c.options[c.selectedIndex]?`${P}-option-${c.selectedIndex}`:void 0}),d&&jsxRuntime.jsx(Ee,{textareaRef:x,containerRef:k,triggerPosition:c.triggerStart,isOpen:c.isOpen,listboxId:P,children:c.options.map((a,p)=>z(a,p))})]})}function gt({content:t,className:n}){if(!t)return null;let o=M(t);return jsxRuntime.jsx("span",{className:n,children:o.map(e=>jsxRuntime.jsx("span",{className:`hbs-token-${e.type}`,children:e.value},e.start))})}exports.HandlebarsEditor=ye;exports.HandlebarsHighlight=gt;exports.default=ye;exports.extract=oe;exports.interpolate=nt;exports.tokenize=M;
|
package/dist/index.d.cts
CHANGED
|
@@ -106,20 +106,41 @@ interface HandlebarsEditorProps {
|
|
|
106
106
|
/** Minimum height */
|
|
107
107
|
minHeight?: string | number;
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Autocomplete option with metadata
|
|
111
|
+
*/
|
|
112
|
+
interface AutocompleteOption {
|
|
113
|
+
/** Display value (the part to insert) */
|
|
114
|
+
value: string;
|
|
115
|
+
/** Type of option for styling */
|
|
116
|
+
type: 'block-open' | 'block-close' | 'helper' | 'variable' | 'data-var';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Block context information
|
|
120
|
+
*/
|
|
121
|
+
interface BlockContext {
|
|
122
|
+
type: 'each' | 'with';
|
|
123
|
+
variable: string;
|
|
124
|
+
blockParams: string[];
|
|
125
|
+
isEach: boolean;
|
|
126
|
+
}
|
|
109
127
|
/**
|
|
110
128
|
* Autocomplete state
|
|
111
129
|
*/
|
|
112
130
|
interface AutocompleteState {
|
|
113
131
|
isOpen: boolean;
|
|
114
|
-
options:
|
|
132
|
+
options: AutocompleteOption[];
|
|
115
133
|
selectedIndex: number;
|
|
134
|
+
/** Position where the replaceable text starts (after {{) */
|
|
116
135
|
triggerStart: number;
|
|
136
|
+
/** Current filter text typed by user */
|
|
117
137
|
filterText: string;
|
|
138
|
+
/** Whether triggered by triple braces {{{ for raw output */
|
|
139
|
+
isRaw: boolean;
|
|
140
|
+
/** Current block context if inside #each/#with */
|
|
141
|
+
contextPath: BlockContext | null;
|
|
118
142
|
}
|
|
119
143
|
|
|
120
|
-
/**
|
|
121
|
-
* Handlebars template editor with syntax highlighting
|
|
122
|
-
*/
|
|
123
144
|
declare function HandlebarsEditor({ value, onChange, placeholder, readOnly, className, style, theme, customHelpers, autocomplete, minHeight, }: HandlebarsEditorProps): react_jsx_runtime.JSX.Element;
|
|
124
145
|
|
|
125
146
|
interface HandlebarsHighlightProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -106,20 +106,41 @@ interface HandlebarsEditorProps {
|
|
|
106
106
|
/** Minimum height */
|
|
107
107
|
minHeight?: string | number;
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Autocomplete option with metadata
|
|
111
|
+
*/
|
|
112
|
+
interface AutocompleteOption {
|
|
113
|
+
/** Display value (the part to insert) */
|
|
114
|
+
value: string;
|
|
115
|
+
/** Type of option for styling */
|
|
116
|
+
type: 'block-open' | 'block-close' | 'helper' | 'variable' | 'data-var';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Block context information
|
|
120
|
+
*/
|
|
121
|
+
interface BlockContext {
|
|
122
|
+
type: 'each' | 'with';
|
|
123
|
+
variable: string;
|
|
124
|
+
blockParams: string[];
|
|
125
|
+
isEach: boolean;
|
|
126
|
+
}
|
|
109
127
|
/**
|
|
110
128
|
* Autocomplete state
|
|
111
129
|
*/
|
|
112
130
|
interface AutocompleteState {
|
|
113
131
|
isOpen: boolean;
|
|
114
|
-
options:
|
|
132
|
+
options: AutocompleteOption[];
|
|
115
133
|
selectedIndex: number;
|
|
134
|
+
/** Position where the replaceable text starts (after {{) */
|
|
116
135
|
triggerStart: number;
|
|
136
|
+
/** Current filter text typed by user */
|
|
117
137
|
filterText: string;
|
|
138
|
+
/** Whether triggered by triple braces {{{ for raw output */
|
|
139
|
+
isRaw: boolean;
|
|
140
|
+
/** Current block context if inside #each/#with */
|
|
141
|
+
contextPath: BlockContext | null;
|
|
118
142
|
}
|
|
119
143
|
|
|
120
|
-
/**
|
|
121
|
-
* Handlebars template editor with syntax highlighting
|
|
122
|
-
*/
|
|
123
144
|
declare function HandlebarsEditor({ value, onChange, placeholder, readOnly, className, style, theme, customHelpers, autocomplete, minHeight, }: HandlebarsEditorProps): react_jsx_runtime.JSX.Element;
|
|
124
145
|
|
|
125
146
|
interface HandlebarsHighlightProps {
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {useRef,useState,useMemo,useCallback,useEffect}from'react';import
|
|
2
|
-
`);P.setInput(r);try{for(let t=P.lex();t!==P.EOF;t=P.lex()){let c=me[t]||"UNKNOWN",n=P.yylloc;a.push({type:c,text:P.yytext,start:J(e,n.first_line,n.first_column),end:J(e,n.last_line,n.last_column)});}}catch{}return a}function xe(r,a){let e=r[a-1],t=r[a+1];return e&&(e.type==="OPEN_BLOCK"||e.type==="OPEN_INVERSE"||e.type==="OPEN_INVERSE_CHAIN"||e.type==="OPEN_ENDBLOCK")?"block-keyword":e?.type==="OPEN_PARTIAL"||e?.type==="OPEN_PARTIAL_BLOCK"||e?.type==="OPEN_SEXPR"?"helper":e?.type==="OPEN"||e?.type==="OPEN_UNESCAPED"?t&&(t.type==="ID"||t.type==="SEP"||t.type==="STRING"||t.type==="NUMBER"||t.type==="BOOLEAN"||t.type==="DATA"||t.type==="OPEN_SEXPR")?"helper":"variable":e?.type==="EQUALS"?"hash-value":e?.type==="ID"?t?.type==="EQUALS"?"hash-key":"helper-arg":e?.type==="DATA"||e?.type==="SEP"?"helper-arg":e?.type==="OPEN_BLOCK_PARAMS"?"block-param":"variable"}function ye(r,a){let e=[],t=0;for(let c=0;c<a.length;c++){let n=a[c];n.start>t&&e.push({type:"text",value:r.slice(t,n.start),start:t,end:n.start});let b=ge[n.type]||"text";if(n.type==="ID"&&(b=xe(a,c)),n.type==="DATA"){let d=a[c+1];if(d?.type==="ID"&&d.start===n.end){e.push({type:"data-var",value:r.slice(n.start,d.end),start:n.start,end:d.end}),t=d.end,c++;continue}}e.push({type:b,value:r.slice(n.start,n.end),start:n.start,end:n.end}),t=n.end;}return t<r.length&&e.push({type:"text",value:r.slice(t),start:t,end:r.length}),e}function L(r){if(!r)return [];let a=Ee(r);return ye(r,a).filter(e=>e.value.length>0)}var Z=new Set(["if","unless","each","with","lookup","log","this","else"]),M=new Set(["each","with"]);function K(r){return Z.has(r)||r.startsWith("@")}var ee=V.Parser,O=ee.lexer,Oe=ee.terminals_;function Ne(r){let a=new Map,e=r;for(;e.length>0;){let t=ke(e,a);if(t===e.length)break;let c=e.slice(t),n=c.search(/\{\{/);if(n===-1)break;e=c.slice(n);}return Array.from(a.values())}function ke(r,a){O.setInput(r),O.conditionStack=["INITIAL"];let e=0,t=false,c=null,n=[],b=[];function d(i,l){let f=[];for(let o=l;o<i.length;o++)if(i[o].name==="ID")f.push(i[o].text);else if(i[o].name!=="SEP")break;return f}function x(i,l,f){a.has(l)||a.set(l,{name:i,path:l,type:f?"block":l.includes(".")?"nested":"simple",blockType:f});}function _(){if(n.length===0)return;let i=0;if(n[i]?.name==="DATA")return;let l=n[i].text;if(c==="block"){let f=b.some(o=>M.has(o.helper));if(M.has(l)){for(i++;i<n.length&&n[i].name!=="ID";)i++;if(i<n.length){let o=d(n,i);o.length>0&&!K(o[0])&&!f&&x(o[0],o.join("."),l),b.push({helper:l,context:o[0]||""});}}else if(Z.has(l)){for(i++;i<n.length&&n[i].name!=="ID";)i++;if(i<n.length){let o=d(n,i);o.length>0&&!K(o[0])&&!f&&x(o[0],o.join("."),l);}b.push({helper:l,context:""});}else b.push({helper:l,context:""});}else if(c==="endblock")b.length>0&&b.pop();else {let f=b.some(o=>M.has(o.helper));if(!K(l)&&!f){let o=d(n,i);o.length>0&&x(o[0],o.join("."));}}}try{for(let i=O.lex();i!==O.EOF;i=O.lex()){let l=Oe[i],f=O.yytext;if(e=O.yylloc?.last_column??e,!(l==="OPEN_RAW_BLOCK"||l==="CLOSE_RAW_BLOCK"||l==="END_RAW_BLOCK")){if(l==="OPEN"||l==="OPEN_UNESCAPED"){t=!0,c="mustache",n=[];continue}if(l==="OPEN_BLOCK"||l==="OPEN_INVERSE"||l==="OPEN_INVERSE_CHAIN"){t=!0,c="block",n=[];continue}if(l==="OPEN_ENDBLOCK"){t=!0,c="endblock",n=[];continue}if(l==="CLOSE"||l==="CLOSE_UNESCAPED"){_(),t=!1,n=[];continue}t&&n.push({name:l,text:f});}}return r.length}catch{return e}}function U(r){let a=Ne(r),e=[...new Set(a.map(t=>t.name))];return {variables:a,rootVariables:e}}function Pe(r,a,e){if(!a)return r;let t=e?.helpers?V.create():V;if(e?.helpers)for(let[c,n]of Object.entries(e.helpers))t.registerHelper(c,n);return t.compile(r)(a)}var Se=["#if","#each","#with","#unless","/if","/each","/with","/unless","else"];function re({value:r,onChange:a,placeholder:e="Enter template...",readOnly:t=false,className:c="",style:n,theme:b,customHelpers:d=[],autocomplete:x=true,minHeight:_=100}){let i=useRef(null),l=useRef(null),f=useRef(null),[o,y]=useState({isOpen:false,options:[],selectedIndex:0,triggerStart:0,filterText:""}),[R,se]=useState({top:0,left:0}),z=useMemo(()=>U(r).rootVariables,[r]),F=useMemo(()=>[...Se,...d,...z],[d,z]),$=useMemo(()=>L(r),[r]),oe=useMemo(()=>r?$.map(s=>s.type==="text"?s.value:jsx("span",{className:`hbs-token-${s.type}`,children:s.value},s.start)):jsx("span",{className:"hbs-editor-placeholder",children:e}),[$,r,e]),ae=useCallback(s=>{let p=s.target.value;if(a?.(p),!x||t)return;let h=s.target.selectionStart,m=p.slice(0,h).match(/\{\{([#/]?\w*)$/);if(m){let g=m[1]||"",E=h-g.length,N=F.filter(w=>w.toLowerCase().startsWith(g.toLowerCase()));if(N.length>0){y({isOpen:true,options:N,selectedIndex:0,triggerStart:E,filterText:g});return}}y(g=>({...g,isOpen:false}));},[a,x,t,F]),v=useCallback(s=>{let p=i.current;if(!p)return;let{triggerStart:h}=o,u=s,m=s.length;if(s.startsWith("#")){let E=s.slice(1);u=`${s} }}{{/${E}}}`,m=s.length+1;}else !s.startsWith("/")&&s!=="else"?(u=`${s}}}`,m=u.length):(u=`${s}}}`,m=u.length);p.focus(),p.setSelectionRange(h,p.selectionStart),document.execCommand("insertText",false,u);let g=h+m;p.setSelectionRange(g,g),a?.(p.value),y(E=>({...E,isOpen:false}));},[a,o]),le=useCallback(s=>{let{scrollTop:p,scrollLeft:h}=s.currentTarget;l.current&&(l.current.scrollTop=p,l.current.scrollLeft=h),se({top:p,left:h});},[]),ie=useCallback(s=>{if(!o.isOpen)return;let{options:p,selectedIndex:h}=o;switch(s.key){case "ArrowDown":s.preventDefault(),y(u=>({...u,selectedIndex:Math.min(h+1,p.length-1)}));break;case "ArrowUp":s.preventDefault(),y(u=>({...u,selectedIndex:Math.max(h-1,0)}));break;case "Enter":case "Tab":s.preventDefault(),p[h]&&v(p[h]);break;case "Escape":s.preventDefault(),y(u=>({...u,isOpen:false}));break}},[o,v]),I=useMemo(()=>{if(!o.isOpen||!i.current)return {top:0,left:0,maxHeight:192,openUpward:false,visible:false};let s=i.current,{triggerStart:p}=o,u=r.slice(0,p).split(`
|
|
3
|
-
`),
|
|
1
|
+
import {useRef,useId,useState,useMemo,useCallback,useEffect}from'react';import ne from'handlebars';import {createPortal}from'react-dom';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var ce=ne.Parser,H=ce.lexer,Te=ce.terminals_,Ne=new Set(["OPEN_BLOCK","OPEN_INVERSE","OPEN_INVERSE_CHAIN","OPEN_ENDBLOCK"]),Ce=new Set(["OPEN","OPEN_UNESCAPED"]),Re=new Set(["OPEN_PARTIAL","OPEN_PARTIAL_BLOCK"]),Ie=new Set(["OPEN","OPEN_UNESCAPED","OPEN_BLOCK","OPEN_INVERSE","OPEN_INVERSE_CHAIN","OPEN_ENDBLOCK","OPEN_PARTIAL","OPEN_PARTIAL_BLOCK"]),Le=new Set(["CLOSE","CLOSE_UNESCAPED","CLOSE_RAW_BLOCK","END_RAW_BLOCK"]),_e=new Set(["ID","STRING","NUMBER","BOOLEAN","DATA","OPEN_SEXPR","UNDEFINED","NULL"]),pe=t=>Ne.has(t),ue=t=>Ce.has(t),fe=t=>Re.has(t),ve=t=>Ie.has(t),we=t=>Le.has(t),De=t=>_e.has(t),Be={CONTENT:"text",COMMENT:"comment",OPEN:"brace",CLOSE:"brace",OPEN_UNESCAPED:"brace",CLOSE_UNESCAPED:"brace",OPEN_RAW_BLOCK:"brace",CLOSE_RAW_BLOCK:"brace",END_RAW_BLOCK:"brace",OPEN_BLOCK:"brace",OPEN_INVERSE:"brace",OPEN_INVERSE_CHAIN:"brace",OPEN_ENDBLOCK:"brace",OPEN_PARTIAL:"brace",OPEN_PARTIAL_BLOCK:"brace",OPEN_SEXPR:"subexpr-paren",CLOSE_SEXPR:"subexpr-paren",OPEN_BLOCK_PARAMS:"block-keyword",CLOSE_BLOCK_PARAMS:"block-keyword",INVERSE:"block-keyword",ID:"variable",STRING:"literal",NUMBER:"literal",BOOLEAN:"literal",UNDEFINED:"literal",NULL:"literal",DATA:"data-var",SEP:"brace",EQUALS:"brace"};function le(t,n,o){let e=0;for(let r=0;r<n-1&&r<t.length;r++)e+=t[r].length+1;return e+o}function He(t){let n=[],o=t.split(`
|
|
2
|
+
`);H.setInput(t);try{for(let e=H.lex();e!==H.EOF;e=H.lex()){let r=Te[e]||"UNKNOWN",s=H.yylloc;n.push({type:r,text:H.yytext,start:le(o,s.first_line,s.first_column),end:le(o,s.last_line,s.last_column)});}}catch{}return n}function Me(t){return t.map(n=>n.type==="ID"&&n.text==="."?{...n,type:"SEP"}:n.type==="ID"&&n.text==="="?{...n,type:"EQUALS"}:n)}function Ve(t){let n=[],o=null,e=false,r=false,s=0;for(let l=0;l<t.length;l++){let i=t[l],d=t[l-1];ve(i.type)?(pe(i.type)?o=i.type==="OPEN_ENDBLOCK"?"block-close":"block-open":fe(i.type)?o="partial":ue(i.type)&&(o="mustache"),r=false,s=0):we(i.type)&&(o=null,r=false,s=0),i.type==="OPEN_BLOCK_PARAMS"?e=true:i.type==="CLOSE_BLOCK_PARAMS"&&(e=false),i.type==="SEP"?s++:i.type==="ID"&&d?.type!=="SEP"&&d?.type!=="DATA"&&(s=0);let O=false;if(i.type==="ID"){if(s===0)O=r;else for(let k=l-1;k>=0;k--)if(t[k].type==="ID"&&n[k]?.context.pathRootAfterHelper!==void 0){let x=t[k-1];if(x?.type!=="SEP"&&x?.type!=="DATA"){O=n[k].context.pathRootAfterHelper;break}}}n.push({...i,context:{type:o,isInBlockParams:e,pathRootAfterHelper:O}}),i.type==="ID"&&s===0&&!e&&d?.type!=="EQUALS"&&d?.type!=="DATA"&&(r=true);}return n}function Ke(t,n,o){let{context:e}=t;return t.text==="this"?"data-var":e.isInBlockParams?"block-param":o?.type==="EQUALS"?"hash-key":n?.type==="EQUALS"?"hash-value":n?.type==="DATA"?"data-var":n?.type==="SEP"?e.pathRootAfterHelper?"helper-arg":"variable-path":Ue(t,n,o)}function Ue(t,n,o){let{context:e}=t;return e.type==="block-open"||e.type==="block-close"?pe(n?.type??"")?"block-keyword":"helper-arg":e.type==="partial"?fe(n?.type??"")?"helper":"helper-arg":n?.type==="OPEN_SEXPR"?"helper":e.type==="mustache"?ue(n?.type??"")?o?.type==="SEP"?"variable":o&&De(o.type)?"helper":"variable":"helper-arg":"variable"}function We(t){return t.map((n,o)=>{let e=t[o-1],r=t[o+1],s;return n.type==="ID"?s=Ke(n,e,r):s=Be[n.type]||"text",{token:n,highlightType:s}})}function ze(t,n){let o=[],e=0;for(let r=0;r<n.length;r++){let{token:s,highlightType:l}=n[r];if(s.start>e&&o.push({type:"text",value:t.slice(e,s.start),start:e,end:s.start}),s.type==="DATA"){let i=n[r+1];if(i?.token.type==="ID"&&i.token.start===s.end){o.push({type:"data-var",value:t.slice(s.start,i.token.end),start:s.start,end:i.token.end}),e=i.token.end,r++;continue}}o.push({type:l,value:t.slice(s.start,s.end),start:s.start,end:s.end}),e=s.end;}return e<t.length&&o.push({type:"text",value:t.slice(e),start:e,end:t.length}),o}function M(t){if(!t)return [];let n=He(t),o=Me(n),e=Ve(o),r=We(e);return ze(t,r).filter(l=>l.value.length>0)}var J=["if","unless","each","with"],de=new Set([...J,"lookup","log","this","else"]),he=new Set(["each","with"]),$e=new Set(["ID","STRING","NUMBER","BOOLEAN","DATA","OPEN_SEXPR"]),me=ne.Parser,D=me.lexer,Fe=me.terminals_;function j(t){return de.has(t)||t.startsWith("@")}function Xe(t){return $e.has(t.name)}function q(t,n){let o=[],e=true;for(let r=n;r<t.length;r++){let s=t[r];if(s.name==="EQUALS")break;if(s.name==="ID"){if(!e||t[r+1]?.name==="EQUALS")break;o.push(s.text),e=false;}else if(s.name==="SEP")e=true;else break}return o}function Qe(t,n,o,e){return {name:t,path:n,type:o?"block":n.includes(".")||e?"nested":"simple",blockType:o,context:e}}function Ge(t){let n=[],o=null;for(let e of t)he.has(e.helper)&&e.context&&(o||(o=e.context),n.push(e.helper==="each"?`${e.context}[]`:e.context));return n.length===0||!o?null:{root:o,prefix:`${n.join(".")}.`}}function je(t){let n=[],o=t;for(;o.length>0;){let e=qe(o);if(n.push(...e.expressions),e.consumed===o.length)break;let r=o.slice(e.consumed),s=r.search(/\{\{/);if(s===-1)break;o=r.slice(s);}return {expressions:n}}function qe(t){D.setInput(t),D.conditionStack=["INITIAL"];let n=[],o=0,e=false,r=null,s=[];try{for(let l=D.lex();l!==D.EOF;l=D.lex()){let i=Fe[l],d=D.yytext;if(o=D.yylloc?.last_column??o,!(i==="OPEN_RAW_BLOCK"||i==="CLOSE_RAW_BLOCK"||i==="END_RAW_BLOCK")){if(i==="OPEN"||i==="OPEN_UNESCAPED"){e=!0,r="mustache",s=[];continue}if(i==="OPEN_PARTIAL"||i==="OPEN_PARTIAL_BLOCK"){e=!0,r="partial",s=[];continue}if(i==="OPEN_BLOCK"||i==="OPEN_INVERSE"||i==="OPEN_INVERSE_CHAIN"){e=!0,r="block",s=[];continue}if(i==="OPEN_ENDBLOCK"){e=!0,r="endblock",s=[];continue}if(i==="CLOSE"||i==="CLOSE_UNESCAPED"){if(r){let O=s[0]?.text??null;n.push({type:r,tokens:[...s],helperName:O});}e=!1,s=[];continue}e&&s.push({name:i,text:d});}}return {expressions:n,consumed:t.length}}catch{return {expressions:n,consumed:o}}}function Ye(t,n,o){let e=t.tokens;if(e.length===0||e[0]?.name==="DATA")return;let r=e[0]?.text;if(j(r))F(e,1,n,o);else {let s=q(e,0);if(s.length>0){let i=s.length*2-1,d=e[i];d&&Xe(d)?F(e,i,n,o):Y(s,n,o);}}}function Je(t,n,o){let e=t.tokens,r=e[0]?.text;if(he.has(r)){if(e[1]?.name==="OPEN_SEXPR")return F(e,1,n,o),{helper:r,context:""};{let s=1;for(;s<e.length&&e[s].name!=="ID";)s++;if(s<e.length){let l=q(e,s);return l.length>0&&!j(l[0])&&Y(l,n,o,r),{helper:r,context:l[0]||""}}return {helper:r,context:""}}}else if(de.has(r)){if(e[1]?.name==="OPEN_SEXPR")F(e,1,n,o);else {let s=1;for(;s<e.length&&e[s].name!=="ID";)s++;if(s<e.length){let l=q(e,s);l.length>0&&!j(l[0])&&Y(l,n,o,r);}}return {helper:r,context:""}}return {helper:r,context:""}}function Ze(t,n,o){let e=t.tokens,r=1;for(;r<e.length&&(e[r].name==="SEP"||e[r].name==="ID")&&!(e[r].name==="ID"&&e[r-1]?.name!=="SEP");)r++;F(e,r,n,o);}function F(t,n,o,e){for(let r=n;r<t.length;r++){let s=t[r];if(!(s.name==="OPEN_SEXPR"||s.name==="CLOSE_SEXPR")&&s.name!=="DATA"&&t[r-1]?.name!=="DATA"&&s.name!=="EQUALS"&&!(s.name==="ID"&&t[r+1]?.name==="EQUALS")&&s.name==="ID"&&!j(s.text)){if(t[r-1]?.name==="OPEN_SEXPR")continue;let i=q(t,r);i.length>0&&(Y(i,o,e),r+=i.length*2-2);}}}function Y(t,n,o,e){let r=t[0],s=n.contextPrefix&&n.rootContext?{prefix:n.contextPrefix,root:n.rootContext}:null,l,i;s?(l=s.prefix+t.join("."),i=s.root):(l=t.join("."),i=void 0),o.has(l)||o.set(l,Qe(r,l,e,i));}function et(t,n){return n.type==="endblock"&&t.length>0?t.slice(0,-1):t}function tt(t){let n=new Map,o=[];for(let e of t){let r=Ge(o),s={contextPrefix:r?.prefix??null,rootContext:r?.root??null};if(e.type==="mustache")Ye(e,s,n);else if(e.type==="block"){let l=Je(e,s,n);o=[...o,l];}else e.type==="partial"?Ze(e,s,n):e.type==="endblock"&&(o=et(o,e));}return Array.from(n.values())}function oe(t){let{expressions:n}=je(t),o=tt(n),e=[...new Set(o.filter(r=>!r.context).map(r=>r.name))];return {variables:o,rootVariables:e}}function nt(t,n,o){if(!n)return t;let e=o?.helpers?ne.create():ne;if(o?.helpers)for(let[r,s]of Object.entries(o.helpers))e.registerHelper(r,s);return e.compile(t)(n)}var ot=["direction","boxSizing","width","height","overflowX","overflowY","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderStyle","paddingTop","paddingRight","paddingBottom","paddingLeft","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","fontSizeAdjust","lineHeight","fontFamily","textAlign","textTransform","textIndent","textDecoration","letterSpacing","wordSpacing","tabSize","MozTabSize","whiteSpace","wordWrap","wordBreak","overflowWrap"];function be(t,n){let o=getComputedStyle(t),e=document.createElement("div");e.id="hbs-caret-mirror",document.body.appendChild(e);let r=e.style;r.position="absolute",r.visibility="hidden",r.whiteSpace="pre-wrap",r.wordWrap="break-word";for(let x of ot)r[x]=o[x];r.width=`${t.clientWidth}px`,r.height="auto",r.overflow="hidden";let s=t.value.substring(0,n);e.textContent=s;let l=document.createElement("span");l.textContent="\u200B",e.appendChild(l);let i=t.value.substring(n);i&&e.appendChild(document.createTextNode(i));let d=l.getBoundingClientRect(),O=e.getBoundingClientRect(),k={top:d.top-O.top,left:d.left-O.left,height:parseFloat(o.lineHeight)||parseFloat(o.fontSize)*1.2};return document.body.removeChild(e),k}var at=160,se=200,X=10,it=["--hbs-color-text","--hbs-color-border","--hbs-color-placeholder","--hbs-color-focus-ring","--hbs-color-autocomplete-bg","--hbs-color-autocomplete-selected"];function Ee({textareaRef:t,containerRef:n,triggerPosition:o,isOpen:e,children:r,listboxId:s}){let[l,i]=useState({top:void 0,bottom:void 0,left:0,maxHeight:se,visible:false}),[d,O]=useState({});useEffect(()=>{if(!e||!n.current)return;let E=getComputedStyle(n.current),P={};for(let c of it){let u=E.getPropertyValue(c).trim();u&&(P[c]=u);}O(P);},[e,n]);let k=useCallback(()=>{let E=t.current;if(!E||!e){i(m=>({...m,visible:false}));return}let P=E.getBoundingClientRect(),c=be(E,o),u=E.scrollTop,S=E.scrollLeft,N=P.top+c.top-u,V=P.left+c.left-S,g=c.height,K=window.innerHeight,ee=window.innerWidth,R=K-N-g-X,Q=N-X,te=R<120&&Q>R,w,U,W;te?(W=Math.min(se,Math.max(80,Q)),U=K-N+X,w=void 0):(W=Math.min(se,Math.max(80,R)),w=N+g,U=void 0);let z=V,G=ee-at-X;z>G&&(z=Math.max(X,G));let a=c.top-u>=0&&c.top-u<E.clientHeight,p=c.left-S>=0&&c.left-S<E.clientWidth;i({top:w,bottom:U,left:z,maxHeight:W,visible:a&&p});},[t,o,e]);if(useEffect(()=>{k();},[k]),useEffect(()=>{if(!e)return;let E=()=>{k();};return window.addEventListener("scroll",E,true),window.addEventListener("resize",E),()=>{window.removeEventListener("scroll",E,true),window.removeEventListener("resize",E);}},[e,k]),!e||!l.visible)return null;let x={top:l.top,bottom:l.bottom,left:l.left,maxHeight:l.maxHeight,...d};return createPortal(jsx("div",{id:s,role:"listbox","aria-label":"Autocomplete suggestions",className:"hbs-autocomplete-portal",style:x,children:r}),document.body)}var ut=["this","@index","@first","@last","@key"],ft=["@root"];function dt(t,n){if(!n)return "prefix";let o=t.toLowerCase(),e=n.toLowerCase();return o===e?"exact":o.startsWith(e)?"prefix":o.includes(e)?"partial":"none"}function ht(t,n,o,e,r){let s=[],l=new Set,i=r.lastIndexOf("."),d=i!==-1;d?r.slice(0,i+1):"";let k=d?r.slice(i+1):r,x=(c,u)=>{if(l.has(c))return;let S=dt(c,k);S!=="none"&&(l.add(c),s.push({option:{value:c,type:u},matchType:S}));};if(d){let c=r.slice(0,i).replace(/\[\]$/,"");n.forEach(u=>{let S=u.path.replace(/\[\]/g,"");if(S.startsWith(`${c}.`)){let V=S.slice(c.length+1).split(".")[0];x(V,"variable");}});}else {if(!o){for(let u of J)x(`#${u}`,"block-open");for(let u of J)x(`/${u}`,"block-close");x("else","block-close");}for(let u of t)x(u,"helper");if(e){if(e.isEach)for(let u of ut)x(u,"data-var");for(let u of e.blockParams)x(u,"variable");for(let u of ft)x(u,"data-var");}let c=new Set;for(let u of n){let S=u.path.split(".")[0].replace("[]","");c.add(S);}for(let u of c)x(u,"variable");}let E={"data-var":0,variable:1,helper:2,"block-open":3,"block-close":4},P={exact:0,prefix:1,partial:2,none:3};return s.sort((c,u)=>{let S=P[c.matchType]-P[u.matchType];if(S!==0)return S;let N=E[c.option.type]-E[u.option.type];return N!==0?N:c.option.value.localeCompare(u.option.value)}),s.map(c=>c.option)}function mt(t,n){let o=t.slice(0,n),e=[],r=/\{\{#(each|with)\s+([^\s}]+)(?:\s+as\s*\|([^|]+)\|)?|\{\{\/(each|with)\}\}/g;for(let s of o.matchAll(r))if(s[1]){let l=s[1],i=s[2],O=(s[3]||"").split(/\s+/).filter(Boolean);e.push({type:l,variable:i,blockParams:O,isEach:l==="each"});}else if(s[4]){let l=s[4];for(let i=e.length-1;i>=0;i--)if(e[i].type===l){e.splice(i,1);break}}return e.length>0?e[e.length-1]:null}function bt(t,n){let o=t.slice(0,n),e=o.lastIndexOf("{{!--");if(e!==-1&&o.slice(e).indexOf("--}}")===-1)return true;let r=o.lastIndexOf("{{!");if(r!==-1){let s=o.slice(r);if(!s.startsWith("{{!--")&&s.indexOf("}}")===-1)return true}return false}function xt(t,n){let o=t.slice(0,n),e=t.slice(n),r=o.lastIndexOf("{{");if(r===-1||o.slice(r).includes("}}"))return false;let l=e.indexOf("}}");return l===-1?false:!e.slice(0,l).includes("{{")}function ye({value:t,onChange:n,placeholder:o="Enter template...",readOnly:e=false,className:r="",style:s,theme:l,customHelpers:i=[],autocomplete:d=true,minHeight:O=100}){let k=useRef(null),x=useRef(null),E=useRef(null),P=useId(),[c,u]=useState({isOpen:false,options:[],selectedIndex:0,triggerStart:0,filterText:"",isRaw:false,contextPath:null}),S=useMemo(()=>oe(t).variables.map(p=>({path:p.path,context:p.context})),[t]),N=useMemo(()=>M(t),[t]),V=useMemo(()=>t?N.map(a=>a.type==="text"?a.value:jsx("span",{className:`hbs-token-${a.type}`,children:a.value},a.start)):jsx("span",{className:"hbs-editor-placeholder",children:o}),[N,t,o]),g=useCallback(()=>{u(a=>({...a,isOpen:false}));},[]),K=useCallback((a,p)=>{if(!d||e){g();return}if(bt(a,p)||xt(a,p)){g();return}let m=a.slice(0,p).match(/(\{\{\{?)([#/]?[\w.@]*)$/);if(!m){g();return}let y=m[1],f=m[2]||"",C=p-f.length,b=y==="{{{";if(f.includes("}")){g();return}let T=mt(a,p),A=ht(i,S,b,T,f);if(A.length===0){g();return}u({isOpen:true,options:A,selectedIndex:0,triggerStart:C,filterText:f,isRaw:b,contextPath:T});},[d,e,i,S,g]),ee=useCallback(a=>{let p=a.target.value;n?.(p),K(p,a.target.selectionStart);},[n,K]),R=useCallback(a=>{let p=x.current;if(!p)return;let{triggerStart:h,filterText:m,isRaw:y}=c,f=y?"}}}":"}}",C=m.lastIndexOf("."),b=C!==-1?m.slice(0,C+1):"",T,A;if(a.type==="block-open"&&!y){let I=a.value.slice(1);T=`${a.value} }}{{/${I}}}`,A=a.value.length+1;}else a.type!=="block-close"&&a.value!=="else"?(T=`${b}${a.value}${f}`,A=T.length):(T=`${a.value}${f}`,A=T.length);p.focus(),p.setSelectionRange(h,p.selectionStart),document.execCommand("insertText",false,T);let B=h+A;p.setSelectionRange(B,B),n?.(p.value),g();},[c,n,g]),Q=useCallback(a=>{let{scrollTop:p,scrollLeft:h}=a.currentTarget;E.current&&(E.current.scrollTop=p,E.current.scrollLeft=h);},[]),te=useCallback(a=>{document.querySelector(".hbs-autocomplete-portal")?.contains(a.relatedTarget)||g();},[g]),w=useCallback(()=>{let a=x.current;if(!a||!c.isOpen)return;let p=a.selectionStart;t.slice(0,p).match(/(\{\{\{?)([#/]?[\w.@]*)$/)||g();},[c.isOpen,t,g]),U=useCallback(a=>{let p=a.currentTarget;if(a.key==="Tab"){if(c.isOpen){a.preventDefault();let C=c.options[c.selectedIndex];C&&R(C);return}a.preventDefault();let{selectionStart:f}=p;if(a.shiftKey){let b=t.slice(0,f).lastIndexOf(`
|
|
3
|
+
`)+1,A=t.slice(b,f).match(/^(\t| {2})/);if(A){let B=A[1].length,I=t.slice(0,b)+t.slice(b+B);n?.(I);let L=Math.max(b,f-B);setTimeout(()=>p.setSelectionRange(L,L),0);}}else document.execCommand("insertText",false," "),n?.(p.value);return}if((a.metaKey||a.ctrlKey)&&(a.key==="z"||a.key==="y")||!c.isOpen)return;let{options:h,selectedIndex:m}=c,y=8;switch(a.key){case "ArrowDown":a.preventDefault(),u(f=>({...f,selectedIndex:Math.min(m+1,h.length-1)}));break;case "ArrowUp":a.preventDefault(),u(f=>({...f,selectedIndex:Math.max(m-1,0)}));break;case "Home":a.preventDefault(),u(f=>({...f,selectedIndex:0}));break;case "End":a.preventDefault(),u(f=>({...f,selectedIndex:h.length-1}));break;case "PageDown":a.preventDefault(),u(f=>({...f,selectedIndex:Math.min(m+y,h.length-1)}));break;case "PageUp":a.preventDefault(),u(f=>({...f,selectedIndex:Math.max(m-y,0)}));break;case "Enter":a.preventDefault(),h[m]&&R(h[m]);break;case "Escape":a.preventDefault(),g();break;case "ArrowLeft":case "ArrowRight":setTimeout(()=>w(),0);break}},[c,R,g,w,t,n]),W=useMemo(()=>{if(!l)return {};let a={},p={variable:"--hbs-color-variable",variablePath:"--hbs-color-variable-path",blockKeyword:"--hbs-color-block-keyword",blockParam:"--hbs-color-block-param",helper:"--hbs-color-helper",helperArg:"--hbs-color-helper-arg",hashKey:"--hbs-color-hash-key",hashValue:"--hbs-color-hash-value",literal:"--hbs-color-literal",dataVar:"--hbs-color-data-var",subexprParen:"--hbs-color-subexpr-paren",comment:"--hbs-color-comment",raw:"--hbs-color-raw",brace:"--hbs-color-brace",text:"--hbs-color-text",background:"--hbs-color-background",caret:"--hbs-color-caret",border:"--hbs-color-border",placeholder:"--hbs-color-placeholder"};for(let[h,m]of Object.entries(p)){let y=l[h];y&&(a[m]=y);}return a},[l]);useEffect(()=>{if(!c.isOpen)return;let a=document.querySelector(".hbs-autocomplete-portal");if(!a)return;let h=a.querySelectorAll(".hbs-autocomplete-item")[c.selectedIndex];h&&h.scrollIntoView({block:"nearest"});},[c.selectedIndex,c.isOpen]),useEffect(()=>{if(!c.isOpen)return;let a=k.current,p=m=>{let y=m.target;document.querySelector(".hbs-autocomplete-portal")?.contains(y)||a&&!a.contains(y)&&g();},h=m=>{let y=m.target;document.querySelector(".hbs-autocomplete-portal")?.contains(y)||a?.contains(y)&&y!==x.current&&g();};return document.addEventListener("mousedown",p),a?.addEventListener("mousedown",h),()=>{document.removeEventListener("mousedown",p),a?.removeEventListener("mousedown",h);}},[c.isOpen,g]);let z=useCallback((a,p)=>{let{filterText:h,selectedIndex:m}=c,y=p===m,f=h.lastIndexOf("."),C=f!==-1?h.slice(f+1):h,b=a.value;(a.type==="block-open"&&b.startsWith("#")||a.type==="block-close"&&b.startsWith("/")||a.type==="data-var"&&b.startsWith("@"))&&(b=b.slice(1));let T,A=C.toLowerCase().replace(/^[#/@]/,""),I=b.toLowerCase().indexOf(A);if(A.length>0&&I!==-1){let $=b.slice(0,I),Se=b.slice(I,I+A.length),Ae=b.slice(I+A.length);T=jsxs(Fragment,{children:[$,jsx("span",{className:"hbs-autocomplete-match",children:Se}),Ae]});}else T=b;let L="";switch(a.type){case "block-open":L="#";break;case "block-close":L="/";break;case "data-var":L="@";break;case "helper":L="\u0192";break;case "variable":L="\xB7";break}let Oe=jsx("span",{className:"hbs-autocomplete-type",children:L});return jsxs("button",{id:`${P}-option-${p}`,type:"button",role:"option","aria-selected":y,className:`hbs-autocomplete-item hbs-autocomplete-${a.type} ${y?"hbs-selected":""}`,onMouseDown:$=>{$.preventDefault(),R(a);},onMouseEnter:()=>u($=>({...$,selectedIndex:p})),children:[Oe,jsx("span",{className:"hbs-autocomplete-value",children:T})]},a.value)},[c,R,P]),G=["hbs-editor",e?"hbs-readonly":"",r].filter(Boolean).join(" ");return jsxs("div",{ref:k,className:G,style:{...W,minHeight:typeof O=="number"?`${O}px`:O,...s},children:[jsx("div",{ref:E,className:"hbs-editor-highlight",children:V}),jsx("textarea",{ref:x,className:"hbs-editor-textarea",value:t,onChange:ee,onKeyDown:U,onScroll:Q,onBlur:te,onSelect:w,placeholder:"",readOnly:e,spellCheck:false,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",role:"combobox","aria-haspopup":"listbox","aria-expanded":d&&c.isOpen,"aria-controls":P,"aria-activedescendant":d&&c.isOpen&&c.options[c.selectedIndex]?`${P}-option-${c.selectedIndex}`:void 0}),d&&jsx(Ee,{textareaRef:x,containerRef:k,triggerPosition:c.triggerStart,isOpen:c.isOpen,listboxId:P,children:c.options.map((a,p)=>z(a,p))})]})}function gt({content:t,className:n}){if(!t)return null;let o=M(t);return jsx("span",{className:n,children:o.map(e=>jsx("span",{className:`hbs-token-${e.type}`,children:e.value},e.start))})}export{ye as HandlebarsEditor,gt as HandlebarsHighlight,ye as default,oe as extract,nt as interpolate,M as tokenize};
|
package/dist/styles.css
CHANGED
|
@@ -1,52 +1,43 @@
|
|
|
1
1
|
/* Handlebars Editor - Default Theme */
|
|
2
2
|
|
|
3
3
|
.hbs-editor {
|
|
4
|
-
/*
|
|
5
|
-
--hbs-color-text: #
|
|
4
|
+
/* Base colors */
|
|
5
|
+
--hbs-color-text: #24292f;
|
|
6
6
|
--hbs-color-background: #ffffff;
|
|
7
|
-
--hbs-color-border: #
|
|
8
|
-
--hbs-color-caret: #
|
|
9
|
-
--hbs-color-placeholder: #
|
|
10
|
-
--hbs-color-focus-ring: #
|
|
11
|
-
|
|
12
|
-
/* Syntax highlighting
|
|
13
|
-
--hbs-color-variable: #
|
|
14
|
-
--hbs-color-variable-path: #
|
|
15
|
-
--hbs-color-block-keyword: #
|
|
16
|
-
--hbs-color-block-param: #
|
|
17
|
-
--hbs-color-helper: #
|
|
18
|
-
--hbs-color-helper-arg: #
|
|
19
|
-
--hbs-color-hash-key: #
|
|
20
|
-
--hbs-color-hash-value: #
|
|
21
|
-
--hbs-color-literal: #
|
|
22
|
-
--hbs-color-data-var: #
|
|
7
|
+
--hbs-color-border: #d1d5db;
|
|
8
|
+
--hbs-color-caret: #24292f;
|
|
9
|
+
--hbs-color-placeholder: #6b7280;
|
|
10
|
+
--hbs-color-focus-ring: #2563eb;
|
|
11
|
+
|
|
12
|
+
/* Syntax highlighting - balanced, readable palette */
|
|
13
|
+
--hbs-color-variable: #0550ae;
|
|
14
|
+
--hbs-color-variable-path: #0550ae;
|
|
15
|
+
--hbs-color-block-keyword: #8250df;
|
|
16
|
+
--hbs-color-block-param: #0550ae;
|
|
17
|
+
--hbs-color-helper: #953800;
|
|
18
|
+
--hbs-color-helper-arg: #0550ae;
|
|
19
|
+
--hbs-color-hash-key: #0550ae;
|
|
20
|
+
--hbs-color-hash-value: #0a3069;
|
|
21
|
+
--hbs-color-literal: #0a3069;
|
|
22
|
+
--hbs-color-data-var: #cf222e;
|
|
23
23
|
--hbs-color-subexpr-paren: #6b7280;
|
|
24
|
-
--hbs-color-comment: #
|
|
25
|
-
--hbs-color-raw: #
|
|
26
|
-
--hbs-color-brace: #
|
|
27
|
-
--hbs-color-error: #
|
|
28
|
-
--hbs-color-error-bg: rgba(
|
|
24
|
+
--hbs-color-comment: #6b7280;
|
|
25
|
+
--hbs-color-raw: #953800;
|
|
26
|
+
--hbs-color-brace: #9ca3af;
|
|
27
|
+
--hbs-color-error: #cf222e;
|
|
28
|
+
--hbs-color-error-bg: rgba(207, 34, 46, 0.1);
|
|
29
29
|
|
|
30
|
-
/* Autocomplete
|
|
30
|
+
/* Autocomplete */
|
|
31
31
|
--hbs-color-autocomplete-bg: #ffffff;
|
|
32
|
-
--hbs-color-autocomplete-border: #e5e7eb;
|
|
33
32
|
--hbs-color-autocomplete-selected: #f3f4f6;
|
|
34
|
-
--hbs-color-autocomplete-hover: #f9fafb;
|
|
35
|
-
|
|
36
|
-
/* Autocomplete dimensions */
|
|
37
|
-
--hbs-autocomplete-min-width: 180px;
|
|
38
|
-
--hbs-autocomplete-max-height: 192px;
|
|
39
33
|
|
|
40
|
-
/*
|
|
41
|
-
--hbs-
|
|
42
|
-
--hbs-
|
|
43
|
-
|
|
44
|
-
/* Spacing */
|
|
34
|
+
/* Dimensions */
|
|
35
|
+
--hbs-autocomplete-min-width: 160px;
|
|
36
|
+
--hbs-autocomplete-max-height: 200px;
|
|
45
37
|
--hbs-padding: 12px;
|
|
46
38
|
--hbs-font-size: 14px;
|
|
47
|
-
--hbs-line-height: 1.
|
|
48
|
-
--hbs-font-family:
|
|
49
|
-
ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
|
39
|
+
--hbs-line-height: 1.6;
|
|
40
|
+
--hbs-font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
|
50
41
|
--hbs-border-radius: 6px;
|
|
51
42
|
--hbs-tab-size: 2;
|
|
52
43
|
|
|
@@ -63,20 +54,34 @@
|
|
|
63
54
|
|
|
64
55
|
/* Dark theme */
|
|
65
56
|
.hbs-editor.hbs-theme-dark {
|
|
66
|
-
--hbs-color-text: #
|
|
67
|
-
--hbs-color-background: #
|
|
68
|
-
--hbs-color-border: #
|
|
69
|
-
--hbs-color-caret: #
|
|
70
|
-
--hbs-color-placeholder: #
|
|
71
|
-
--hbs-color-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
--hbs-color-
|
|
75
|
-
--hbs-color-
|
|
76
|
-
|
|
57
|
+
--hbs-color-text: #e6edf3;
|
|
58
|
+
--hbs-color-background: #0d1117;
|
|
59
|
+
--hbs-color-border: #30363d;
|
|
60
|
+
--hbs-color-caret: #e6edf3;
|
|
61
|
+
--hbs-color-placeholder: #6e7681;
|
|
62
|
+
--hbs-color-focus-ring: #58a6ff;
|
|
63
|
+
|
|
64
|
+
/* Syntax - GitHub dark inspired */
|
|
65
|
+
--hbs-color-variable: #79c0ff;
|
|
66
|
+
--hbs-color-variable-path: #79c0ff;
|
|
67
|
+
--hbs-color-block-keyword: #d2a8ff;
|
|
68
|
+
--hbs-color-block-param: #79c0ff;
|
|
69
|
+
--hbs-color-helper: #ffa657;
|
|
70
|
+
--hbs-color-helper-arg: #79c0ff;
|
|
71
|
+
--hbs-color-hash-key: #79c0ff;
|
|
72
|
+
--hbs-color-hash-value: #a5d6ff;
|
|
73
|
+
--hbs-color-literal: #a5d6ff;
|
|
74
|
+
--hbs-color-data-var: #ff7b72;
|
|
75
|
+
--hbs-color-subexpr-paren: #6e7681;
|
|
76
|
+
--hbs-color-comment: #6e7681;
|
|
77
|
+
--hbs-color-raw: #ffa657;
|
|
78
|
+
--hbs-color-brace: #6e7681;
|
|
79
|
+
--hbs-color-error: #f85149;
|
|
80
|
+
--hbs-color-error-bg: rgba(248, 81, 73, 0.15);
|
|
77
81
|
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
/* Autocomplete */
|
|
83
|
+
--hbs-color-autocomplete-bg: #161b22;
|
|
84
|
+
--hbs-color-autocomplete-selected: #30363d;
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
/* Highlight layer */
|
|
@@ -95,7 +100,6 @@
|
|
|
95
100
|
color: var(--hbs-color-text);
|
|
96
101
|
tab-size: var(--hbs-tab-size);
|
|
97
102
|
-moz-tab-size: var(--hbs-tab-size);
|
|
98
|
-
/* Hide scrollbars - scrolling is synced from textarea */
|
|
99
103
|
scrollbar-width: none;
|
|
100
104
|
-ms-overflow-style: none;
|
|
101
105
|
}
|
|
@@ -109,7 +113,7 @@
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
.hbs-editor.hbs-readonly .hbs-editor-highlight {
|
|
112
|
-
background: rgba(0, 0, 0, 0.
|
|
116
|
+
background: rgba(0, 0, 0, 0.02);
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
/* Textarea layer */
|
|
@@ -132,16 +136,45 @@
|
|
|
132
136
|
outline: none;
|
|
133
137
|
tab-size: var(--hbs-tab-size);
|
|
134
138
|
-moz-tab-size: var(--hbs-tab-size);
|
|
139
|
+
scrollbar-width: thin;
|
|
140
|
+
scrollbar-color: var(--hbs-color-border) transparent;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.hbs-editor-textarea::-webkit-scrollbar {
|
|
144
|
+
width: 10px;
|
|
145
|
+
height: 10px;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.hbs-editor-textarea::-webkit-scrollbar-track {
|
|
149
|
+
background: transparent;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.hbs-editor-textarea::-webkit-scrollbar-thumb {
|
|
153
|
+
background: var(--hbs-color-border);
|
|
154
|
+
border: 2px solid var(--hbs-color-background);
|
|
155
|
+
border-radius: 5px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.hbs-editor-textarea::-webkit-scrollbar-thumb:hover {
|
|
159
|
+
background: var(--hbs-color-placeholder);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.hbs-editor-textarea::-webkit-scrollbar-corner {
|
|
163
|
+
background: transparent;
|
|
135
164
|
}
|
|
136
165
|
|
|
137
166
|
.hbs-editor-textarea:focus {
|
|
138
167
|
border-color: var(--hbs-color-focus-ring);
|
|
139
|
-
box-shadow: 0 0 0
|
|
168
|
+
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.hbs-editor.hbs-theme-dark .hbs-editor-textarea:focus {
|
|
172
|
+
box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.15);
|
|
140
173
|
}
|
|
141
174
|
|
|
142
175
|
.hbs-editor.hbs-readonly .hbs-editor-textarea {
|
|
143
176
|
cursor: default;
|
|
144
|
-
background: rgba(0, 0, 0, 0.
|
|
177
|
+
background: rgba(0, 0, 0, 0.02);
|
|
145
178
|
}
|
|
146
179
|
|
|
147
180
|
/* Placeholder */
|
|
@@ -153,91 +186,134 @@
|
|
|
153
186
|
.hbs-token-variable {
|
|
154
187
|
color: var(--hbs-color-variable);
|
|
155
188
|
}
|
|
189
|
+
|
|
156
190
|
.hbs-token-variable-path {
|
|
157
191
|
color: var(--hbs-color-variable-path);
|
|
158
192
|
}
|
|
193
|
+
|
|
159
194
|
.hbs-token-block-keyword {
|
|
160
195
|
color: var(--hbs-color-block-keyword);
|
|
161
|
-
font-weight:
|
|
196
|
+
font-weight: 600;
|
|
162
197
|
}
|
|
198
|
+
|
|
163
199
|
.hbs-token-block-param {
|
|
164
200
|
color: var(--hbs-color-block-param);
|
|
165
201
|
}
|
|
202
|
+
|
|
166
203
|
.hbs-token-helper {
|
|
167
204
|
color: var(--hbs-color-helper);
|
|
168
|
-
font-weight: 500;
|
|
169
205
|
}
|
|
206
|
+
|
|
170
207
|
.hbs-token-helper-arg {
|
|
171
208
|
color: var(--hbs-color-helper-arg);
|
|
172
209
|
}
|
|
210
|
+
|
|
173
211
|
.hbs-token-hash-key {
|
|
174
212
|
color: var(--hbs-color-hash-key);
|
|
175
213
|
}
|
|
214
|
+
|
|
176
215
|
.hbs-token-hash-value {
|
|
177
216
|
color: var(--hbs-color-hash-value);
|
|
178
217
|
}
|
|
218
|
+
|
|
179
219
|
.hbs-token-literal {
|
|
180
220
|
color: var(--hbs-color-literal);
|
|
181
221
|
}
|
|
222
|
+
|
|
182
223
|
.hbs-token-data-var {
|
|
183
224
|
color: var(--hbs-color-data-var);
|
|
184
225
|
}
|
|
226
|
+
|
|
185
227
|
.hbs-token-subexpr-paren {
|
|
186
228
|
color: var(--hbs-color-subexpr-paren);
|
|
187
|
-
font-weight: 500;
|
|
188
229
|
}
|
|
230
|
+
|
|
189
231
|
.hbs-token-comment {
|
|
190
232
|
color: var(--hbs-color-comment);
|
|
191
233
|
font-style: italic;
|
|
192
234
|
}
|
|
235
|
+
|
|
193
236
|
.hbs-token-raw {
|
|
194
237
|
color: var(--hbs-color-raw);
|
|
195
238
|
}
|
|
239
|
+
|
|
196
240
|
.hbs-token-brace {
|
|
197
241
|
color: var(--hbs-color-brace);
|
|
198
242
|
}
|
|
243
|
+
|
|
199
244
|
.hbs-token-error {
|
|
200
245
|
color: var(--hbs-color-error);
|
|
201
246
|
background: var(--hbs-color-error-bg);
|
|
202
247
|
text-decoration: wavy underline var(--hbs-color-error);
|
|
203
248
|
}
|
|
204
249
|
|
|
205
|
-
/* Autocomplete dropdown */
|
|
206
|
-
.hbs-autocomplete {
|
|
207
|
-
position:
|
|
208
|
-
z-index:
|
|
209
|
-
min-width:
|
|
250
|
+
/* Autocomplete dropdown (portal-based, rendered to document.body) */
|
|
251
|
+
.hbs-autocomplete-portal {
|
|
252
|
+
position: fixed;
|
|
253
|
+
z-index: 9999;
|
|
254
|
+
min-width: 160px;
|
|
255
|
+
max-width: 240px;
|
|
210
256
|
overflow: auto;
|
|
211
|
-
border-radius:
|
|
212
|
-
border: 1px solid var(--hbs-color-autocomplete-border);
|
|
213
|
-
background: var(--hbs-color-autocomplete-bg);
|
|
257
|
+
border-radius: 8px;
|
|
214
258
|
padding: 4px;
|
|
215
|
-
box-shadow:
|
|
216
|
-
|
|
217
|
-
|
|
259
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
260
|
+
|
|
261
|
+
/* Default theme values (can be overridden via inline styles) */
|
|
262
|
+
--hbs-color-text: #24292f;
|
|
263
|
+
--hbs-color-border: #d1d5db;
|
|
264
|
+
--hbs-color-placeholder: #6b7280;
|
|
265
|
+
--hbs-color-focus-ring: #2563eb;
|
|
266
|
+
--hbs-color-autocomplete-bg: #ffffff;
|
|
267
|
+
--hbs-color-autocomplete-selected: #f3f4f6;
|
|
268
|
+
--hbs-font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
|
269
|
+
|
|
270
|
+
border: 1px solid var(--hbs-color-border);
|
|
271
|
+
background: var(--hbs-color-autocomplete-bg);
|
|
272
|
+
font-family: var(--hbs-font-family);
|
|
273
|
+
color: var(--hbs-color-text);
|
|
218
274
|
}
|
|
219
275
|
|
|
220
276
|
.hbs-autocomplete-item {
|
|
221
|
-
display:
|
|
277
|
+
display: flex;
|
|
278
|
+
align-items: center;
|
|
279
|
+
gap: 6px;
|
|
222
280
|
width: 100%;
|
|
223
281
|
text-align: left;
|
|
224
282
|
cursor: pointer;
|
|
225
283
|
border-radius: 4px;
|
|
226
|
-
padding:
|
|
284
|
+
padding: 5px 8px;
|
|
227
285
|
font-family: var(--hbs-font-family);
|
|
228
|
-
font-size:
|
|
286
|
+
font-size: 13px;
|
|
229
287
|
background: transparent;
|
|
230
288
|
border: none;
|
|
289
|
+
color: var(--hbs-color-text);
|
|
231
290
|
}
|
|
232
291
|
|
|
233
|
-
.hbs-autocomplete-item:hover
|
|
234
|
-
background: var(--hbs-color-autocomplete-hover);
|
|
235
|
-
}
|
|
236
|
-
|
|
292
|
+
.hbs-autocomplete-item:hover,
|
|
237
293
|
.hbs-autocomplete-item.hbs-selected {
|
|
238
294
|
background: var(--hbs-color-autocomplete-selected);
|
|
239
295
|
}
|
|
240
296
|
|
|
297
|
+
.hbs-autocomplete-value {
|
|
298
|
+
flex: 1;
|
|
299
|
+
overflow: hidden;
|
|
300
|
+
text-overflow: ellipsis;
|
|
301
|
+
white-space: nowrap;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.hbs-autocomplete-match {
|
|
305
|
+
color: var(--hbs-color-focus-ring);
|
|
306
|
+
font-weight: 600;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* Type indicator */
|
|
310
|
+
.hbs-autocomplete-type {
|
|
311
|
+
flex-shrink: 0;
|
|
312
|
+
font-size: 11px;
|
|
313
|
+
color: var(--hbs-color-placeholder);
|
|
314
|
+
opacity: 0.8;
|
|
315
|
+
}
|
|
316
|
+
|
|
241
317
|
/* Error bar */
|
|
242
318
|
.hbs-error-bar {
|
|
243
319
|
position: absolute;
|
|
@@ -248,10 +324,10 @@
|
|
|
248
324
|
align-items: center;
|
|
249
325
|
gap: 8px;
|
|
250
326
|
border-radius: var(--hbs-border-radius);
|
|
251
|
-
border: 1px solid
|
|
252
|
-
background: var(--hbs-color-error-
|
|
327
|
+
border: 1px solid rgba(207, 34, 46, 0.4);
|
|
328
|
+
background: var(--hbs-color-error-bg);
|
|
253
329
|
padding: 8px 12px;
|
|
254
|
-
font-size:
|
|
330
|
+
font-size: 13px;
|
|
255
331
|
color: var(--hbs-color-error);
|
|
256
332
|
}
|
|
257
333
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "handlebars-editor-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A React component for editing Handlebars templates with syntax highlighting and autocomplete",
|
|
5
5
|
"author": "Dogukan Incesu",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,6 +24,20 @@
|
|
|
24
24
|
"sideEffects": [
|
|
25
25
|
"*.css"
|
|
26
26
|
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"dev": "tsup --watch",
|
|
30
|
+
"test": "vitest",
|
|
31
|
+
"test:run": "vitest run",
|
|
32
|
+
"check-types": "tsc --noEmit",
|
|
33
|
+
"lint": "biome lint src/ tests/",
|
|
34
|
+
"format": "biome format --write src/ tests/",
|
|
35
|
+
"check": "biome check src/ tests/",
|
|
36
|
+
"prepublishOnly": "pnpm run build",
|
|
37
|
+
"example": "pnpm --dir example dev",
|
|
38
|
+
"example:dist": "pnpm --dir example dev:dist",
|
|
39
|
+
"example:build": "pnpm --dir example build"
|
|
40
|
+
},
|
|
27
41
|
"peerDependencies": {
|
|
28
42
|
"react": ">=18.0.0",
|
|
29
43
|
"react-dom": ">=18.0.0"
|
|
@@ -59,18 +73,5 @@
|
|
|
59
73
|
"bugs": {
|
|
60
74
|
"url": "https://github.com/dogukani/handlebars-editor/issues"
|
|
61
75
|
},
|
|
62
|
-
"homepage": "https://dogukani.github.io/handlebars-editor"
|
|
63
|
-
|
|
64
|
-
"build": "tsup",
|
|
65
|
-
"dev": "tsup --watch",
|
|
66
|
-
"test": "vitest",
|
|
67
|
-
"test:run": "vitest run",
|
|
68
|
-
"check-types": "tsc --noEmit",
|
|
69
|
-
"lint": "biome lint src/ tests/",
|
|
70
|
-
"format": "biome format --write src/ tests/",
|
|
71
|
-
"check": "biome check src/ tests/",
|
|
72
|
-
"example": "pnpm --dir example dev",
|
|
73
|
-
"example:dist": "pnpm --dir example dev:dist",
|
|
74
|
-
"example:build": "pnpm --dir example build"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
76
|
+
"homepage": "https://dogukani.github.io/handlebars-editor"
|
|
77
|
+
}
|