qlik-script-editor
Version:
A React component library for Qlik Sense script editing with syntax highlighting, autocomplete, and theme support
7 lines (6 loc) • 8.1 kB
JavaScript
;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react/jsx-runtime"),o=require("react"),W=t=>t&&t.__esModule?t:{default:t},q=W(o);function O(t){var n,e,s="";if(typeof t=="string"||typeof t=="number")s+=t;else if(typeof t=="object")if(Array.isArray(t)){var c=t.length;for(n=0;n<c;n++)t[n]&&(e=O(t[n]))&&(s&&(s+=" "),s+=e)}else for(e in t)t[e]&&(s&&(s+=" "),s+=e);return s}function U(){for(var t,n,e=0,s="",c=arguments.length;e<c;e++)(t=arguments[e])&&(n=O(t))&&(s&&(s+=" "),s+=n);return s}function M(...t){return U(t)}function B(t,n){let e=null;return function(...c){const r=()=>{e=null,t(...c)};e&&clearTimeout(e),e=setTimeout(r,n)}}function $(t){const n=Math.random().toString(36).substr(2,9);return t?`${t}-${n}`:n}function H(t){return t!=null}function Q(t,n){const e={...t};return n.forEach(s=>delete e[s]),e}function V(t,n){const e={};return n.forEach(s=>{s in t&&(e[s]=t[s])}),e}const Y=({initialScript:t="",onChange:n,variables:e=[],theme:s="light",height:c="400px",width:r="100%",readOnly:d=!1,className:p,placeholder:E="Enter your Qlik script here..."})=>{const a=o.useRef(null),[h,T]=o.useState(t),[y,i]=o.useState([]),[v,m]=o.useState(!1),[k,C]=o.useState(0),x=["LOAD","FROM","SELECT","WHERE","GROUP BY","ORDER BY","LEFT JOIN","RIGHT JOIN","INNER JOIN","OUTER JOIN","CONCATENATE","MAPPING","QUALIFY","UNQUALIFY","DROP","STORE","LET","SET","CALL","SUB","END SUB","FOR","NEXT","DO","LOOP","WHILE","WEND","IF","THEN","ELSE","ELSEIF","END IF","SWITCH","CASE","DEFAULT","END SWITCH","EXIT SCRIPT","TRACE"],L=["Sum","Count","Avg","Min","Max","Date","Today","Now","Year","Month","Day","Hour","Minute","Second","If","Alt","Match","ApplyMap","Lookup","Peek","Previous","Exists","FieldValue","FieldIndex","NoOfRows","RowNo","RecNo","Len","Left","Right","Mid","Trim","Upper","Lower","Replace","SubField","PurgeChar","KeepChar","Chr","Ord"],b=o.useCallback(l=>{T(l),n?.(l)},[n]),_=l=>{const f=l.target.value,N=l.target.selectionStart||0;b(f),C(N);const g=I(f,N);if(g.length>0){const w=[...x.filter(S=>S.toLowerCase().startsWith(g.toLowerCase())),...L.filter(S=>S.toLowerCase().startsWith(g.toLowerCase())),...e.filter(S=>S.toLowerCase().startsWith(g.toLowerCase()))].slice(0,10);i(w),m(w.length>0)}else m(!1)},I=(l,f)=>{const N=l.slice(0,f),g=l.slice(f),w=N.search(/\w+$/),S=g.search(/\W/);if(w===-1)return"";const P=w,F=f+(S===-1?g.length:S);return l.slice(P,F)},D=l=>{if(!a.current)return;const f=a.current,N=I(h,k),g=h.slice(0,k).lastIndexOf(N);if(g!==-1){const w=h.slice(0,g)+l+h.slice(g+N.length);b(w),m(!1),setTimeout(()=>{f.focus();const S=g+l.length;f.setSelectionRange(S,S)},0)}},A=l=>{if(l.key==="Tab"){l.preventDefault();const f=l.currentTarget,N=f.selectionStart,g=f.selectionEnd,w=f.value,S=w.substring(0,N)+" "+w.substring(g);b(S),setTimeout(()=>{f.selectionStart=f.selectionEnd=N+2},0)}l.key==="Escape"&&m(!1)};return o.useEffect(()=>{t!==h&&T(t)},[t,h]),u.jsx("div",{className:M("qlik-script-editor",p),style:{width:r},children:u.jsxs("div",{className:M("qlik-script-editor__container",`qlik-script-editor--${s}`,{"qlik-script-editor--readonly":d}),style:{height:c},children:[u.jsx("textarea",{ref:a,value:h,onChange:_,onKeyDown:A,placeholder:E,readOnly:d,className:"qlik-script-editor__textarea",spellCheck:!1}),v&&y.length>0&&u.jsx("div",{className:"qlik-script-editor__suggestions",children:y.map(l=>u.jsx("button",{className:"qlik-script-editor__suggestion",onClick:()=>D(l),type:"button",children:l},l))})]})})},R=o.createContext(void 0),J=({defaultTheme:t="system",storageKey:n="qlik-script-editor-theme",children:e})=>{const[s,c]=o.useState(t),[r,d]=o.useState("light");o.useEffect(()=>{const a=localStorage.getItem(n);a&&c(a)},[n]),o.useEffect(()=>{if(s==="system"){const a=window.matchMedia("(prefers-color-scheme: dark)");d(a.matches?"dark":"light");const h=T=>{d(T.matches?"dark":"light")};return a.addEventListener("change",h),()=>a.removeEventListener("change",h)}else d(s)},[s]);const E={theme:s,actualTheme:r,setTheme:a=>{c(a),localStorage.setItem(n,a)}};return u.jsx(R.Provider,{value:E,children:u.jsx("div",{className:`qlik-script-editor-theme qlik-script-editor-theme--${r}`,children:e})})},G=()=>{const t=o.useContext(R);if(!t)throw new Error("useTheme must be used within a ThemeProvider");return t},j=q.default.forwardRef(({variant:t="primary",size:n="md",loading:e=!1,leftIcon:s,rightIcon:c,fullWidth:r=!1,className:d,disabled:p,children:E,...a},h)=>{const T=p||e;return u.jsxs("button",{ref:h,className:M("rc-button",`rc-button--${t}`,`rc-button--${n}`,{"rc-button--loading":e,"rc-button--full-width":r},d),disabled:T,...a,children:[e&&u.jsx("span",{className:"rc-button__spinner","aria-hidden":"true",children:u.jsxs("svg",{className:"rc-button__spinner-icon",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[u.jsx("circle",{className:"rc-button__spinner-circle",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),u.jsx("path",{className:"rc-button__spinner-path",fill:"currentColor",d:"m12 2a10 10 0 0 1 10 10h-4a6 6 0 0 0-6-6V2z"})]})}),s&&!e&&u.jsx("span",{className:"rc-button__icon rc-button__icon--left","aria-hidden":"true",children:s}),E&&u.jsx("span",{className:"rc-button__content",children:E}),c&&!e&&u.jsx("span",{className:"rc-button__icon rc-button__icon--right","aria-hidden":"true",children:c})]})});j.displayName="Button";const z=({children:t,title:n,padding:e="md",shadow:s=!0,className:c=""})=>{const r="bg-white rounded-lg border border-gray-200",d={sm:"p-4",md:"p-6",lg:"p-8"},p=s?"shadow-sm hover:shadow-md transition-shadow":"",E=[r,d[e],p,c].filter(Boolean).join(" ");return u.jsxs("div",{className:E,children:[n&&u.jsx("div",{className:"mb-4",children:u.jsx("h3",{className:"text-lg font-medium text-gray-900",children:n})}),t]})};function K(t={}){const{initialValue:n=0,min:e=-1/0,max:s=1/0,step:c=1}=t,[r,d]=o.useState(n),p=o.useCallback(()=>{d(i=>Math.min(i+c,s))},[c,s]),E=o.useCallback(()=>{d(i=>Math.max(i-c,e))},[c,e]),a=o.useCallback(()=>{d(n)},[n]),h=o.useCallback(i=>{d(Math.max(e,Math.min(s,i)))},[e,s]),T=r<=e,y=r>=s;return{count:r,increment:p,decrement:E,reset:a,set:h,isAtMin:T,isAtMax:y}}function X(t={}){const{initialScript:n="",onChange:e,variables:s=[],enableValidation:c=!0}=t,[r,d]=o.useState(n),p=o.useCallback(i=>{d(i),e?.(i)},[e]),E=o.useCallback(()=>{p("")},[p]),a=o.useMemo(()=>{if(!c||!r.trim())return[];const i=[];return r.split(`
`).forEach((m,k)=>{const C=m.trim();if(!C)return;C.match(/^(LOAD|SELECT|LET|SET|STORE|DROP)\s+/i)&&!C.endsWith(";")&&!C.endsWith(":")&&!C.includes("FROM")&&i.push({line:k+1,column:m.length,message:"Missing semicolon",type:"warning"});const x=(m.match(/\(/g)||[]).length,L=(m.match(/\)/g)||[]).length;x!==L&&i.push({line:k+1,column:m.indexOf("(")+1,message:"Unmatched parentheses",type:"syntax"});const b=m.match(/\$\([^)]+\)/g);b&&b.forEach(_=>{const I=_.slice(2,-1);s.includes(I)||i.push({line:k+1,column:m.indexOf(_)+1,message:`Undefined variable: ${I}`,type:"warning"})})}),i},[r,s,c]),h=o.useMemo(()=>a.some(i=>i.type==="syntax"),[a]),T=o.useCallback(()=>{const i=r.split(`
`);let v=0;const m=2,k=i.map(C=>{const x=C.trim();if(!x)return"";x.match(/^(END\s+(IF|SUB|SWITCH))/i)&&(v=Math.max(0,v-1));const L=" ".repeat(v*m)+x;return(x.match(/^(IF\s+|FOR\s+|DO\s*$|WHILE\s+|SUB\s+|SWITCH\s+)/i)||x.match(/^(THEN\s*$|ELSE\s*$)/i))&&v++,L});p(k.join(`
`))},[r,p]),y=o.useCallback(()=>{const i=r.split(`
`).filter(b=>b.trim()).length,v=r.length,m=r.split(/\s+/).filter(b=>b).length,C=(r.match(/^(LOAD|SELECT)\s+/gmi)||[]).length,L=(r.match(/^(LET|SET)\s+([^=\s]+)/gmi)||[]).map(b=>b.split(/\s+/)[1]||"").filter(Boolean);return{lines:i,characters:v,words:m,tables:C,variables:L}},[r]);return{script:r,setScript:p,clearScript:E,errors:a,hasErrors:h,formatScript:T,getScriptStats:y}}exports.Button=j;exports.Card=z;exports.QlikScriptEditor=Y;exports.ThemeContext=R;exports.ThemeProvider=J;exports.cn=M;exports.debounce=B;exports.generateId=$;exports.isNotNullish=H;exports.omit=Q;exports.pick=V;exports.useCounter=K;exports.useQlikScript=X;exports.useTheme=G;
//# sourceMappingURL=index.cjs.map