@tslite/react 0.1.0 → 0.2.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/full.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Extension } from '@codemirror/state';
2
- import { U as UseExpressionFieldOptions } from './useExpressionField-CA__y0bO.cjs';
2
+ import { U as UseExpressionFieldOptions } from './useExpressionField-CmiOEqIK.cjs';
3
3
  export { searchEditing } from '@tslite/codemirror/search';
4
4
  export { format, formatExpression } from '@tslite/format';
5
5
  export { tsliteTokenStyles } from '@tslite/editor';
@@ -35,8 +35,13 @@ interface PresetOptions {
35
35
  * faz o `parseExpression` lançar, e o serviço então declara que não sabe
36
36
  * formatar — em silêncio. Foi um defeito real, e é por isso que o preset
37
37
  * escolhe por você.
38
+ *
39
+ * **`"template"`** liga o controle de fluxo (`{% if %}` / `{% for %}` /
40
+ * `{# #}`). Ele não é o padrão porque um `{%` literal no texto deixaria de ser
41
+ * texto — e num campo que hoje aceita qualquer string isso seria mudança de
42
+ * comportamento sem pedido. Quem quer, declara.
38
43
  */
39
- readonly mode?: "expression" | "program";
44
+ readonly mode?: "expression" | "program" | "template";
40
45
  /** Régua de linhas. Padrão: ligada no `"block"`, desligada no `"inline"`. */
41
46
  readonly gutters?: boolean;
42
47
  /** Busca e `Ctrl+D`. Padrão: ligadas no `"block"`, desligadas no `"inline"`. */
package/dist/full.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Extension } from '@codemirror/state';
2
- import { U as UseExpressionFieldOptions } from './useExpressionField-CA__y0bO.js';
2
+ import { U as UseExpressionFieldOptions } from './useExpressionField-CmiOEqIK.js';
3
3
  export { searchEditing } from '@tslite/codemirror/search';
4
4
  export { format, formatExpression } from '@tslite/format';
5
5
  export { tsliteTokenStyles } from '@tslite/editor';
@@ -35,8 +35,13 @@ interface PresetOptions {
35
35
  * faz o `parseExpression` lançar, e o serviço então declara que não sabe
36
36
  * formatar — em silêncio. Foi um defeito real, e é por isso que o preset
37
37
  * escolhe por você.
38
+ *
39
+ * **`"template"`** liga o controle de fluxo (`{% if %}` / `{% for %}` /
40
+ * `{# #}`). Ele não é o padrão porque um `{%` literal no texto deixaria de ser
41
+ * texto — e num campo que hoje aceita qualquer string isso seria mudança de
42
+ * comportamento sem pedido. Quem quer, declara.
38
43
  */
39
- readonly mode?: "expression" | "program";
44
+ readonly mode?: "expression" | "program" | "template";
40
45
  /** Régua de linhas. Padrão: ligada no `"block"`, desligada no `"inline"`. */
41
46
  readonly gutters?: boolean;
42
47
  /** Busca e `Ctrl+D`. Padrão: ligadas no `"block"`, desligadas no `"inline"`. */
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var o=require('react'),state=require('@codemirror/state'),view=require('@codemirror/view'),commands=require('@codemirror/commands'),codemirror=require('@tslite/codemirror'),editor=require('@tslite/editor'),languageService=require('@tslite/language-service'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var o__namespace=/*#__PURE__*/_interopNamespace(o);var te={mustache:languageService.mustache,whole:languageService.whole},oe=e=>typeof e=="function"?e:te[e];function P(e){let{env:n,service:i,segmenter:t="mustache",mode:u="expression",profile:c,limits:l,unused:d,format:s}=e;return o__namespace.useMemo(()=>i||(n?editor.createHostService({env:n,segmenter:oe(t),mode:u,...c?{profile:c}:{},...l?{limits:l}:{},...d!==void 0?{unused:d}:{},...s?{format:s}:{}}):null),[i,n,t,u,c,l,d,s])}var me=view.EditorView.theme({".cm-scroller":{overflowX:"auto",overflowY:"hidden"},".cm-content":{padding:"6px 8px"},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),Ee=view.EditorView.theme({"&":{height:"100%"},".cm-scroller":{overflowY:"auto"},".cm-content":{padding:"8px"},"&.cm-focused":{outline:"none"}}),Y=e=>e.replace(/\r?\n/g," "),ye=(e,n)=>{if(e===false)return [];let i=n==="block"?{}:{tab:false,indentOnInput:false};return codemirror.codeEditing(typeof e=="object"?{...i,...e}:i)},ve=e=>e?codemirror.gutters(typeof e=="object"?e:{}):[];function M(e){let{value:n,onChange:i,layout:t="inline",wrap:u=t==="block",editing:c,gutters:l,readOnly:d=false,placeholder:s,features:y,tooltipParent:E,onTokenAction:A,isTokenActionable:D,definition:k,extensions:W}=e,v=P(e),L=o__namespace.useRef(null),g=o__namespace.useRef(null),[z,I]=o__namespace.useState(null),[X,$]=o__namespace.useState(false),b=o__namespace.useRef({onChange:i,onTokenAction:A,isTokenActionable:D});b.current={onChange:i,onTokenAction:A,isTokenActionable:D};let p=o__namespace.useRef({service:new state.Compartment,layout:new state.Compartment,editable:new state.Compartment,actions:new state.Compartment}).current,C=o__namespace.useCallback(r=>r?codemirror.languageService(r,{theme:editor.tsliteTokenStyles,...E!==null?{tooltipParent:E??(typeof document<"u"?document.body:void 0)}:{},...y}):[],[y,E]),w=o__namespace.useCallback((r,a,S,h)=>[r==="block"?[...a?[view.EditorView.lineWrapping]:[],Ee]:[codemirror.singleLine,me],ye(S,r),ve(h)],[]),H=o__namespace.useCallback(()=>{let r=[];return b.current.onTokenAction&&r.push(codemirror.tokenAction({actionable:a=>b.current.isTokenActionable?.(a)??true,onAction:a=>b.current.onTokenAction?.(a)})),k&&v?.definitionAt&&r.push(codemirror.gotoDefinition(k)),r},[k,v]);o__namespace.useEffect(()=>{if(!L.current)return;let r=new view.EditorView({parent:L.current,state:state.EditorState.create({doc:t==="inline"?Y(n):n,extensions:[commands.history(),p.service.of(C(v)),p.layout.of(w(t,u,c,l)),p.editable.of(view.EditorView.editable.of(!d)),p.actions.of(H()),...s?[view.placeholder(s)]:[],view.keymap.of([...commands.historyKeymap,...commands.defaultKeymap]),view.EditorView.updateListener.of(a=>{if(a.focusChanged&&$(a.view.hasFocus),!a.docChanged)return;a.transactions.some(h=>h.annotation(codemirror.externalChange))||b.current.onChange?.(a.state.doc.toString());}),view.EditorView.contentAttributes.of({"aria-label":s??"expression"}),...W??[]]})});return g.current=r,I(r),()=>{r.destroy(),g.current=null,I(null);}},[]),o__namespace.useEffect(()=>{g.current?.dispatch({effects:p.service.reconfigure(C(v))});},[v,C,p]),o__namespace.useEffect(()=>{g.current?.dispatch({effects:p.layout.reconfigure(w(t,u,c,l))});},[t,u,c,l,w,p]),o__namespace.useEffect(()=>{g.current?.dispatch({effects:p.editable.reconfigure(view.EditorView.editable.of(!d))});},[d,p]),o__namespace.useEffect(()=>{g.current?.dispatch({effects:p.actions.reconfigure(H())});},[H,p]),o__namespace.useEffect(()=>{let r=g.current;if(!r)return;let a=t==="inline"?Y(n):n;if(a===r.state.doc.toString())return;let{anchor:S,head:h}=r.state.selection.main,U=J=>Math.min(J,a.length);r.dispatch({changes:{from:0,to:r.state.doc.length,insert:a},selection:{anchor:U(S),head:U(h)},annotations:codemirror.externalChange.of(true)});},[n,t]);let q=o__namespace.useCallback(()=>g.current?.focus(),[]);return {ref:L,view:z,focused:X,service:v,focus:q}}var G=o__namespace.createContext(null);function K(){let e=o__namespace.useContext(G);if(!e)throw new Error("useFieldContext must be used inside <ExpressionField.Root>");return e}var be=["value","onChange","layout","wrap","editing","gutters","readOnly","placeholder","features","tooltipParent","onTokenAction","isTokenActionable","definition","extensions","env","service","segmenter","mode","profile","limits","unused","format"];var N=o__namespace.forwardRef(function(n,i){let{children:t,...u}=n,c={},l={};for(let[s,y]of Object.entries(u))(be.includes(s)?c:l)[s]=y;let d=M(c);return jsxRuntime.jsx(G.Provider,{value:d,children:jsxRuntime.jsx("div",{ref:i,...l,children:typeof t=="function"?t(d):t})})}),j=o__namespace.forwardRef(function(n,i){let t=K();return jsxRuntime.jsx("div",{ref:t.ref,...n})}),B=o__namespace.forwardRef(function({children:n,...i},t){return jsxRuntime.jsx("button",{ref:t,type:"button",...i,children:n})}),R={Root:N,Editor:j,ExpandTrigger:B};var f={fg:"var(--foreground, #cccccc)",mutedFg:"var(--muted-foreground, #8b8b8b)",border:"var(--border, #2b2b2b)",ring:"var(--ring, #0078d4)",input:"var(--input, transparent)",destructive:"var(--destructive, #f14c4c)",font:"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)"},he=["--foreground","--muted-foreground","--border","--ring","--input","--destructive","--font-mono","--muted","--popover","--popover-foreground","--primary","--primary-foreground","--secondary","--accent"];var Re=jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"})});function Fe({invalid:e,className:n,style:i,onExpand:t,expandIcon:u,multiline:c,layout:l,...d}){let s=l??(c?"block":"inline");return jsxRuntime.jsx(R.Root,{...d,layout:s,className:n,children:y=>jsxRuntime.jsxs("div",{style:{position:"relative",border:`1px solid ${e?f.destructive:y.focused?f.ring:f.border}`,borderRadius:"6px",backgroundColor:f.input,color:f.fg,fontFamily:f.font,fontSize:"13px",overflow:"hidden",...s==="block"?{height:"100%",display:"flex",flexDirection:"column"}:{},...i},children:[jsxRuntime.jsx(R.Editor,{style:s==="block"?{flex:1,minHeight:0}:{paddingRight:t?"24px":void 0}}),t&&jsxRuntime.jsx(R.ExpandTrigger,{onClick:t,"aria-label":"Expandir",title:"Expandir",onMouseEnter:E=>E.currentTarget.style.opacity="1",onMouseLeave:E=>E.currentTarget.style.opacity="0.55",style:{position:"absolute",top:s==="block"?"6px":"50%",right:"4px",transform:s==="block"?void 0:"translateY(-50%)",display:"flex",alignItems:"center",justifyContent:"center",width:"20px",height:"20px",padding:0,lineHeight:0,border:"none",borderRadius:"4px",background:f.input,color:f.mutedFg,cursor:"pointer",opacity:.55},children:u??Re})]})})}exports.CSS_VARS=he;exports.ExpressionField=R;exports.ExpressionFieldEditor=j;exports.ExpressionFieldExpandTrigger=B;exports.ExpressionFieldRoot=N;exports.ExpressionInput=Fe;exports.V=f;exports.useExpressionField=M;exports.useFieldContext=K;exports.useLanguageService=P;
1
+ 'use strict';var o=require('react'),state=require('@codemirror/state'),view=require('@codemirror/view'),commands=require('@codemirror/commands'),codemirror=require('@tslite/codemirror'),editor=require('@tslite/editor'),languageService=require('@tslite/language-service'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var o__namespace=/*#__PURE__*/_interopNamespace(o);var te={mustache:languageService.mustache,whole:languageService.whole},oe=e=>typeof e=="function"?e:te[e];function P(e){let{env:n,service:i,segmenter:t="mustache",mode:c="expression",profile:l,limits:d,unused:p,format:s}=e;return o__namespace.useMemo(()=>{if(i)return i;if(!n)return null;let g={env:n,...l?{profile:l}:{},...d?{limits:d}:{},...p!==void 0?{unused:p}:{},...s?{format:s}:{}};return c==="template"?editor.createHostService({...g,mode:c}):editor.createHostService({...g,segmenter:oe(t),mode:c})},[i,n,t,c,l,d,p,s])}var xe=view.EditorView.theme({".cm-scroller":{overflowX:"auto",overflowY:"hidden"},".cm-content":{padding:"6px 8px"},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),Ee=view.EditorView.theme({"&":{height:"100%"},".cm-scroller":{overflowY:"auto"},".cm-content":{padding:"8px"},"&.cm-focused":{outline:"none"}}),G=e=>e.replace(/\r?\n/g," "),ye=(e,n)=>{if(e===false)return [];let i=n==="block"?{}:{tab:false,indentOnInput:false};return codemirror.codeEditing(typeof e=="object"?{...i,...e}:i)},ve=e=>e?codemirror.gutters(typeof e=="object"?e:{}):[];function M(e){let{value:n,onChange:i,layout:t="inline",wrap:c=t==="block",editing:l,gutters:d,readOnly:p=false,placeholder:s,features:g,tooltipParent:y,onTokenAction:A,isTokenActionable:D,definition:k,extensions:z}=e,v=P(e),L=o__namespace.useRef(null),m=o__namespace.useRef(null),[X,I]=o__namespace.useState(null),[$,q]=o__namespace.useState(false),b=o__namespace.useRef({onChange:i,onTokenAction:A,isTokenActionable:D});b.current={onChange:i,onTokenAction:A,isTokenActionable:D};let u=o__namespace.useRef({service:new state.Compartment,layout:new state.Compartment,editable:new state.Compartment,actions:new state.Compartment}).current,C=o__namespace.useCallback(r=>r?codemirror.languageService(r,{theme:editor.tsliteTokenStyles,...y!==null?{tooltipParent:y??(typeof document<"u"?document.body:void 0)}:{},...g}):[],[g,y]),w=o__namespace.useCallback((r,a,S,h)=>[r==="block"?[...a?[view.EditorView.lineWrapping]:[],Ee]:[codemirror.singleLine,xe],ye(S,r),ve(h)],[]),H=o__namespace.useCallback(()=>{let r=[];return b.current.onTokenAction&&r.push(codemirror.tokenAction({actionable:a=>b.current.isTokenActionable?.(a)??true,onAction:a=>b.current.onTokenAction?.(a)})),k&&v?.definitionAt&&r.push(codemirror.gotoDefinition(k)),r},[k,v]);o__namespace.useEffect(()=>{if(!L.current)return;let r=new view.EditorView({parent:L.current,state:state.EditorState.create({doc:t==="inline"?G(n):n,extensions:[commands.history(),u.service.of(C(v)),u.layout.of(w(t,c,l,d)),u.editable.of(view.EditorView.editable.of(!p)),u.actions.of(H()),...s?[view.placeholder(s)]:[],view.keymap.of([...commands.historyKeymap,...commands.defaultKeymap]),view.EditorView.updateListener.of(a=>{if(a.focusChanged&&q(a.view.hasFocus),!a.docChanged)return;a.transactions.some(h=>h.annotation(codemirror.externalChange))||b.current.onChange?.(a.state.doc.toString());}),view.EditorView.contentAttributes.of({"aria-label":s??"expression"}),...z??[]]})});return m.current=r,I(r),()=>{r.destroy(),m.current=null,I(null);}},[]),o__namespace.useEffect(()=>{m.current?.dispatch({effects:u.service.reconfigure(C(v))});},[v,C,u]),o__namespace.useEffect(()=>{m.current?.dispatch({effects:u.layout.reconfigure(w(t,c,l,d))});},[t,c,l,d,w,u]),o__namespace.useEffect(()=>{m.current?.dispatch({effects:u.editable.reconfigure(view.EditorView.editable.of(!p))});},[p,u]),o__namespace.useEffect(()=>{m.current?.dispatch({effects:u.actions.reconfigure(H())});},[H,u]),o__namespace.useEffect(()=>{let r=m.current;if(!r)return;let a=t==="inline"?G(n):n;if(a===r.state.doc.toString())return;let{anchor:S,head:h}=r.state.selection.main,U=Q=>Math.min(Q,a.length);r.dispatch({changes:{from:0,to:r.state.doc.length,insert:a},selection:{anchor:U(S),head:U(h)},annotations:codemirror.externalChange.of(true)});},[n,t]);let J=o__namespace.useCallback(()=>m.current?.focus(),[]);return {ref:L,view:X,focused:$,service:v,focus:J}}var K=o__namespace.createContext(null);function N(){let e=o__namespace.useContext(K);if(!e)throw new Error("useFieldContext must be used inside <ExpressionField.Root>");return e}var be=["value","onChange","layout","wrap","editing","gutters","readOnly","placeholder","features","tooltipParent","onTokenAction","isTokenActionable","definition","extensions","env","service","segmenter","mode","profile","limits","unused","format"];var j=o__namespace.forwardRef(function(n,i){let{children:t,...c}=n,l={},d={};for(let[s,g]of Object.entries(c))(be.includes(s)?l:d)[s]=g;let p=M(l);return jsxRuntime.jsx(K.Provider,{value:p,children:jsxRuntime.jsx("div",{ref:i,...d,children:typeof t=="function"?t(p):t})})}),B=o__namespace.forwardRef(function(n,i){let t=N();return jsxRuntime.jsx("div",{ref:t.ref,...n})}),W=o__namespace.forwardRef(function({children:n,...i},t){return jsxRuntime.jsx("button",{ref:t,type:"button",...i,children:n})}),R={Root:j,Editor:B,ExpandTrigger:W};var f={fg:"var(--foreground, #cccccc)",mutedFg:"var(--muted-foreground, #8b8b8b)",border:"var(--border, #2b2b2b)",ring:"var(--ring, #0078d4)",input:"var(--input, transparent)",destructive:"var(--destructive, #f14c4c)",font:"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)"},he=["--foreground","--muted-foreground","--border","--ring","--input","--destructive","--font-mono","--muted","--popover","--popover-foreground","--primary","--primary-foreground","--secondary","--accent"];var Re=jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"})});function Fe({invalid:e,className:n,style:i,onExpand:t,expandIcon:c,multiline:l,layout:d,...p}){let s=d??(l?"block":"inline");return jsxRuntime.jsx(R.Root,{...p,layout:s,className:n,children:g=>jsxRuntime.jsxs("div",{style:{position:"relative",border:`1px solid ${e?f.destructive:g.focused?f.ring:f.border}`,borderRadius:"6px",backgroundColor:f.input,color:f.fg,fontFamily:f.font,fontSize:"13px",overflow:"hidden",...s==="block"?{height:"100%",display:"flex",flexDirection:"column"}:{},...i},children:[jsxRuntime.jsx(R.Editor,{style:s==="block"?{flex:1,minHeight:0}:{paddingRight:t?"24px":void 0}}),t&&jsxRuntime.jsx(R.ExpandTrigger,{onClick:t,"aria-label":"Expandir",title:"Expandir",onMouseEnter:y=>y.currentTarget.style.opacity="1",onMouseLeave:y=>y.currentTarget.style.opacity="0.55",style:{position:"absolute",top:s==="block"?"6px":"50%",right:"4px",transform:s==="block"?void 0:"translateY(-50%)",display:"flex",alignItems:"center",justifyContent:"center",width:"20px",height:"20px",padding:0,lineHeight:0,border:"none",borderRadius:"4px",background:f.input,color:f.mutedFg,cursor:"pointer",opacity:.55},children:c??Re})]})})}exports.CSS_VARS=he;exports.ExpressionField=R;exports.ExpressionFieldEditor=B;exports.ExpressionFieldExpandTrigger=W;exports.ExpressionFieldRoot=j;exports.ExpressionInput=Fe;exports.V=f;exports.useExpressionField=M;exports.useFieldContext=N;exports.useLanguageService=P;
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { U as UseExpressionFieldOptions, E as ExpressionFieldHandle } from './useExpressionField-CA__y0bO.cjs';
3
- export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-CA__y0bO.cjs';
2
+ import { U as UseExpressionFieldOptions, E as ExpressionFieldHandle } from './useExpressionField-CmiOEqIK.cjs';
3
+ export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-CmiOEqIK.cjs';
4
4
  export { TokenActionTarget } from '@tslite/codemirror';
5
5
  import '@codemirror/state';
6
6
  import '@codemirror/view';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { U as UseExpressionFieldOptions, E as ExpressionFieldHandle } from './useExpressionField-CA__y0bO.js';
3
- export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-CA__y0bO.js';
2
+ import { U as UseExpressionFieldOptions, E as ExpressionFieldHandle } from './useExpressionField-CmiOEqIK.js';
3
+ export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-CmiOEqIK.js';
4
4
  export { TokenActionTarget } from '@tslite/codemirror';
5
5
  import '@codemirror/state';
6
6
  import '@codemirror/view';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import*as o from'react';import {Compartment,EditorState}from'@codemirror/state';import {EditorView,placeholder,keymap}from'@codemirror/view';import {history,historyKeymap,defaultKeymap}from'@codemirror/commands';import {languageService,singleLine,tokenAction,gotoDefinition,externalChange,codeEditing,gutters}from'@tslite/codemirror';import {tsliteTokenStyles,createHostService}from'@tslite/editor';import {whole,mustache}from'@tslite/language-service';import {jsx,jsxs}from'react/jsx-runtime';var te={mustache:mustache,whole:whole},oe=e=>typeof e=="function"?e:te[e];function P(e){let{env:n,service:i,segmenter:t="mustache",mode:u="expression",profile:c,limits:l,unused:d,format:s}=e;return o.useMemo(()=>i||(n?createHostService({env:n,segmenter:oe(t),mode:u,...c?{profile:c}:{},...l?{limits:l}:{},...d!==void 0?{unused:d}:{},...s?{format:s}:{}}):null),[i,n,t,u,c,l,d,s])}var me=EditorView.theme({".cm-scroller":{overflowX:"auto",overflowY:"hidden"},".cm-content":{padding:"6px 8px"},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),Ee=EditorView.theme({"&":{height:"100%"},".cm-scroller":{overflowY:"auto"},".cm-content":{padding:"8px"},"&.cm-focused":{outline:"none"}}),Y=e=>e.replace(/\r?\n/g," "),ye=(e,n)=>{if(e===false)return [];let i=n==="block"?{}:{tab:false,indentOnInput:false};return codeEditing(typeof e=="object"?{...i,...e}:i)},ve=e=>e?gutters(typeof e=="object"?e:{}):[];function M(e){let{value:n,onChange:i,layout:t="inline",wrap:u=t==="block",editing:c,gutters:l,readOnly:d=false,placeholder:s,features:y,tooltipParent:E,onTokenAction:A,isTokenActionable:D,definition:k,extensions:W}=e,v=P(e),L=o.useRef(null),g=o.useRef(null),[z,I]=o.useState(null),[X,$]=o.useState(false),b=o.useRef({onChange:i,onTokenAction:A,isTokenActionable:D});b.current={onChange:i,onTokenAction:A,isTokenActionable:D};let p=o.useRef({service:new Compartment,layout:new Compartment,editable:new Compartment,actions:new Compartment}).current,C=o.useCallback(r=>r?languageService(r,{theme:tsliteTokenStyles,...E!==null?{tooltipParent:E??(typeof document<"u"?document.body:void 0)}:{},...y}):[],[y,E]),w=o.useCallback((r,a,S,h)=>[r==="block"?[...a?[EditorView.lineWrapping]:[],Ee]:[singleLine,me],ye(S,r),ve(h)],[]),H=o.useCallback(()=>{let r=[];return b.current.onTokenAction&&r.push(tokenAction({actionable:a=>b.current.isTokenActionable?.(a)??true,onAction:a=>b.current.onTokenAction?.(a)})),k&&v?.definitionAt&&r.push(gotoDefinition(k)),r},[k,v]);o.useEffect(()=>{if(!L.current)return;let r=new EditorView({parent:L.current,state:EditorState.create({doc:t==="inline"?Y(n):n,extensions:[history(),p.service.of(C(v)),p.layout.of(w(t,u,c,l)),p.editable.of(EditorView.editable.of(!d)),p.actions.of(H()),...s?[placeholder(s)]:[],keymap.of([...historyKeymap,...defaultKeymap]),EditorView.updateListener.of(a=>{if(a.focusChanged&&$(a.view.hasFocus),!a.docChanged)return;a.transactions.some(h=>h.annotation(externalChange))||b.current.onChange?.(a.state.doc.toString());}),EditorView.contentAttributes.of({"aria-label":s??"expression"}),...W??[]]})});return g.current=r,I(r),()=>{r.destroy(),g.current=null,I(null);}},[]),o.useEffect(()=>{g.current?.dispatch({effects:p.service.reconfigure(C(v))});},[v,C,p]),o.useEffect(()=>{g.current?.dispatch({effects:p.layout.reconfigure(w(t,u,c,l))});},[t,u,c,l,w,p]),o.useEffect(()=>{g.current?.dispatch({effects:p.editable.reconfigure(EditorView.editable.of(!d))});},[d,p]),o.useEffect(()=>{g.current?.dispatch({effects:p.actions.reconfigure(H())});},[H,p]),o.useEffect(()=>{let r=g.current;if(!r)return;let a=t==="inline"?Y(n):n;if(a===r.state.doc.toString())return;let{anchor:S,head:h}=r.state.selection.main,U=J=>Math.min(J,a.length);r.dispatch({changes:{from:0,to:r.state.doc.length,insert:a},selection:{anchor:U(S),head:U(h)},annotations:externalChange.of(true)});},[n,t]);let q=o.useCallback(()=>g.current?.focus(),[]);return {ref:L,view:z,focused:X,service:v,focus:q}}var G=o.createContext(null);function K(){let e=o.useContext(G);if(!e)throw new Error("useFieldContext must be used inside <ExpressionField.Root>");return e}var be=["value","onChange","layout","wrap","editing","gutters","readOnly","placeholder","features","tooltipParent","onTokenAction","isTokenActionable","definition","extensions","env","service","segmenter","mode","profile","limits","unused","format"];var N=o.forwardRef(function(n,i){let{children:t,...u}=n,c={},l={};for(let[s,y]of Object.entries(u))(be.includes(s)?c:l)[s]=y;let d=M(c);return jsx(G.Provider,{value:d,children:jsx("div",{ref:i,...l,children:typeof t=="function"?t(d):t})})}),j=o.forwardRef(function(n,i){let t=K();return jsx("div",{ref:t.ref,...n})}),B=o.forwardRef(function({children:n,...i},t){return jsx("button",{ref:t,type:"button",...i,children:n})}),R={Root:N,Editor:j,ExpandTrigger:B};var f={fg:"var(--foreground, #cccccc)",mutedFg:"var(--muted-foreground, #8b8b8b)",border:"var(--border, #2b2b2b)",ring:"var(--ring, #0078d4)",input:"var(--input, transparent)",destructive:"var(--destructive, #f14c4c)",font:"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)"},he=["--foreground","--muted-foreground","--border","--ring","--input","--destructive","--font-mono","--muted","--popover","--popover-foreground","--primary","--primary-foreground","--secondary","--accent"];var Re=jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:jsx("path",{d:"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"})});function Fe({invalid:e,className:n,style:i,onExpand:t,expandIcon:u,multiline:c,layout:l,...d}){let s=l??(c?"block":"inline");return jsx(R.Root,{...d,layout:s,className:n,children:y=>jsxs("div",{style:{position:"relative",border:`1px solid ${e?f.destructive:y.focused?f.ring:f.border}`,borderRadius:"6px",backgroundColor:f.input,color:f.fg,fontFamily:f.font,fontSize:"13px",overflow:"hidden",...s==="block"?{height:"100%",display:"flex",flexDirection:"column"}:{},...i},children:[jsx(R.Editor,{style:s==="block"?{flex:1,minHeight:0}:{paddingRight:t?"24px":void 0}}),t&&jsx(R.ExpandTrigger,{onClick:t,"aria-label":"Expandir",title:"Expandir",onMouseEnter:E=>E.currentTarget.style.opacity="1",onMouseLeave:E=>E.currentTarget.style.opacity="0.55",style:{position:"absolute",top:s==="block"?"6px":"50%",right:"4px",transform:s==="block"?void 0:"translateY(-50%)",display:"flex",alignItems:"center",justifyContent:"center",width:"20px",height:"20px",padding:0,lineHeight:0,border:"none",borderRadius:"4px",background:f.input,color:f.mutedFg,cursor:"pointer",opacity:.55},children:u??Re})]})})}export{he as CSS_VARS,R as ExpressionField,j as ExpressionFieldEditor,B as ExpressionFieldExpandTrigger,N as ExpressionFieldRoot,Fe as ExpressionInput,f as V,M as useExpressionField,K as useFieldContext,P as useLanguageService};
1
+ import*as o from'react';import {Compartment,EditorState}from'@codemirror/state';import {EditorView,placeholder,keymap}from'@codemirror/view';import {history,historyKeymap,defaultKeymap}from'@codemirror/commands';import {languageService,singleLine,tokenAction,gotoDefinition,externalChange,codeEditing,gutters}from'@tslite/codemirror';import {tsliteTokenStyles,createHostService}from'@tslite/editor';import {whole,mustache}from'@tslite/language-service';import {jsx,jsxs}from'react/jsx-runtime';var te={mustache:mustache,whole:whole},oe=e=>typeof e=="function"?e:te[e];function P(e){let{env:n,service:i,segmenter:t="mustache",mode:c="expression",profile:l,limits:d,unused:p,format:s}=e;return o.useMemo(()=>{if(i)return i;if(!n)return null;let g={env:n,...l?{profile:l}:{},...d?{limits:d}:{},...p!==void 0?{unused:p}:{},...s?{format:s}:{}};return c==="template"?createHostService({...g,mode:c}):createHostService({...g,segmenter:oe(t),mode:c})},[i,n,t,c,l,d,p,s])}var xe=EditorView.theme({".cm-scroller":{overflowX:"auto",overflowY:"hidden"},".cm-content":{padding:"6px 8px"},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),Ee=EditorView.theme({"&":{height:"100%"},".cm-scroller":{overflowY:"auto"},".cm-content":{padding:"8px"},"&.cm-focused":{outline:"none"}}),G=e=>e.replace(/\r?\n/g," "),ye=(e,n)=>{if(e===false)return [];let i=n==="block"?{}:{tab:false,indentOnInput:false};return codeEditing(typeof e=="object"?{...i,...e}:i)},ve=e=>e?gutters(typeof e=="object"?e:{}):[];function M(e){let{value:n,onChange:i,layout:t="inline",wrap:c=t==="block",editing:l,gutters:d,readOnly:p=false,placeholder:s,features:g,tooltipParent:y,onTokenAction:A,isTokenActionable:D,definition:k,extensions:z}=e,v=P(e),L=o.useRef(null),m=o.useRef(null),[X,I]=o.useState(null),[$,q]=o.useState(false),b=o.useRef({onChange:i,onTokenAction:A,isTokenActionable:D});b.current={onChange:i,onTokenAction:A,isTokenActionable:D};let u=o.useRef({service:new Compartment,layout:new Compartment,editable:new Compartment,actions:new Compartment}).current,C=o.useCallback(r=>r?languageService(r,{theme:tsliteTokenStyles,...y!==null?{tooltipParent:y??(typeof document<"u"?document.body:void 0)}:{},...g}):[],[g,y]),w=o.useCallback((r,a,S,h)=>[r==="block"?[...a?[EditorView.lineWrapping]:[],Ee]:[singleLine,xe],ye(S,r),ve(h)],[]),H=o.useCallback(()=>{let r=[];return b.current.onTokenAction&&r.push(tokenAction({actionable:a=>b.current.isTokenActionable?.(a)??true,onAction:a=>b.current.onTokenAction?.(a)})),k&&v?.definitionAt&&r.push(gotoDefinition(k)),r},[k,v]);o.useEffect(()=>{if(!L.current)return;let r=new EditorView({parent:L.current,state:EditorState.create({doc:t==="inline"?G(n):n,extensions:[history(),u.service.of(C(v)),u.layout.of(w(t,c,l,d)),u.editable.of(EditorView.editable.of(!p)),u.actions.of(H()),...s?[placeholder(s)]:[],keymap.of([...historyKeymap,...defaultKeymap]),EditorView.updateListener.of(a=>{if(a.focusChanged&&q(a.view.hasFocus),!a.docChanged)return;a.transactions.some(h=>h.annotation(externalChange))||b.current.onChange?.(a.state.doc.toString());}),EditorView.contentAttributes.of({"aria-label":s??"expression"}),...z??[]]})});return m.current=r,I(r),()=>{r.destroy(),m.current=null,I(null);}},[]),o.useEffect(()=>{m.current?.dispatch({effects:u.service.reconfigure(C(v))});},[v,C,u]),o.useEffect(()=>{m.current?.dispatch({effects:u.layout.reconfigure(w(t,c,l,d))});},[t,c,l,d,w,u]),o.useEffect(()=>{m.current?.dispatch({effects:u.editable.reconfigure(EditorView.editable.of(!p))});},[p,u]),o.useEffect(()=>{m.current?.dispatch({effects:u.actions.reconfigure(H())});},[H,u]),o.useEffect(()=>{let r=m.current;if(!r)return;let a=t==="inline"?G(n):n;if(a===r.state.doc.toString())return;let{anchor:S,head:h}=r.state.selection.main,U=Q=>Math.min(Q,a.length);r.dispatch({changes:{from:0,to:r.state.doc.length,insert:a},selection:{anchor:U(S),head:U(h)},annotations:externalChange.of(true)});},[n,t]);let J=o.useCallback(()=>m.current?.focus(),[]);return {ref:L,view:X,focused:$,service:v,focus:J}}var K=o.createContext(null);function N(){let e=o.useContext(K);if(!e)throw new Error("useFieldContext must be used inside <ExpressionField.Root>");return e}var be=["value","onChange","layout","wrap","editing","gutters","readOnly","placeholder","features","tooltipParent","onTokenAction","isTokenActionable","definition","extensions","env","service","segmenter","mode","profile","limits","unused","format"];var j=o.forwardRef(function(n,i){let{children:t,...c}=n,l={},d={};for(let[s,g]of Object.entries(c))(be.includes(s)?l:d)[s]=g;let p=M(l);return jsx(K.Provider,{value:p,children:jsx("div",{ref:i,...d,children:typeof t=="function"?t(p):t})})}),B=o.forwardRef(function(n,i){let t=N();return jsx("div",{ref:t.ref,...n})}),W=o.forwardRef(function({children:n,...i},t){return jsx("button",{ref:t,type:"button",...i,children:n})}),R={Root:j,Editor:B,ExpandTrigger:W};var f={fg:"var(--foreground, #cccccc)",mutedFg:"var(--muted-foreground, #8b8b8b)",border:"var(--border, #2b2b2b)",ring:"var(--ring, #0078d4)",input:"var(--input, transparent)",destructive:"var(--destructive, #f14c4c)",font:"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)"},he=["--foreground","--muted-foreground","--border","--ring","--input","--destructive","--font-mono","--muted","--popover","--popover-foreground","--primary","--primary-foreground","--secondary","--accent"];var Re=jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:jsx("path",{d:"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"})});function Fe({invalid:e,className:n,style:i,onExpand:t,expandIcon:c,multiline:l,layout:d,...p}){let s=d??(l?"block":"inline");return jsx(R.Root,{...p,layout:s,className:n,children:g=>jsxs("div",{style:{position:"relative",border:`1px solid ${e?f.destructive:g.focused?f.ring:f.border}`,borderRadius:"6px",backgroundColor:f.input,color:f.fg,fontFamily:f.font,fontSize:"13px",overflow:"hidden",...s==="block"?{height:"100%",display:"flex",flexDirection:"column"}:{},...i},children:[jsx(R.Editor,{style:s==="block"?{flex:1,minHeight:0}:{paddingRight:t?"24px":void 0}}),t&&jsx(R.ExpandTrigger,{onClick:t,"aria-label":"Expandir",title:"Expandir",onMouseEnter:y=>y.currentTarget.style.opacity="1",onMouseLeave:y=>y.currentTarget.style.opacity="0.55",style:{position:"absolute",top:s==="block"?"6px":"50%",right:"4px",transform:s==="block"?void 0:"translateY(-50%)",display:"flex",alignItems:"center",justifyContent:"center",width:"20px",height:"20px",padding:0,lineHeight:0,border:"none",borderRadius:"4px",background:f.input,color:f.mutedFg,cursor:"pointer",opacity:.55},children:c??Re})]})})}export{he as CSS_VARS,R as ExpressionField,B as ExpressionFieldEditor,W as ExpressionFieldExpandTrigger,j as ExpressionFieldRoot,Fe as ExpressionInput,f as V,M as useExpressionField,N as useFieldContext,P as useLanguageService};
@@ -27,15 +27,31 @@ interface LanguageServiceOptions {
27
27
  * trocar o cérebro por outro (outra linguagem, outra implementação).
28
28
  */
29
29
  readonly service?: LanguageService;
30
- /** Onde o código está. Padrão: `"mustache"`. */
30
+ /**
31
+ * Onde o código está. Padrão: `"mustache"`.
32
+ *
33
+ * **Não se aplica a `mode: "template"`** — lá quem acha as marcações é o
34
+ * scanner do `@tslite/template`, que conhece `{{ }}`, `{% %}` e `{# #}` e
35
+ * fecha certo em `{{ f("}}") }}` porque tokeniza. O que for passado aqui é
36
+ * ignorado naquele modo.
37
+ */
31
38
  readonly segmenter?: SegmenterOption;
32
39
  /**
33
40
  * O que o código É. Padrão: `"expression"`.
34
41
  *
35
- * Ortogonal ao `segmenter`: uma ilha pode conter um programa, e um campo
36
- * inteiro pode ser uma expressão. São dois botões porque nada os amarra.
42
+ * `"expression"` e `"program"` são ortogonais ao `segmenter`: uma ilha pode
43
+ * conter um programa, e um campo inteiro pode ser uma expressão. São dois
44
+ * botões porque nada os amarra.
45
+ *
46
+ * **`"template"` é outra coisa.** O documento inteiro é um template — `{{ }}`
47
+ * mais `{% if %}` / `{% for %}` / `{# #}` —, e a análise é dele todo, porque o
48
+ * binding de um `{% for u of us %}` atravessa as ilhas de dentro.
49
+ *
50
+ * Ele **não tira nada**: uma saída sozinha continua valendo o tipo dela
51
+ * (`{{ order.total }}` é `number`), porque essa regra é estrutural. O que ele
52
+ * acrescenta é o controle de fluxo.
37
53
  */
38
- readonly mode?: "expression" | "program";
54
+ readonly mode?: "expression" | "program" | "template";
39
55
  /**
40
56
  * Capability — **desinstala** features da Linguagem.
41
57
  *
@@ -27,15 +27,31 @@ interface LanguageServiceOptions {
27
27
  * trocar o cérebro por outro (outra linguagem, outra implementação).
28
28
  */
29
29
  readonly service?: LanguageService;
30
- /** Onde o código está. Padrão: `"mustache"`. */
30
+ /**
31
+ * Onde o código está. Padrão: `"mustache"`.
32
+ *
33
+ * **Não se aplica a `mode: "template"`** — lá quem acha as marcações é o
34
+ * scanner do `@tslite/template`, que conhece `{{ }}`, `{% %}` e `{# #}` e
35
+ * fecha certo em `{{ f("}}") }}` porque tokeniza. O que for passado aqui é
36
+ * ignorado naquele modo.
37
+ */
31
38
  readonly segmenter?: SegmenterOption;
32
39
  /**
33
40
  * O que o código É. Padrão: `"expression"`.
34
41
  *
35
- * Ortogonal ao `segmenter`: uma ilha pode conter um programa, e um campo
36
- * inteiro pode ser uma expressão. São dois botões porque nada os amarra.
42
+ * `"expression"` e `"program"` são ortogonais ao `segmenter`: uma ilha pode
43
+ * conter um programa, e um campo inteiro pode ser uma expressão. São dois
44
+ * botões porque nada os amarra.
45
+ *
46
+ * **`"template"` é outra coisa.** O documento inteiro é um template — `{{ }}`
47
+ * mais `{% if %}` / `{% for %}` / `{# #}` —, e a análise é dele todo, porque o
48
+ * binding de um `{% for u of us %}` atravessa as ilhas de dentro.
49
+ *
50
+ * Ele **não tira nada**: uma saída sozinha continua valendo o tipo dela
51
+ * (`{{ order.total }}` é `number`), porque essa regra é estrutural. O que ele
52
+ * acrescenta é o controle de fluxo.
37
53
  */
38
- readonly mode?: "expression" | "program";
54
+ readonly mode?: "expression" | "program" | "template";
39
55
  /**
40
56
  * Capability — **desinstala** features da Linguagem.
41
57
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tslite/react",
3
- "version": "0.1.0",
3
+ "version": "0.2.3",
4
4
  "description": "React bindings for TSLite — a headless expression field (CodeMirror 6) with type-aware highlighting, completion, diagnostics and quick-fixes, driven by the TSLite checker.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -47,10 +47,10 @@
47
47
  "access": "public"
48
48
  },
49
49
  "dependencies": {
50
- "@tslite/codemirror": "0.1.0",
51
- "@tslite/editor": "0.4.0",
52
- "@tslite/format": "0.3.0",
53
- "@tslite/language-service": "0.1.0"
50
+ "@tslite/codemirror": "0.3.1",
51
+ "@tslite/editor": "0.6.1",
52
+ "@tslite/language-service": "0.3.0",
53
+ "@tslite/format": "0.3.2"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@codemirror/autocomplete": "^6.0.0",
@@ -76,7 +76,7 @@
76
76
  "@types/react-dom": "^18.3.1",
77
77
  "react": "^18.3.1",
78
78
  "react-dom": "^18.3.1",
79
- "@tslite/checker": "0.7.0"
79
+ "@tslite/checker": "0.7.1"
80
80
  },
81
81
  "peerDependenciesMeta": {
82
82
  "@codemirror/search": {