@tslite/react 0.2.12 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/full.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var search=require('@tslite/codemirror/search'),format=require('@tslite/format'),editor=require('@tslite/editor');function y(t={}){let{dark:s=true,layout:e="inline",mode:o="expression",gutters:n=e==="block",search:i=e==="block",extensions:r=[]}=t;return {layout:e,mode:o,gutters:n,format:o==="program"?format.format:format.formatExpression,features:{chrome:{dark:s},theme:editor.tsliteTokenStyles},extensions:i?[search.searchEditing(),...r]:[...r]}}Object.defineProperty(exports,"searchEditing",{enumerable:true,get:function(){return search.searchEditing}});Object.defineProperty(exports,"format",{enumerable:true,get:function(){return format.format}});Object.defineProperty(exports,"formatExpression",{enumerable:true,get:function(){return format.formatExpression}});Object.defineProperty(exports,"tsliteTokenStyles",{enumerable:true,get:function(){return editor.tsliteTokenStyles}});exports.expressionFieldProps=y;
1
+ 'use strict';var search=require('@tslite/codemirror/search'),format=require('@tslite/format'),editor=require('@tslite/editor');function u(t={}){let{dark:s=true,layout:e="inline",mode:o="expression",segmenter:n="mustache",gutters:i=e==="block",search:a=e==="block",extensions:r=[]}=t;return {layout:e,mode:o,...o==="template"?{}:{segmenter:n},gutters:i,format:o==="program"?format.format:format.formatExpression,features:{chrome:{dark:s},theme:editor.tsliteTokenStyles},extensions:a?[search.searchEditing(),...r]:[...r]}}Object.defineProperty(exports,"searchEditing",{enumerable:true,get:function(){return search.searchEditing}});Object.defineProperty(exports,"format",{enumerable:true,get:function(){return format.format}});Object.defineProperty(exports,"formatExpression",{enumerable:true,get:function(){return format.formatExpression}});Object.defineProperty(exports,"tsliteTokenStyles",{enumerable:true,get:function(){return editor.tsliteTokenStyles}});exports.expressionFieldProps=u;
package/dist/full.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Extension } from '@codemirror/state';
2
- import { U as UseExpressionFieldOptions } from './useExpressionField-CmiOEqIK.cjs';
2
+ import { F as FieldLayout, S as SegmenterOption, U as UseExpressionFieldOptions } from './useExpressionField-RJzhO-r7.cjs';
3
3
  export { searchEditing } from '@tslite/codemirror/search';
4
4
  export { format, formatExpression } from '@tslite/format';
5
5
  export { tsliteTokenStyles } from '@tslite/editor';
@@ -23,10 +23,12 @@ interface PresetOptions {
23
23
  /**
24
24
  * Como o campo se apresenta. Padrão: `"inline"`.
25
25
  *
26
- * `"block"` é o campo EXPANDIDO (tipicamente num modal): ganha o `Tab` que
26
+ * `"grow"` é o campo de FORMULÁRIO que cresce com o conteúdo: `Enter` termina,
27
+ * `Shift+Enter` quebra, `Tab` navega; régua e busca ficam desligadas, como no
28
+ * `"inline"`. `"block"` é o campo EXPANDIDO (tipicamente num modal): ganha o `Tab` que
27
29
  * indenta, a quebra de linha e — por este preset — a régua de linhas.
28
30
  */
29
- readonly layout?: "inline" | "block";
31
+ readonly layout?: FieldLayout;
30
32
  /**
31
33
  * O que o código É. Padrão: `"expression"`.
32
34
  *
@@ -42,6 +44,17 @@ interface PresetOptions {
42
44
  * comportamento sem pedido. Quem quer, declara.
43
45
  */
44
46
  readonly mode?: "expression" | "program" | "template";
47
+ /**
48
+ * ONDE o código está. Padrão: `"mustache"` (texto com ilhas `{{ }}`). Um slot em
49
+ * que o campo inteiro é código (um predicado, um mapper) é `"whole"` — e sem o
50
+ * preset emiti-lo, quem esquecia de passá-lo depois do spread ficava com o
51
+ * `mustache` procurando `{{ }}` num predicado: o campo inteiro virava texto
52
+ * inerte, sem token, sem hover, sem erro.
53
+ *
54
+ * Com `mode: "template"` o preset NÃO o emite: lá quem acha as marcações é o
55
+ * scanner do `@tslite/template`, e a combinação seria contraditória (R14).
56
+ */
57
+ readonly segmenter?: SegmenterOption;
45
58
  /** Régua de linhas. Padrão: ligada no `"block"`, desligada no `"inline"`. */
46
59
  readonly gutters?: boolean;
47
60
  /** Busca e `Ctrl+D`. Padrão: ligadas no `"block"`, desligadas no `"inline"`. */
@@ -50,7 +63,7 @@ interface PresetOptions {
50
63
  readonly extensions?: readonly Extension[];
51
64
  }
52
65
  /** As props que o preset resolve — o resto (`value`, `onChange`, `env`) é seu. */
53
- type PresetProps = Pick<UseExpressionFieldOptions, "layout" | "mode" | "gutters" | "format" | "features" | "extensions">;
66
+ type PresetProps = Pick<UseExpressionFieldOptions, "layout" | "mode" | "segmenter" | "gutters" | "format" | "features" | "extensions">;
54
67
  /**
55
68
  * As props de um campo que já nasce certo.
56
69
  *
package/dist/full.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Extension } from '@codemirror/state';
2
- import { U as UseExpressionFieldOptions } from './useExpressionField-CmiOEqIK.js';
2
+ import { F as FieldLayout, S as SegmenterOption, U as UseExpressionFieldOptions } from './useExpressionField-RJzhO-r7.js';
3
3
  export { searchEditing } from '@tslite/codemirror/search';
4
4
  export { format, formatExpression } from '@tslite/format';
5
5
  export { tsliteTokenStyles } from '@tslite/editor';
@@ -23,10 +23,12 @@ interface PresetOptions {
23
23
  /**
24
24
  * Como o campo se apresenta. Padrão: `"inline"`.
25
25
  *
26
- * `"block"` é o campo EXPANDIDO (tipicamente num modal): ganha o `Tab` que
26
+ * `"grow"` é o campo de FORMULÁRIO que cresce com o conteúdo: `Enter` termina,
27
+ * `Shift+Enter` quebra, `Tab` navega; régua e busca ficam desligadas, como no
28
+ * `"inline"`. `"block"` é o campo EXPANDIDO (tipicamente num modal): ganha o `Tab` que
27
29
  * indenta, a quebra de linha e — por este preset — a régua de linhas.
28
30
  */
29
- readonly layout?: "inline" | "block";
31
+ readonly layout?: FieldLayout;
30
32
  /**
31
33
  * O que o código É. Padrão: `"expression"`.
32
34
  *
@@ -42,6 +44,17 @@ interface PresetOptions {
42
44
  * comportamento sem pedido. Quem quer, declara.
43
45
  */
44
46
  readonly mode?: "expression" | "program" | "template";
47
+ /**
48
+ * ONDE o código está. Padrão: `"mustache"` (texto com ilhas `{{ }}`). Um slot em
49
+ * que o campo inteiro é código (um predicado, um mapper) é `"whole"` — e sem o
50
+ * preset emiti-lo, quem esquecia de passá-lo depois do spread ficava com o
51
+ * `mustache` procurando `{{ }}` num predicado: o campo inteiro virava texto
52
+ * inerte, sem token, sem hover, sem erro.
53
+ *
54
+ * Com `mode: "template"` o preset NÃO o emite: lá quem acha as marcações é o
55
+ * scanner do `@tslite/template`, e a combinação seria contraditória (R14).
56
+ */
57
+ readonly segmenter?: SegmenterOption;
45
58
  /** Régua de linhas. Padrão: ligada no `"block"`, desligada no `"inline"`. */
46
59
  readonly gutters?: boolean;
47
60
  /** Busca e `Ctrl+D`. Padrão: ligadas no `"block"`, desligadas no `"inline"`. */
@@ -50,7 +63,7 @@ interface PresetOptions {
50
63
  readonly extensions?: readonly Extension[];
51
64
  }
52
65
  /** As props que o preset resolve — o resto (`value`, `onChange`, `env`) é seu. */
53
- type PresetProps = Pick<UseExpressionFieldOptions, "layout" | "mode" | "gutters" | "format" | "features" | "extensions">;
66
+ type PresetProps = Pick<UseExpressionFieldOptions, "layout" | "mode" | "segmenter" | "gutters" | "format" | "features" | "extensions">;
54
67
  /**
55
68
  * As props de um campo que já nasce certo.
56
69
  *
package/dist/full.js CHANGED
@@ -1 +1 @@
1
- import {searchEditing}from'@tslite/codemirror/search';export{searchEditing}from'@tslite/codemirror/search';import {format,formatExpression}from'@tslite/format';export{format,formatExpression}from'@tslite/format';import {tsliteTokenStyles}from'@tslite/editor';export{tsliteTokenStyles}from'@tslite/editor';function y(t={}){let{dark:s=true,layout:e="inline",mode:o="expression",gutters:n=e==="block",search:i=e==="block",extensions:r=[]}=t;return {layout:e,mode:o,gutters:n,format:o==="program"?format:formatExpression,features:{chrome:{dark:s},theme:tsliteTokenStyles},extensions:i?[searchEditing(),...r]:[...r]}}export{y as expressionFieldProps};
1
+ import {searchEditing}from'@tslite/codemirror/search';export{searchEditing}from'@tslite/codemirror/search';import {format,formatExpression}from'@tslite/format';export{format,formatExpression}from'@tslite/format';import {tsliteTokenStyles}from'@tslite/editor';export{tsliteTokenStyles}from'@tslite/editor';function u(t={}){let{dark:s=true,layout:e="inline",mode:o="expression",segmenter:n="mustache",gutters:i=e==="block",search:a=e==="block",extensions:r=[]}=t;return {layout:e,mode:o,...o==="template"?{}:{segmenter:n},gutters:i,format:o==="program"?format:formatExpression,features:{chrome:{dark:s},theme:tsliteTokenStyles},extensions:a?[searchEditing(),...r]:[...r]}}export{u as expressionFieldProps};
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: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;
1
+ 'use strict';var n=require('react'),state=require('@codemirror/state'),view=require('@codemirror/view'),commands=require('@codemirror/commands'),autocomplete=require('@codemirror/autocomplete'),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 n__namespace=/*#__PURE__*/_interopNamespace(n);var ae={mustache:languageService.mustache,whole:languageService.whole},ce=t=>typeof t=="function"?t:ae[t];function A(t){let{env:o,service:c,segmenter:i="mustache",mode:s="expression",profile:l,limits:d,unused:p,format:a}=t;return n__namespace.useMemo(()=>{if(c)return c;if(!o)return null;let m={env:o,...l?{profile:l}:{},...d?{limits:d}:{},...p!==void 0?{unused:p}:{},...a?{format:a}:{}};return s==="template"?editor.createHostService({...m,mode:s}):editor.createHostService({...m,segmenter:ce(i),mode:s})},[c,o,i,s,l,d,p,a])}var Oe=view.EditorView.theme({".cm-scroller":{overflowX:"auto",overflowY:"hidden"},".cm-content":{padding:"6px 8px"},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),z=6,Te=view.EditorView.theme({".cm-scroller":{overflowY:"auto"},".cm-content":{padding:`${z}px 8px`},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),Le=(t,o)=>`${o*t.defaultLineHeight+2*z}px`,we=view.EditorView.theme({"&":{height:"100%"},".cm-scroller":{overflowY:"auto"},".cm-content":{padding:"8px"},"&.cm-focused":{outline:"none"}}),$=t=>t.replace(/\r?\n/g," "),ke=(t,o)=>{if(t===false)return [];let c=o==="block"?{}:{tab:false,indentOnInput:false};return codemirror.codeEditing(typeof t=="object"?{...c,...t}:c)},Ce=t=>t?codemirror.gutters(typeof t=="object"?t:{}):[];function D(t){let{value:o,onChange:c,onCommit:i,layout:s="inline",maxLines:l,wrap:d=s!=="inline",editing:p,gutters:a,readOnly:m=false,placeholder:b,features:I,tooltipParent:L,onTokenAction:V,isTokenActionable:_,definition:w,extensions:ee}=t,h=A(t),k=n__namespace.useRef(null),y=n__namespace.useRef(null),[U,Y]=n__namespace.useState(null),[te,oe]=n__namespace.useState(false),R=n__namespace.useRef({value:o,onChange:c,onCommit:i,onTokenAction:V,isTokenActionable:_});R.current={value:o,onChange:c,onCommit:i,onTokenAction:V,isTokenActionable:_};let C=n__namespace.useCallback(e=>{let{value:r,onCommit:x}=R.current;if(!x)return;let f=e.state.doc.toString();f!==r&&x(f);},[]),u=n__namespace.useRef({service:new state.Compartment,layout:new state.Compartment,editable:new state.Compartment,actions:new state.Compartment}).current,H=n__namespace.useCallback(e=>e?codemirror.languageService(e,{theme:editor.tsliteTokenStyles,...L!==null?{tooltipParent:L??(typeof document<"u"?document.body:void 0)}:{},...I}):[],[I,L]),G=n__namespace.useCallback(e=>autocomplete.completionStatus(e.state)==="active"?autocomplete.acceptCompletion(e)||true:(C(e),true),[C]),P=n__namespace.useCallback((e,r,x,f)=>[e==="block"?[...r?[view.EditorView.lineWrapping]:[],we]:e==="grow"?[...r?[view.EditorView.lineWrapping]:[],Te,state.Prec.highest(view.keymap.of([{key:"Enter",run:G},{key:"Shift-Enter",run:commands.insertNewlineAndIndent}]))]:[codemirror.singleLine,Oe],ke(x,e),Ce(f)],[G]),M=n__namespace.useCallback(()=>{let e=[];return R.current.onTokenAction&&e.push(codemirror.tokenAction({actionable:r=>R.current.isTokenActionable?.(r)??true,onAction:r=>R.current.onTokenAction?.(r)})),w&&h?.definitionAt&&e.push(codemirror.gotoDefinition(w)),e},[w,h]);n__namespace.useEffect(()=>{if(!k.current)return;let e=new view.EditorView({parent:k.current,state:state.EditorState.create({doc:s==="inline"?$(o):o,extensions:[commands.history(),u.service.of(H(h)),u.layout.of(P(s,d,p,a)),u.editable.of(view.EditorView.editable.of(!m)),u.actions.of(M()),...b?[view.placeholder(b)]:[],view.keymap.of([...commands.historyKeymap,...commands.defaultKeymap]),view.EditorView.updateListener.of(r=>{if(r.focusChanged&&oe(r.view.hasFocus),!r.docChanged)return;r.transactions.some(f=>f.annotation(codemirror.externalChange))||R.current.onChange?.(r.state.doc.toString());}),view.EditorView.contentAttributes.of({"aria-label":b??"expression"}),view.EditorView.domEventHandlers({blur:(r,x)=>{let f=r.relatedTarget;return f instanceof Element&&(x.dom.contains(f)||f.closest(".cm-tooltip"))||C(x),false}}),...ee??[]]})});return y.current=e,Y(e),()=>{e.destroy(),y.current=null,Y(null);}},[]),n__namespace.useEffect(()=>{y.current?.dispatch({effects:u.service.reconfigure(H(h))});},[h,H,u]),n__namespace.useEffect(()=>{y.current?.dispatch({effects:u.layout.reconfigure(P(s,d,p,a))});},[s,d,p,a,P,u]),n__namespace.useEffect(()=>{y.current?.dispatch({effects:u.editable.reconfigure(view.EditorView.editable.of(!m))});},[m,u]),n__namespace.useEffect(()=>{let e=y.current;e&&(e.scrollDOM.style.maxHeight=s==="grow"&&l!==void 0&&l>0?Le(e,l):"");},[s,l,U]),n__namespace.useEffect(()=>{y.current?.dispatch({effects:u.actions.reconfigure(M())});},[M,u]),n__namespace.useEffect(()=>{let e=y.current;if(!e)return;let r=s==="inline"?$(o):o;if(r===e.state.doc.toString())return;let{anchor:x,head:f}=e.state.selection.main,N=re=>Math.min(re,r.length);e.dispatch({changes:{from:0,to:e.state.doc.length,insert:r},selection:{anchor:N(x),head:N(f)},annotations:codemirror.externalChange.of(true)});},[o,s]);let ne=n__namespace.useCallback(()=>y.current?.focus(),[]);return {ref:k,view:U,focused:te,service:h,focus:ne}}var X=n__namespace.createContext(null);function J(){let t=n__namespace.useContext(X);if(!t)throw new Error("useFieldContext must be used inside <ExpressionField.Root>");return t}var He=["value","onChange","onCommit","layout","maxLines","wrap","editing","gutters","readOnly","placeholder","features","tooltipParent","onTokenAction","isTokenActionable","definition","extensions","env","service","segmenter","mode","profile","limits","unused","format"];var Q=n__namespace.forwardRef(function(o,c){let{children:i,...s}=o,l={},d={};for(let[a,m]of Object.entries(s))(He.includes(a)?l:d)[a]=m;let p=D(l);return jsxRuntime.jsx(X.Provider,{value:p,children:jsxRuntime.jsx("div",{ref:c,...d,children:typeof i=="function"?i(p):i})})}),Z=n__namespace.forwardRef(function(o,c){let i=J();return jsxRuntime.jsx("div",{ref:i.ref,...o})}),q=n__namespace.forwardRef(function({children:o,...c},i){return jsxRuntime.jsx("button",{ref:i,type:"button",...c,children:o})}),S={Root:Q,Editor:Z,ExpandTrigger:q};var E={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)"},Pe=["--foreground","--muted-foreground","--border","--ring","--input","--destructive","--font-mono","--muted","--popover","--popover-foreground","--primary","--primary-foreground","--secondary","--accent"];var Me=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 Ae({invalid:t,className:o,style:c,onExpand:i,expandIcon:s,multiline:l,layout:d,...p}){let a=d??(l?"block":"inline");return jsxRuntime.jsx(S.Root,{...p,layout:a,className:o,children:m=>jsxRuntime.jsxs("div",{style:{position:"relative",border:`1px solid ${t?E.destructive:m.focused?E.ring:E.border}`,borderRadius:"6px",backgroundColor:E.input,color:E.fg,fontFamily:E.font,fontSize:"13px",overflow:"hidden",...a==="block"?{height:"100%",display:"flex",flexDirection:"column"}:{},...c},children:[jsxRuntime.jsx(S.Editor,{style:a==="block"?{flex:1,minHeight:0}:a==="grow"?{paddingRight:i?"28px":void 0}:{paddingRight:i?"24px":void 0}}),i&&jsxRuntime.jsx(S.ExpandTrigger,{onClick:i,"aria-label":"Expandir",title:"Expandir",onMouseEnter:b=>b.currentTarget.style.opacity="1",onMouseLeave:b=>b.currentTarget.style.opacity="0.55",style:{position:"absolute",top:a==="inline"?"50%":"6px",right:"4px",transform:a==="inline"?"translateY(-50%)":void 0,display:"flex",alignItems:"center",justifyContent:"center",width:"20px",height:"20px",padding:0,lineHeight:0,border:"none",borderRadius:"4px",background:E.input,color:E.mutedFg,cursor:"pointer",opacity:.55},children:s??Me})]})})}exports.CSS_VARS=Pe;exports.ExpressionField=S;exports.ExpressionFieldEditor=Z;exports.ExpressionFieldExpandTrigger=q;exports.ExpressionFieldRoot=Q;exports.ExpressionInput=Ae;exports.V=E;exports.useExpressionField=D;exports.useFieldContext=J;exports.useLanguageService=A;
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-CmiOEqIK.cjs';
3
- export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-CmiOEqIK.cjs';
2
+ import { U as UseExpressionFieldOptions, E as ExpressionFieldHandle } from './useExpressionField-RJzhO-r7.cjs';
3
+ export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-RJzhO-r7.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-CmiOEqIK.js';
3
- export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-CmiOEqIK.js';
2
+ import { U as UseExpressionFieldOptions, E as ExpressionFieldHandle } from './useExpressionField-RJzhO-r7.js';
3
+ export { F as FieldLayout, L as LanguageServiceOptions, S as SegmenterOption, u as useExpressionField, a as useLanguageService } from './useExpressionField-RJzhO-r7.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: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};
1
+ import*as n from'react';import {Compartment,Prec,EditorState}from'@codemirror/state';import {EditorView,keymap,placeholder}from'@codemirror/view';import {insertNewlineAndIndent,history,historyKeymap,defaultKeymap}from'@codemirror/commands';import {completionStatus,acceptCompletion}from'@codemirror/autocomplete';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 ae={mustache:mustache,whole:whole},ce=t=>typeof t=="function"?t:ae[t];function A(t){let{env:o,service:c,segmenter:i="mustache",mode:s="expression",profile:l,limits:d,unused:p,format:a}=t;return n.useMemo(()=>{if(c)return c;if(!o)return null;let m={env:o,...l?{profile:l}:{},...d?{limits:d}:{},...p!==void 0?{unused:p}:{},...a?{format:a}:{}};return s==="template"?createHostService({...m,mode:s}):createHostService({...m,segmenter:ce(i),mode:s})},[c,o,i,s,l,d,p,a])}var Oe=EditorView.theme({".cm-scroller":{overflowX:"auto",overflowY:"hidden"},".cm-content":{padding:"6px 8px"},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),z=6,Te=EditorView.theme({".cm-scroller":{overflowY:"auto"},".cm-content":{padding:`${z}px 8px`},".cm-line":{padding:"0"},"&.cm-focused":{outline:"none"}}),Le=(t,o)=>`${o*t.defaultLineHeight+2*z}px`,we=EditorView.theme({"&":{height:"100%"},".cm-scroller":{overflowY:"auto"},".cm-content":{padding:"8px"},"&.cm-focused":{outline:"none"}}),$=t=>t.replace(/\r?\n/g," "),ke=(t,o)=>{if(t===false)return [];let c=o==="block"?{}:{tab:false,indentOnInput:false};return codeEditing(typeof t=="object"?{...c,...t}:c)},Ce=t=>t?gutters(typeof t=="object"?t:{}):[];function D(t){let{value:o,onChange:c,onCommit:i,layout:s="inline",maxLines:l,wrap:d=s!=="inline",editing:p,gutters:a,readOnly:m=false,placeholder:b,features:I,tooltipParent:L,onTokenAction:V,isTokenActionable:_,definition:w,extensions:ee}=t,h=A(t),k=n.useRef(null),y=n.useRef(null),[U,Y]=n.useState(null),[te,oe]=n.useState(false),R=n.useRef({value:o,onChange:c,onCommit:i,onTokenAction:V,isTokenActionable:_});R.current={value:o,onChange:c,onCommit:i,onTokenAction:V,isTokenActionable:_};let C=n.useCallback(e=>{let{value:r,onCommit:x}=R.current;if(!x)return;let f=e.state.doc.toString();f!==r&&x(f);},[]),u=n.useRef({service:new Compartment,layout:new Compartment,editable:new Compartment,actions:new Compartment}).current,H=n.useCallback(e=>e?languageService(e,{theme:tsliteTokenStyles,...L!==null?{tooltipParent:L??(typeof document<"u"?document.body:void 0)}:{},...I}):[],[I,L]),G=n.useCallback(e=>completionStatus(e.state)==="active"?acceptCompletion(e)||true:(C(e),true),[C]),P=n.useCallback((e,r,x,f)=>[e==="block"?[...r?[EditorView.lineWrapping]:[],we]:e==="grow"?[...r?[EditorView.lineWrapping]:[],Te,Prec.highest(keymap.of([{key:"Enter",run:G},{key:"Shift-Enter",run:insertNewlineAndIndent}]))]:[singleLine,Oe],ke(x,e),Ce(f)],[G]),M=n.useCallback(()=>{let e=[];return R.current.onTokenAction&&e.push(tokenAction({actionable:r=>R.current.isTokenActionable?.(r)??true,onAction:r=>R.current.onTokenAction?.(r)})),w&&h?.definitionAt&&e.push(gotoDefinition(w)),e},[w,h]);n.useEffect(()=>{if(!k.current)return;let e=new EditorView({parent:k.current,state:EditorState.create({doc:s==="inline"?$(o):o,extensions:[history(),u.service.of(H(h)),u.layout.of(P(s,d,p,a)),u.editable.of(EditorView.editable.of(!m)),u.actions.of(M()),...b?[placeholder(b)]:[],keymap.of([...historyKeymap,...defaultKeymap]),EditorView.updateListener.of(r=>{if(r.focusChanged&&oe(r.view.hasFocus),!r.docChanged)return;r.transactions.some(f=>f.annotation(externalChange))||R.current.onChange?.(r.state.doc.toString());}),EditorView.contentAttributes.of({"aria-label":b??"expression"}),EditorView.domEventHandlers({blur:(r,x)=>{let f=r.relatedTarget;return f instanceof Element&&(x.dom.contains(f)||f.closest(".cm-tooltip"))||C(x),false}}),...ee??[]]})});return y.current=e,Y(e),()=>{e.destroy(),y.current=null,Y(null);}},[]),n.useEffect(()=>{y.current?.dispatch({effects:u.service.reconfigure(H(h))});},[h,H,u]),n.useEffect(()=>{y.current?.dispatch({effects:u.layout.reconfigure(P(s,d,p,a))});},[s,d,p,a,P,u]),n.useEffect(()=>{y.current?.dispatch({effects:u.editable.reconfigure(EditorView.editable.of(!m))});},[m,u]),n.useEffect(()=>{let e=y.current;e&&(e.scrollDOM.style.maxHeight=s==="grow"&&l!==void 0&&l>0?Le(e,l):"");},[s,l,U]),n.useEffect(()=>{y.current?.dispatch({effects:u.actions.reconfigure(M())});},[M,u]),n.useEffect(()=>{let e=y.current;if(!e)return;let r=s==="inline"?$(o):o;if(r===e.state.doc.toString())return;let{anchor:x,head:f}=e.state.selection.main,N=re=>Math.min(re,r.length);e.dispatch({changes:{from:0,to:e.state.doc.length,insert:r},selection:{anchor:N(x),head:N(f)},annotations:externalChange.of(true)});},[o,s]);let ne=n.useCallback(()=>y.current?.focus(),[]);return {ref:k,view:U,focused:te,service:h,focus:ne}}var X=n.createContext(null);function J(){let t=n.useContext(X);if(!t)throw new Error("useFieldContext must be used inside <ExpressionField.Root>");return t}var He=["value","onChange","onCommit","layout","maxLines","wrap","editing","gutters","readOnly","placeholder","features","tooltipParent","onTokenAction","isTokenActionable","definition","extensions","env","service","segmenter","mode","profile","limits","unused","format"];var Q=n.forwardRef(function(o,c){let{children:i,...s}=o,l={},d={};for(let[a,m]of Object.entries(s))(He.includes(a)?l:d)[a]=m;let p=D(l);return jsx(X.Provider,{value:p,children:jsx("div",{ref:c,...d,children:typeof i=="function"?i(p):i})})}),Z=n.forwardRef(function(o,c){let i=J();return jsx("div",{ref:i.ref,...o})}),q=n.forwardRef(function({children:o,...c},i){return jsx("button",{ref:i,type:"button",...c,children:o})}),S={Root:Q,Editor:Z,ExpandTrigger:q};var E={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)"},Pe=["--foreground","--muted-foreground","--border","--ring","--input","--destructive","--font-mono","--muted","--popover","--popover-foreground","--primary","--primary-foreground","--secondary","--accent"];var Me=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 Ae({invalid:t,className:o,style:c,onExpand:i,expandIcon:s,multiline:l,layout:d,...p}){let a=d??(l?"block":"inline");return jsx(S.Root,{...p,layout:a,className:o,children:m=>jsxs("div",{style:{position:"relative",border:`1px solid ${t?E.destructive:m.focused?E.ring:E.border}`,borderRadius:"6px",backgroundColor:E.input,color:E.fg,fontFamily:E.font,fontSize:"13px",overflow:"hidden",...a==="block"?{height:"100%",display:"flex",flexDirection:"column"}:{},...c},children:[jsx(S.Editor,{style:a==="block"?{flex:1,minHeight:0}:a==="grow"?{paddingRight:i?"28px":void 0}:{paddingRight:i?"24px":void 0}}),i&&jsx(S.ExpandTrigger,{onClick:i,"aria-label":"Expandir",title:"Expandir",onMouseEnter:b=>b.currentTarget.style.opacity="1",onMouseLeave:b=>b.currentTarget.style.opacity="0.55",style:{position:"absolute",top:a==="inline"?"50%":"6px",right:"4px",transform:a==="inline"?"translateY(-50%)":void 0,display:"flex",alignItems:"center",justifyContent:"center",width:"20px",height:"20px",padding:0,lineHeight:0,border:"none",borderRadius:"4px",background:E.input,color:E.mutedFg,cursor:"pointer",opacity:.55},children:s??Me})]})})}export{Pe as CSS_VARS,S as ExpressionField,Z as ExpressionFieldEditor,q as ExpressionFieldExpandTrigger,Q as ExpressionFieldRoot,Ae as ExpressionInput,E as V,D as useExpressionField,J as useFieldContext,A as useLanguageService};
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { Extension } from '@codemirror/state';
3
3
  import { EditorView } from '@codemirror/view';
4
4
  import { CodeEditingOptions, GuttersOptions, LanguageServiceOptions as LanguageServiceOptions$1, TokenActionTarget, GotoDefinitionOptions } from '@tslite/codemirror';
5
- import { LanguageService, Segmenter, Token } from '@tslite/language-service';
5
+ import { Segmenter, LanguageService, Token } from '@tslite/language-service';
6
6
  import { HostServiceOptions } from '@tslite/editor';
7
7
 
8
8
  /**
@@ -18,7 +18,7 @@ interface LanguageServiceOptions {
18
18
  /**
19
19
  * O ambiente de tipos — o shape dos dados no escopo das expressões.
20
20
  *
21
- * ⚠️ **Memoize-o.** Um objeto novo a cada render reconstrói o serviço e joga
21
+ * **Memoize-o.** Um objeto novo a cada render reconstrói o serviço e joga
22
22
  * fora o cache de análise. `useMemo` no seu lado resolve.
23
23
  */
24
24
  readonly env?: HostServiceOptions["env"];
@@ -77,19 +77,48 @@ declare function useLanguageService(options: LanguageServiceOptions): LanguageSe
77
77
  * Como o campo se APRESENTA — ortogonal ao que ele contém.
78
78
  *
79
79
  * - `"inline"` — uma linha, estilo input: sem quebra, rolagem horizontal;
80
- * - `"block"` — várias linhas, estilo editor: quebra de linha e rolagem vertical.
80
+ * - `"grow"` — um campo de formulário que cresce com o conteúdo (até `maxLines`,
81
+ * e depois rola por dentro): quebra de linha, `Tab` navega, `Enter` TERMINA
82
+ * (commit) e `Shift+Enter` quebra. Um valor com quebras é preservado;
83
+ * - `"block"` — várias linhas, estilo editor: quebra de linha e rolagem vertical,
84
+ * `Tab` indenta, `Enter` quebra.
81
85
  */
82
- type FieldLayout = "inline" | "block";
86
+ type FieldLayout = "inline" | "grow" | "block";
83
87
  interface UseExpressionFieldOptions extends LanguageServiceOptions {
84
88
  /** O texto do campo (controlado). */
85
89
  readonly value: string;
86
90
  /** Chamado a cada edição do USUÁRIO — nunca por sincronização externa. */
87
91
  readonly onChange?: (value: string) => void;
92
+ /**
93
+ * O autor TERMINOU: o foco saiu do campo, ou o `Enter` terminou (layout
94
+ * `"grow"`). Recebe o texto do editor, e só dispara quando ele difere do
95
+ * `value` recebido.
96
+ *
97
+ * É o par `onValueChange`/`onValueCommit` do Slider do Radix. Quem usa
98
+ * `onCommit` passa como `value` o valor COMMITADO do documento: o documento do
99
+ * CodeMirror é o rascunho, e não há estado a mais no consumidor — uma entrada
100
+ * de histórico por commit, não por tecla. Quando o valor muda por baixo (um
101
+ * undo do documento, uma edição vinda de outra superfície), a sincronização
102
+ * externa reassenta o editor. `onChange` continua como está; os dois convivem
103
+ * (um preview ao vivo e o commit no fim).
104
+ *
105
+ * O foco que vai para um tooltip do próprio campo (o dropdown, o "Quick Fix…")
106
+ * não é o autor terminando, e não commita.
107
+ */
108
+ readonly onCommit?: (text: string) => void;
88
109
  /** Como o campo se apresenta. Padrão: `"inline"`. */
89
110
  readonly layout?: FieldLayout;
90
111
  /**
91
- * Quebrar linha longa em vez de rolar na horizontal. Padrão: `true` no layout
92
- * `"block"`.
112
+ * O teto do layout `"grow"`, em LINHAS: até ele o campo cresce com o conteúdo;
113
+ * a partir dele, rola por dentro. Sem padrão — quanto espaço um campo pode
114
+ * ocupar é decisão do layout de quem monta a tela (é a regra do `maxRows` do
115
+ * MUI e do `field-sizing: content` do CSS: o campo cresce, e para onde o
116
+ * `max-height` de quem monta disser). Ignorado nos outros layouts.
117
+ */
118
+ readonly maxLines?: number;
119
+ /**
120
+ * Quebrar linha longa em vez de rolar na horizontal. Padrão: `true` nos
121
+ * layouts `"grow"` e `"block"`.
93
122
  *
94
123
  * É opção à parte do `layout` porque são decisões diferentes: um CAMPO de
95
124
  * várias linhas quer quebrar (o texto é o conteúdo); um editor de ARQUIVO
@@ -105,7 +134,7 @@ interface UseExpressionFieldOptions extends LanguageServiceOptions {
105
134
  * | layout | `Tab` | por quê |
106
135
  * | --- | --- | --- |
107
136
  * | `"block"` | indenta | é um editor: não há para onde o foco ir |
108
- * | `"inline"` | **navega** | num campo de formulário, roubar o `Tab` prende o teclado — o usuário não sai sem o mouse |
137
+ * | `"inline"` · `"grow"` | **navega** | num campo de formulário, roubar o `Tab` prende o teclado — o usuário não sai sem o mouse |
109
138
  *
110
139
  * Passe `false` para não instalar nada, ou um objeto para ajustar (ele é
111
140
  * mesclado sobre o padrão do layout).
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { Extension } from '@codemirror/state';
3
3
  import { EditorView } from '@codemirror/view';
4
4
  import { CodeEditingOptions, GuttersOptions, LanguageServiceOptions as LanguageServiceOptions$1, TokenActionTarget, GotoDefinitionOptions } from '@tslite/codemirror';
5
- import { LanguageService, Segmenter, Token } from '@tslite/language-service';
5
+ import { Segmenter, LanguageService, Token } from '@tslite/language-service';
6
6
  import { HostServiceOptions } from '@tslite/editor';
7
7
 
8
8
  /**
@@ -18,7 +18,7 @@ interface LanguageServiceOptions {
18
18
  /**
19
19
  * O ambiente de tipos — o shape dos dados no escopo das expressões.
20
20
  *
21
- * ⚠️ **Memoize-o.** Um objeto novo a cada render reconstrói o serviço e joga
21
+ * **Memoize-o.** Um objeto novo a cada render reconstrói o serviço e joga
22
22
  * fora o cache de análise. `useMemo` no seu lado resolve.
23
23
  */
24
24
  readonly env?: HostServiceOptions["env"];
@@ -77,19 +77,48 @@ declare function useLanguageService(options: LanguageServiceOptions): LanguageSe
77
77
  * Como o campo se APRESENTA — ortogonal ao que ele contém.
78
78
  *
79
79
  * - `"inline"` — uma linha, estilo input: sem quebra, rolagem horizontal;
80
- * - `"block"` — várias linhas, estilo editor: quebra de linha e rolagem vertical.
80
+ * - `"grow"` — um campo de formulário que cresce com o conteúdo (até `maxLines`,
81
+ * e depois rola por dentro): quebra de linha, `Tab` navega, `Enter` TERMINA
82
+ * (commit) e `Shift+Enter` quebra. Um valor com quebras é preservado;
83
+ * - `"block"` — várias linhas, estilo editor: quebra de linha e rolagem vertical,
84
+ * `Tab` indenta, `Enter` quebra.
81
85
  */
82
- type FieldLayout = "inline" | "block";
86
+ type FieldLayout = "inline" | "grow" | "block";
83
87
  interface UseExpressionFieldOptions extends LanguageServiceOptions {
84
88
  /** O texto do campo (controlado). */
85
89
  readonly value: string;
86
90
  /** Chamado a cada edição do USUÁRIO — nunca por sincronização externa. */
87
91
  readonly onChange?: (value: string) => void;
92
+ /**
93
+ * O autor TERMINOU: o foco saiu do campo, ou o `Enter` terminou (layout
94
+ * `"grow"`). Recebe o texto do editor, e só dispara quando ele difere do
95
+ * `value` recebido.
96
+ *
97
+ * É o par `onValueChange`/`onValueCommit` do Slider do Radix. Quem usa
98
+ * `onCommit` passa como `value` o valor COMMITADO do documento: o documento do
99
+ * CodeMirror é o rascunho, e não há estado a mais no consumidor — uma entrada
100
+ * de histórico por commit, não por tecla. Quando o valor muda por baixo (um
101
+ * undo do documento, uma edição vinda de outra superfície), a sincronização
102
+ * externa reassenta o editor. `onChange` continua como está; os dois convivem
103
+ * (um preview ao vivo e o commit no fim).
104
+ *
105
+ * O foco que vai para um tooltip do próprio campo (o dropdown, o "Quick Fix…")
106
+ * não é o autor terminando, e não commita.
107
+ */
108
+ readonly onCommit?: (text: string) => void;
88
109
  /** Como o campo se apresenta. Padrão: `"inline"`. */
89
110
  readonly layout?: FieldLayout;
90
111
  /**
91
- * Quebrar linha longa em vez de rolar na horizontal. Padrão: `true` no layout
92
- * `"block"`.
112
+ * O teto do layout `"grow"`, em LINHAS: até ele o campo cresce com o conteúdo;
113
+ * a partir dele, rola por dentro. Sem padrão — quanto espaço um campo pode
114
+ * ocupar é decisão do layout de quem monta a tela (é a regra do `maxRows` do
115
+ * MUI e do `field-sizing: content` do CSS: o campo cresce, e para onde o
116
+ * `max-height` de quem monta disser). Ignorado nos outros layouts.
117
+ */
118
+ readonly maxLines?: number;
119
+ /**
120
+ * Quebrar linha longa em vez de rolar na horizontal. Padrão: `true` nos
121
+ * layouts `"grow"` e `"block"`.
93
122
  *
94
123
  * É opção à parte do `layout` porque são decisões diferentes: um CAMPO de
95
124
  * várias linhas quer quebrar (o texto é o conteúdo); um editor de ARQUIVO
@@ -105,7 +134,7 @@ interface UseExpressionFieldOptions extends LanguageServiceOptions {
105
134
  * | layout | `Tab` | por quê |
106
135
  * | --- | --- | --- |
107
136
  * | `"block"` | indenta | é um editor: não há para onde o foco ir |
108
- * | `"inline"` | **navega** | num campo de formulário, roubar o `Tab` prende o teclado — o usuário não sai sem o mouse |
137
+ * | `"inline"` · `"grow"` | **navega** | num campo de formulário, roubar o `Tab` prende o teclado — o usuário não sai sem o mouse |
109
138
  *
110
139
  * Passe `false` para não instalar nada, ou um objeto para ajustar (ele é
111
140
  * mesclado sobre o padrão do layout).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tslite/react",
3
- "version": "0.2.12",
3
+ "version": "0.3.0",
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.3.1",
51
- "@tslite/editor": "0.6.8",
52
- "@tslite/format": "0.5.4",
53
- "@tslite/language-service": "0.3.0"
50
+ "@tslite/editor": "0.6.9",
51
+ "@tslite/format": "0.5.5",
52
+ "@tslite/codemirror": "0.3.2",
53
+ "@tslite/language-service": "0.4.0"
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.10.0"
79
+ "@tslite/checker": "0.11.0"
80
80
  },
81
81
  "peerDependenciesMeta": {
82
82
  "@codemirror/search": {