@bikdotai/bik-component-library 0.0.838-beta.5 → 0.0.838
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/cjs/components/WhatsAppTextEditor/WhatsAppTextEditor.js +23 -23
- package/dist/cjs/components/WhatsAppTextEditor/WhatsAppTextEditor.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/AiTextArea.js +1 -1
- package/dist/cjs/components/agent-builder/components/AiTextArea.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
- package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/cjs/components/bik-chatbot/components/ChatWindow.js +20 -20
- package/dist/cjs/components/bik-chatbot/components/ChatWindow.js.map +1 -1
- package/dist/cjs/components/input/ChipInput.js +1 -1
- package/dist/cjs/components/input/ChipInput.js.map +1 -1
- package/dist/cjs/components/input/Input-helper.js +1 -1
- package/dist/cjs/components/input/Input-helper.js.map +1 -1
- package/dist/cjs/components/input/Input.js +1 -1
- package/dist/cjs/components/input/Input.js.map +1 -1
- package/dist/cjs/components/plans/SubscriptionPlanSelector.js +5 -5
- package/dist/cjs/components/plans/SubscriptionPlanSelector.js.map +1 -1
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.utils.js +3 -3
- package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
- package/dist/cjs/editor/extensions/buildExtensions.js +2 -2
- package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/cjs/icons/Informational/General/HourglassFilled.js +2 -0
- package/dist/cjs/icons/Informational/General/HourglassFilled.js.map +1 -0
- package/dist/cjs/icons/index.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/WhatsAppTextEditor/WhatsAppTextEditor.js +143 -144
- package/dist/esm/components/WhatsAppTextEditor/WhatsAppTextEditor.js.map +1 -1
- package/dist/esm/components/agent-builder/components/AiTextArea.js +23 -24
- package/dist/esm/components/agent-builder/components/AiTextArea.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +30 -31
- package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
- package/dist/esm/components/bik-chatbot/components/ChatWindow.js +53 -54
- package/dist/esm/components/bik-chatbot/components/ChatWindow.js.map +1 -1
- package/dist/esm/components/input/ChipInput.js +40 -41
- package/dist/esm/components/input/ChipInput.js.map +1 -1
- package/dist/esm/components/input/Input-helper.d.ts +0 -7
- package/dist/esm/components/input/Input-helper.js +25 -16
- package/dist/esm/components/input/Input-helper.js.map +1 -1
- package/dist/esm/components/input/Input.js +58 -60
- package/dist/esm/components/input/Input.js.map +1 -1
- package/dist/esm/components/input/Input.model.d.ts +0 -1
- package/dist/esm/components/plans/SubscriptionPlanSelector.js +40 -42
- package/dist/esm/components/plans/SubscriptionPlanSelector.js.map +1 -1
- package/dist/esm/editor/BikEditor.js +118 -122
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.utils.d.ts +1 -1
- package/dist/esm/editor/BikEditor.utils.js +140 -141
- package/dist/esm/editor/BikEditor.utils.js.map +1 -1
- package/dist/esm/editor/extensions/buildExtensions.js +39 -49
- package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/esm/helpers/index.d.ts +0 -1
- package/dist/esm/icons/Informational/General/HourglassFilled.d.ts +7 -0
- package/dist/esm/icons/Informational/General/HourglassFilled.js +33 -0
- package/dist/esm/icons/Informational/General/HourglassFilled.js.map +1 -0
- package/dist/esm/icons/Informational/General/index.d.ts +1 -0
- package/dist/esm/icons/Media/Visual/index.d.ts +0 -2
- package/dist/esm/icons/index.d.ts +25 -25
- package/dist/esm/icons/index.js +416 -418
- package/dist/esm/icons/index.js.map +1 -1
- package/dist/esm/index.js +114 -123
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -2
- package/dist/cjs/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js +0 -2
- package/dist/cjs/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js.map +0 -1
- package/dist/cjs/helpers/sanitize.js +0 -2
- package/dist/cjs/helpers/sanitize.js.map +0 -1
- package/dist/cjs/icons/Media/Visual/FormkitNeutral.js +0 -2
- package/dist/cjs/icons/Media/Visual/FormkitNeutral.js.map +0 -1
- package/dist/cjs/icons/Media/Visual/FormkitSad.js +0 -2
- package/dist/cjs/icons/Media/Visual/FormkitSad.js.map +0 -1
- package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.d.ts +0 -13
- package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js +0 -64
- package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js.map +0 -1
- package/dist/esm/helpers/sanitize.d.ts +0 -26
- package/dist/esm/helpers/sanitize.js +0 -123
- package/dist/esm/helpers/sanitize.js.map +0 -1
- package/dist/esm/icons/Media/Visual/FormkitNeutral.js +0 -58
- package/dist/esm/icons/Media/Visual/FormkitNeutral.js.map +0 -1
- package/dist/esm/icons/Media/Visual/FormkitSad.js +0 -61
- package/dist/esm/icons/Media/Visual/FormkitSad.js.map +0 -1
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),Nt=require("../../assets/icons/check.svg.js"),Ft=require("../../assets/icons/chevronLeft.svg.js"),Bt=require("../../assets/icons/chevronRight.svg.js"),qt=require("../../assets/icons/cross.svg.js"),Ut=require("../../assets/icons/edit.svg.js"),Gt=require("../../assets/icons/info.svg.js"),zt=require("../../assets/icons/rewind.svg.js"),Wt=require("../../assets/icons/thumb-down-line.svg.js"),Xt=require("../../assets/icons/thumb-up-line.svg.js"),Yt=require("../../helpers/BaseWhatsappContentLang.helper.js"),r=require("react"),gt=require("styled-components"),s=require("../../constants/Theme.js"),te=require("../tooltips/Tooltip.js"),ye=require("../TypographyStyle.js"),q=require("./ai/actionRegistry.js"),ne=require("./ai/aiTag.js"),at=require("./ai/api.js"),U=require("./CustomEditor.styled.js"),c=require("./WhatsAppTextEditorHeader.js"),ht=a=>a&&typeof a=="object"&&"default"in a?a:{default:a},Jt=ht(r),f=ht(gt),_e="Character limit reached",lt=3e3,Vt=5,ut=3,dt=1200,Qt=1e3,Zt="Rephrase this WhatsApp utility template to improve clarity and readability while preserving variables, intent, and compliance.",pt=gt.keyframes`
|
|
2
2
|
0% { opacity: 0.55; }
|
|
3
3
|
50% { opacity: 1; }
|
|
4
4
|
100% { opacity: 0.55; }
|
|
5
|
-
`,
|
|
5
|
+
`,Kt=f.default.div`
|
|
6
6
|
padding: 14px 12px;
|
|
7
7
|
display: flex;
|
|
8
8
|
flex-direction: column;
|
|
9
9
|
gap: 10px;
|
|
10
10
|
min-height: 150px;
|
|
11
|
-
`,j=
|
|
11
|
+
`,j=f.default.div`
|
|
12
12
|
height: 16px;
|
|
13
13
|
border-radius: 6px;
|
|
14
14
|
width: ${a=>a.width};
|
|
15
15
|
background: #ececef;
|
|
16
|
-
animation: ${
|
|
17
|
-
`,
|
|
16
|
+
animation: ${pt} 1.1s ease-in-out infinite;
|
|
17
|
+
`,en=f.default.div`
|
|
18
18
|
padding: 12px;
|
|
19
19
|
display: flex;
|
|
20
20
|
flex-direction: column;
|
|
@@ -33,25 +33,25 @@
|
|
|
33
33
|
::-webkit-scrollbar-track {
|
|
34
34
|
background: transparent;
|
|
35
35
|
}
|
|
36
|
-
`,
|
|
36
|
+
`,tn=f.default.div`
|
|
37
37
|
text-decoration: line-through;
|
|
38
38
|
color: ${s.COLORS.content.secondary};
|
|
39
|
-
`,ft=
|
|
39
|
+
`,ft=f.default.div`
|
|
40
40
|
color: ${s.COLORS.content.primary};
|
|
41
|
-
`,
|
|
41
|
+
`,nn=f.default.div`
|
|
42
42
|
display: flex;
|
|
43
43
|
flex-direction: column;
|
|
44
44
|
gap: 8px;
|
|
45
45
|
width: 100%;
|
|
46
46
|
min-height: 40px;
|
|
47
|
-
`,
|
|
47
|
+
`,rn=f.default.div`
|
|
48
48
|
display: flex;
|
|
49
49
|
align-items: center;
|
|
50
50
|
gap: 6px;
|
|
51
|
-
`,
|
|
51
|
+
`,sn=f.default.span`
|
|
52
52
|
color: ${s.COLORS.content.primary};
|
|
53
53
|
font-size: 14px;
|
|
54
|
-
`,H=
|
|
54
|
+
`,H=f.default.button`
|
|
55
55
|
border: 0;
|
|
56
56
|
background: transparent;
|
|
57
57
|
padding: 6px;
|
|
@@ -69,19 +69,19 @@
|
|
|
69
69
|
opacity: 0.35;
|
|
70
70
|
cursor: not-allowed;
|
|
71
71
|
}
|
|
72
|
-
`,
|
|
72
|
+
`,on=f.default(H)`
|
|
73
73
|
:disabled {
|
|
74
74
|
opacity: 1;
|
|
75
75
|
cursor: wait;
|
|
76
76
|
}
|
|
77
|
-
`,
|
|
77
|
+
`,cn=f.default.div`
|
|
78
78
|
width: 14px;
|
|
79
79
|
height: 14px;
|
|
80
80
|
border-radius: 4px;
|
|
81
81
|
background: #ececef;
|
|
82
82
|
flex-shrink: 0;
|
|
83
|
-
animation: ${
|
|
84
|
-
`,
|
|
83
|
+
animation: ${pt} 1.1s ease-in-out infinite;
|
|
84
|
+
`,an=f.default.div`
|
|
85
85
|
background: ${s.COLORS.surface.standard};
|
|
86
86
|
display: flex;
|
|
87
87
|
flex-direction: column;
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
gap: 10px;
|
|
90
90
|
border-radius: 0 0 4px 4px;
|
|
91
91
|
position: relative;
|
|
92
|
-
`,
|
|
92
|
+
`,ln=f.default.div`
|
|
93
93
|
border: 1px solid #f5a4c0;
|
|
94
94
|
border-radius: 10px;
|
|
95
95
|
padding: 8px 10px;
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
align-items: center;
|
|
98
98
|
gap: 10px;
|
|
99
99
|
background: ${s.COLORS.surface.standard};
|
|
100
|
-
`,
|
|
100
|
+
`,un=f.default.input`
|
|
101
101
|
flex: 1;
|
|
102
102
|
min-width: 0;
|
|
103
103
|
border: 0;
|
|
@@ -105,11 +105,11 @@
|
|
|
105
105
|
font-size: 14px;
|
|
106
106
|
background: transparent;
|
|
107
107
|
color: ${s.COLORS.content.primary};
|
|
108
|
-
`,
|
|
108
|
+
`,dn=f.default.div`
|
|
109
109
|
display: flex;
|
|
110
110
|
align-items: center;
|
|
111
111
|
gap: 10px;
|
|
112
|
-
`,fn=
|
|
112
|
+
`,fn=f.default.button`
|
|
113
113
|
border: 0;
|
|
114
114
|
background: transparent;
|
|
115
115
|
color: ${s.COLORS.content.secondary};
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
font-weight: 500;
|
|
118
118
|
padding: 0;
|
|
119
119
|
cursor: pointer;
|
|
120
|
-
`,
|
|
120
|
+
`,gn=f.default.button`
|
|
121
121
|
border: 1px solid #5d3a72;
|
|
122
122
|
color: #5d3a72;
|
|
123
123
|
background: ${s.COLORS.surface.standard};
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
line-height: 1.1;
|
|
128
128
|
font-weight: 600;
|
|
129
129
|
cursor: pointer;
|
|
130
|
-
`,
|
|
130
|
+
`,hn=f.default.div`
|
|
131
131
|
margin-top: 4px;
|
|
132
132
|
border-radius: 12px;
|
|
133
133
|
width: 331px;
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
display: flex;
|
|
139
139
|
flex-direction: column;
|
|
140
140
|
gap: 2px;
|
|
141
|
-
`,
|
|
141
|
+
`,pn=f.default.button`
|
|
142
142
|
width: 100%;
|
|
143
143
|
border: 0;
|
|
144
144
|
border-radius: 8px;
|
|
@@ -152,5 +152,5 @@
|
|
|
152
152
|
:hover {
|
|
153
153
|
background: ${a=>a.selected?"#d9e8db":s.COLORS.surface.subdued};
|
|
154
154
|
}
|
|
155
|
-
`,v=new Jt.BaseWhatsappContentLangHelper,bn={[c.EditorActionTypes.BOLD]:"*",[c.EditorActionTypes.ITALIC]:"_",[c.EditorActionTypes.STRIKETHROUGH]:"~"};function mn(a){return`whatsapp-editor-rephrase-highlight-${a||"default"}`}const bt=Vt.default.forwardRef(({onChange:a,onClickVariable:Rn,text:P,RightComponent:mt,error:I,limit:M,onError:D,rows:Rt,actions:St,editorInstanceKey:A,editorSessionId:re,templateType:L="marketing",templateId:R,requestExecutor:fe,baseUrl:he,endpointPath:Oe,useCase:Ie,storeId:Le,apiAdapter:pe,conversationId:ke="whatsapp-template-editor",systemId:we="whatsapp-writer",intent:je="default",enabledAIActions:ve=[c.AIEditorActionTypes.REPHRASE,c.AIEditorActionTypes.SHORTEN,c.AIEditorActionTypes.EXPAND,c.AIEditorActionTypes.EMOJIFY],disableBuiltInAIActions:He=!1,promptOverrides:Pe,rephraseTones:Me,aiActionMinChars:De,instructionSuggestions:$e=B.DEFAULT_INSTRUCTION_SUGGESTIONS,onAnalyticsEvent:Ne,onAITagComputed:ie,prefillWasAiGenerated:C=!1,editorHeader:Fe,onAIToneSelect:At,onAIActionRequest:se,onBuildAIPrompt:qe,onBlur:Et,...Ct},Tt)=>{const f=r.useRef(null),[o,yt]=r.useState(P||""),[Be,z]=r.useState(!1),[xe,Ue]=r.useState(0),[l,ze]=r.useState(!1),[Ge,be]=r.useState(!1),[T,oe]=r.useState(""),[ce,_t]=r.useState({}),[m,We]=r.useState(null),[p,me]=r.useState([]),[y,G]=r.useState(0),[u,Xe]=r.useState(null),Ye=r.useRef(null),h=r.useRef(null),W=r.useRef(null),E=r.useRef(null),X=r.useRef(null),Y=r.useRef(null),Je=r.useRef(null),Re=r.useRef(!!C),ae=r.useRef(null),J=r.useRef(""),le=r.useRef(!1),[Se,Ve]=r.useState({}),Ot=r.useRef(`mount-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`),V=r.useMemo(()=>mn(`${A||"default"}-${re||Ot.current}`),[A,re]);r.useEffect(()=>{Re.current=!!C},[C,A]),r.useEffect(()=>{le.current=!1,J.current=""},[A,re]),r.useEffect(()=>{if(!C){le.current=!1,J.current="";return}if(le.current)return;const e=P??"";e.length>0&&(J.current=e,le.current=!0)},[C,P,A,re]);const ue=r.useMemo(()=>B.resolveActionPrompts(L,Pe,Me),[Pe,Me,L]),Qe=r.useMemo(()=>{const e=T.trim().toLowerCase();return e?$e.filter(t=>t.toLowerCase().includes(e)):[]},[$e,T]),Q=r.useMemo(()=>({...B.DEFAULT_AI_ACTION_MIN_CHARS,...De||{}}),[De]),Ze=Q[c.AIEditorActionTypes.REPHRASE]||B.DEFAULT_AI_ACTION_MIN_CHARS[c.AIEditorActionTypes.REPHRASE],It=r.useCallback(e=>{const t=e.trim().replace(/\s+/g," ");if(!t)return"";const i=t.split(" ").length;return`[anonymized:length_${t.length}:words_${i}]`},[]),S=r.useCallback((e,t)=>{Ne?.(e,t)},[Ne]),_=r.useCallback(e=>{yt(t=>t===e?t:e)},[]),k=r.useCallback(e=>{if(Y.current&&clearTimeout(Y.current),e.length>gt){a?.(e,e),Y.current=setTimeout(()=>{a?.(e,v.getHTML(e))},16);return}a?.(e,v.getHTML(e))},[a]),Ke=r.useCallback(e=>{const i=ae.current?.acceptedText||(C?J.current:"");if(!i||e===i)return;const d=ne.computeAiTagOnPostEdit({acceptedAiText:i,currentEditedText:e});ie?.({...d,source:"post_edit_debounce"})},[ie,C]),Z=r.useCallback(()=>{We(null),me([]),G(0),Xe(null),Ve({})},[]),et=r.useCallback(()=>{if(l||m&&p.length>0||xe>=Qt)return;const e=xe+1;Ue(e),typeof window<"u"&&A&&sessionStorage.setItem(V,String(e)),z(!0),W.current&&clearTimeout(W.current),W.current=setTimeout(()=>{z(!1)},1200)},[A,V,l,m,p,xe]),de=r.useRef(et);de.current=et;function Lt(e){const t=at.stripHtmlTags(e.target.value),i=ae.current;i&&!i.editedEventEmitted&&t!==i.acceptedText&&(ae.current={...i,editedEventEmitted:!0},S("ai_suggestion_edited",{action_type:i.actionType,template_id:R})),E.current&&(clearTimeout(E.current),E.current=null);const d=i?.acceptedText||(C?J.current:"");d&&t!==d&&(E.current=setTimeout(()=>{Ke(t)},Zt)),_(t),k(t)}function tt(e){const t=f?.current;t!=null&&(t.selectionStart?(t.focus(),t.selectionEnd=e):t.focus())}function kt(e){const t=bn[e];if(t&&f.current){const i=f.current.selectionStart,d=f.current.selectionEnd;if(i===d){const{text:b}=nt(t,i);tt(i+1),k(b)}else{const{text:b}=Ae(t);k(b)}}}function wt(e){const{text:t}=ge(e);k(t)}function Ae(e){let t=f.current?.value??"";if(f.current&&e){const i=f.current.selectionStart,d=f.current.selectionEnd,b=e;if(i===d)return ge(b);{t=v.wrappWildcard(i,d,b,t);const N=v.getHTML(t);return _(t),{text:t,html:N}}}return{text:t,html:t}}function ge(e){const t=f.current?.value??"";if(f.current&&e){const i=f.current.selectionStart,d=f.current.selectionEnd;if(i===d)return nt(e,i)}return{text:t,html:t}}function nt(e,t){let i=f.current?.value??"";i=i.slice(0,t)+e+i.slice(t);const d=v.getHTML(i);return _(i),{text:i,html:d}}r.useEffect(()=>{if(typeof window>"u"||!A)return;const e=Number(sessionStorage.getItem(V)||"0");return Number.isNaN(e)||Ue(e),()=>{sessionStorage.removeItem(V)}},[A,V]),r.useEffect(()=>{if(l){z(!1),h.current&&(clearTimeout(h.current),h.current=null);return}if(m&&p.length>0){z(!1),h.current&&(clearTimeout(h.current),h.current=null);return}const e=!!o.trim()&&o.length>=Ze;if(X.current===null){X.current=e,e&&(h.current=setTimeout(()=>{de.current()},ut));return}if(!e){X.current=!1,z(!1),h.current&&(clearTimeout(h.current),h.current=null);return}const t=!X.current&&e;X.current=!0,t&&de.current(),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{de.current()},ut)},[o,l,Ze,m,p]),r.useEffect(()=>()=>{h.current&&clearTimeout(h.current),W.current&&clearTimeout(W.current),Y.current&&clearTimeout(Y.current),E.current&&clearTimeout(E.current)},[]);const x=p[y]||"",$=r.useMemo(()=>!u||!x?null:`${u}-${y}-${x}`,[x,u,y]),rt=!!($&&Se[$]),jt=r.useMemo(()=>v.getHTML(m||""),[m]),vt=r.useMemo(()=>v.getHTML(x),[x]),Ee=p.length<dt,O=!!m&&p.length>0,Ht=p.length<=1||y<=0,Pt=p.length<=1||y>=p.length-1;r.useEffect(()=>{if(!O)return;const e=Ye.current;e&&(e.scrollTop=e.scrollHeight)},[x,O,l]);const K=r.useCallback(async(e,t=!1,i,d,b=c.AIActionVariant.DEFAULT)=>{if(!se&&!pe&&(!fe||!he)){D?.("AI configuration missing");return}if(!o.trim())return;const N=Q[e]||B.DEFAULT_AI_ACTION_MIN_CHARS[e]||50;if(o.length<N||l||t&&!Ee)return;const ee=ue[e],F=e===c.AIEditorActionTypes.REPHRASE&&L==="utility"&&b===c.AIActionVariant.REPHRASE?{...ee,label:"Rephrase",basePrompt:Kt}:ee,w=d||ce[e],st=F.tones?.find(q=>q.id===w),Ce=i!==void 0?i:T,ot=qe?.({actionType:e,actionVariant:b,currentText:o,templateType:L,config:F,toneId:w,toneLabel:st?.label,instructionText:Ce||void 0})||lt.buildActionPrompt({config:F,currentText:o,selectedToneId:w,instructionText:Ce});ze(!0),S("ai_action_triggered",{action_type:e,template_id:R,template_category:L});try{const q=se?await se({actionType:e,actionVariant:b,currentText:o,templateType:L,toneId:w,toneLabel:st?.label,instructionText:Ce||void 0,prompt:ot}):await lt.requestAISuggestion({apiAdapter:pe,requestExecutor:fe,baseUrl:he,endpointPath:Oe,prompt:ot,intent:je,conversationId:ke,systemId:we,useCase:Ie,storeId:Le}),Te=typeof q=="string"?q.trim():(q?.body||"").trim();if(!Te)return;if(!t){We(o),Xe(e),me([Te]),G(0);return}me(Nt=>{const ct=[...Nt,Te].slice(0,dt);return G(ct.length-1),ct})}catch{D?.("Failed to generate AI suggestion")}finally{ze(!1)}},[fe,he,o,l,Ee,ue,ce,T,S,R,Oe,pe,je,ke,we,Ie,Le,L,D,Q,se,qe]),Mt=r.useCallback(()=>{if(!x||!m||!u)return;_(x),k(x),S("ai_suggestion_accepted",{action_type:u,template_id:R}),ae.current={acceptedText:x,baselineText:m,actionType:u,editedEventEmitted:!1};const e=Re.current,t=ne.computeAiTagOnAccept({baselineText:m,acceptedText:x,initialAiPrefillPhase:e});e&&(Re.current=!1),ie?.({...t,source:"accept"}),Z()},[x,m,u,_,k,S,R,ie,Z]),Dt=r.useCallback(()=>{u&&(S("ai_suggestion_discarded",{action_type:u,template_id:R}),Z())},[Z,S,u,R]),it=r.useCallback(e=>{!u||!$||Se[$]||(Ve(t=>({...t,[$]:e})),S("ai_feedback_submitted",{action_type:u,template_id:R,rating:e,candidate_index:y+1}))},[$,S,Se,u,y,R]),$t=r.useMemo(()=>He?[]:ve.map(e=>{const t=ue[e],i=ce[e];return{type:e,label:t.label,isPrimary:e===c.AIEditorActionTypes.REPHRASE,loading:l&&u===e,highlighted:e===c.AIEditorActionTypes.REPHRASE&&Be,disabled:!o.trim()||o.length<(Q[e]||B.DEFAULT_AI_ACTION_MIN_CHARS[e]||50)||l||O&&u===e,showToneDropdown:e===c.AIEditorActionTypes.REPHRASE&&!!t.tones?.length,tones:t.tones,selectedToneId:i}}),[ve,He,ue,ce,l,u,O,Be,o,Q]);return r.useImperativeHandle(Tt,()=>({addTextOrWrap:Ae,addText:ge,get(){return o},setCaretPosition:tt}),[Ae,ge,o]),r.useEffect(()=>{P!==void 0&&_(P||"")},[P,_]),r.useEffect(()=>{if(!M||!D)return;const e=o.length>M?_e:I??"";Je.current!==e&&(Je.current=e,D(e))},[o,I,M,D]),n.jsxs(U.OuterContainer,{children:[n.jsxs(U.EditorFooterRow,{children:[n.jsx(U.EditorFooterTitle,{children:Fe?n.jsx(ye.TitleSmall,{"data-test":"body-text-for-edit-template",children:Fe}):null}),n.jsxs(U.EditorFooterRight,{children:[I&&I!==_e?n.jsxs(n.Fragment,{children:[n.jsx(Gt.default,{width:16,height:16,color:s.COLORS.content.negative}),n.jsx(ye.BodyCaption,{color:s.COLORS.content.negative,children:I})]}):null,M?n.jsxs(ye.BodyCaption,{style:{color:I===_e||o.length>M?s.COLORS.content.negative:s.COLORS.content.secondary},children:[o.length,"/",M]}):null]})]}),n.jsxs(U.Container,{isError:!!I,children:[O?n.jsxs(tn,{ref:Ye,children:[n.jsx(nn,{dangerouslySetInnerHTML:{__html:jt}}),l?n.jsx(ft,{"aria-busy":"true",children:n.jsxs(rn,{children:[n.jsx(j,{width:"96%"}),n.jsx(j,{width:"84%"}),n.jsx(j,{width:"68%"})]})}):n.jsx(ft,{dangerouslySetInnerHTML:{__html:vt}}),n.jsxs(sn,{children:[n.jsx(H,{"aria-label":"Previous suggestion",type:"button",disabled:Ht,onClick:()=>G(e=>Math.max(0,e-1)),children:n.jsx(qt.default,{width:14,height:14,color:s.COLORS.content.secondary})}),n.jsxs(on,{children:[y+1,"/",p.length]}),n.jsx(H,{"aria-label":"Next suggestion",type:"button",disabled:Pt,onClick:()=>G(e=>Math.min(p.length-1,e+1)),children:n.jsx(Bt.default,{width:14,height:14,color:s.COLORS.content.secondary})}),n.jsx(te.Tooltip,{body:"Like",placement:"top",children:n.jsx(H,{"aria-label":"Like suggestion",type:"button",disabled:rt,onClick:()=>it("like"),children:n.jsx(Yt.default,{width:14,height:14,color:s.COLORS.content.secondary})})}),n.jsx(te.Tooltip,{body:"Dislike",placement:"top",children:n.jsx(H,{"aria-label":"Dislike suggestion",type:"button",disabled:rt,onClick:()=>it("dislike"),children:n.jsx(Xt.default,{width:14,height:14,color:s.COLORS.content.secondary})})}),Ee?n.jsx(te.Tooltip,{body:l?"Regenerating…":"Regenerate",placement:"top",children:n.jsx(cn,{"aria-label":"Regenerate suggestion","aria-busy":l,type:"button",disabled:l,onClick:()=>{u&&K(u,!0)},children:l?n.jsx(an,{"aria-hidden":!0}):n.jsx(Wt.default,{width:14,height:14})})}):null,n.jsx(te.Tooltip,{body:"Discard",placement:"top",children:n.jsx(H,{"aria-label":"Discard suggestion",type:"button",onClick:Dt,children:n.jsx(Ut.default,{width:14,height:14,color:s.COLORS.content.secondary})})}),n.jsx(te.Tooltip,{body:"Accept",placement:"top",children:n.jsx(H,{"aria-label":"Accept suggestion",type:"button",onClick:Mt,children:n.jsx(Ft.default,{width:14,height:14,color:s.COLORS.content.secondary})})})]})]}):l?n.jsxs(en,{children:[n.jsx(j,{width:"96%"}),n.jsx(j,{width:"92%"}),n.jsx(j,{width:"88%"}),n.jsx(j,{width:"54%"})]}):n.jsx(U.TextSpace,{ref:f,...Ct,value:o,onChange:Lt,onBlur:e=>{E.current&&(clearTimeout(E.current),E.current=null),Ke(e.target.value),Et?.(e)},onPaste:e=>{const t=e.clipboardData.getData("text");if(t.length>gt){e.preventDefault();const i=f.current,d=i?.selectionStart??0,b=i?.selectionEnd??d,N=i?.value??o,ee=N.slice(0,d)+t+N.slice(b);_(ee),k(ee);const F=d+t.length;requestAnimationFrame(()=>{const w=f.current;if(w)try{w.setSelectionRange(F,F)}catch{}})}},rows:Rt}),Ge?n.jsxs(ln,{children:[n.jsxs(un,{children:[n.jsx(zt.default,{width:18,height:18,color:s.COLORS.content.secondary}),n.jsx(dn,{value:T,placeholder:"Add specific instructions to refine your message",onChange:e=>oe(at.stripHtmlTags(e.target.value))}),n.jsxs(gn,{children:[n.jsx(fn,{type:"button",onClick:()=>{oe(""),be(!1)},children:"Cancel"}),n.jsx(hn,{type:"button",onClick:()=>{const e=T.trim();e&&S("ai_instruction_used",{action_type:c.AIEditorActionTypes.REPHRASE,template_id:R,instruction_text:It(e)}),be(!1),oe(""),K(c.AIEditorActionTypes.REPHRASE,!1,e)},children:"Improve"})]})]}),T.trim().length>0&&Qe.length>0?n.jsx(pn,{children:Qe.map(e=>n.jsx(xn,{type:"button",selected:T===e,onClick:()=>oe(e),children:e},e))}):null]}):n.jsx(c.WhatsAppTextEditorHeader,{actions:St,ref:f,onActionSelect:kt,RightComponent:mt,rightActionsDisabled:O||l,onEmojiClick:wt,aiActions:$t,disableAllActions:O||l,instructionActive:Ge,onAIInstructionsClick:()=>be(!0),onAIToneChange:(e,t)=>{_t(i=>({...i,[e]:t})),At?.(e,t),e===c.AIEditorActionTypes.REPHRASE&&K(e,!1,void 0,t,c.AIActionVariant.DEFAULT)},onAIActionClick:(e,t=c.AIActionVariant.DEFAULT)=>{if(!l){if(O){if(u===e)return;Z(),K(e,!1,void 0,void 0,t);return}K(e,!1,void 0,void 0,t)}}})]})]})});bt.displayName="WhatsAppTextEditor";exports.AI_TAG_CHANGE_RATIO_THRESHOLD=ne.AI_TAG_CHANGE_RATIO_THRESHOLD;exports.computeAiTagOnAccept=ne.computeAiTagOnAccept;exports.levenshteinDistance=ne.levenshteinDistance;exports.WhatsAppTextEditor=bt;
|
|
155
|
+
`,v=new Yt.BaseWhatsappContentLangHelper,xn={[c.EditorActionTypes.BOLD]:"*",[c.EditorActionTypes.ITALIC]:"_",[c.EditorActionTypes.STRIKETHROUGH]:"~"};function bn(a){return`whatsapp-editor-rephrase-highlight-${a||"default"}`}const xt=Jt.default.forwardRef(({onChange:a,onClickVariable:Rn,text:P,RightComponent:bt,error:I,limit:M,onError:D,rows:Rt,actions:St,editorInstanceKey:A,editorSessionId:re,templateType:L="marketing",templateId:S,requestExecutor:ge,baseUrl:he,endpointPath:Oe,useCase:Ie,storeId:Le,apiAdapter:pe,conversationId:ke="whatsapp-template-editor",systemId:we="whatsapp-writer",intent:je="default",enabledAIActions:ve=[c.AIEditorActionTypes.REPHRASE,c.AIEditorActionTypes.SHORTEN,c.AIEditorActionTypes.EXPAND,c.AIEditorActionTypes.EMOJIFY],disableBuiltInAIActions:He=!1,promptOverrides:Pe,rephraseTones:Me,aiActionMinChars:De,instructionSuggestions:$e=q.DEFAULT_INSTRUCTION_SUGGESTIONS,onAnalyticsEvent:Ne,onAITagComputed:ie,prefillWasAiGenerated:C=!1,editorHeader:Fe,onAIToneSelect:mt,onAIActionRequest:se,onBuildAIPrompt:Be,onBlur:At,...Et},Ct)=>{const g=r.useRef(null),[o,Tt]=r.useState(P||""),[qe,G]=r.useState(!1),[xe,Ue]=r.useState(0),[l,Ge]=r.useState(!1),[ze,be]=r.useState(!1),[T,oe]=r.useState(""),[ce,yt]=r.useState({}),[R,We]=r.useState(null),[p,Re]=r.useState([]),[y,z]=r.useState(0),[u,Xe]=r.useState(null),Ye=r.useRef(null),h=r.useRef(null),W=r.useRef(null),E=r.useRef(null),X=r.useRef(null),Y=r.useRef(null),Je=r.useRef(null),Se=r.useRef(!!C),ae=r.useRef(null),J=r.useRef(""),le=r.useRef(!1),[me,Ve]=r.useState({}),_t=r.useRef(`mount-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`),V=r.useMemo(()=>bn(`${A||"default"}-${re||_t.current}`),[A,re]);r.useEffect(()=>{Se.current=!!C},[C,A]),r.useEffect(()=>{le.current=!1,J.current=""},[A,re]),r.useEffect(()=>{if(!C){le.current=!1,J.current="";return}if(le.current)return;const e=P??"";e.length>0&&(J.current=e,le.current=!0)},[C,P,A,re]);const ue=r.useMemo(()=>q.resolveActionPrompts(L,Pe,Me),[Pe,Me,L]),Qe=r.useMemo(()=>{const e=T.trim().toLowerCase();return e?$e.filter(t=>t.toLowerCase().includes(e)):[]},[$e,T]),Q=r.useMemo(()=>({...q.DEFAULT_AI_ACTION_MIN_CHARS,...De||{}}),[De]),Ze=Q[c.AIEditorActionTypes.REPHRASE]||q.DEFAULT_AI_ACTION_MIN_CHARS[c.AIEditorActionTypes.REPHRASE],Ot=r.useCallback(e=>{const t=e.trim().replace(/\s+/g," ");if(!t)return"";const i=t.split(" ").length;return`[anonymized:length_${t.length}:words_${i}]`},[]),m=r.useCallback((e,t)=>{Ne?.(e,t)},[Ne]),_=r.useCallback(e=>{Tt(t=>t===e?t:e)},[]),k=r.useCallback(e=>{if(Y.current&&clearTimeout(Y.current),e.length>dt){a?.(e,e),Y.current=setTimeout(()=>{a?.(e,v.getHTML(e))},16);return}a?.(e,v.getHTML(e))},[a]),Ke=r.useCallback(e=>{const i=ae.current?.acceptedText||(C?J.current:"");if(!i||e===i)return;const d=ne.computeAiTagOnPostEdit({acceptedAiText:i,currentEditedText:e});ie?.({...d,source:"post_edit_debounce"})},[ie,C]),Z=r.useCallback(()=>{We(null),Re([]),z(0),Xe(null),Ve({})},[]),et=r.useCallback(()=>{if(l||R&&p.length>0||xe>=Vt)return;const e=xe+1;Ue(e),typeof window<"u"&&A&&sessionStorage.setItem(V,String(e)),G(!0),W.current&&clearTimeout(W.current),W.current=setTimeout(()=>{G(!1)},1200)},[A,V,l,R,p,xe]),de=r.useRef(et);de.current=et;function It(e){const t=e.target.value,i=ae.current;i&&!i.editedEventEmitted&&t!==i.acceptedText&&(ae.current={...i,editedEventEmitted:!0},m("ai_suggestion_edited",{action_type:i.actionType,template_id:S})),E.current&&(clearTimeout(E.current),E.current=null);const d=i?.acceptedText||(C?J.current:"");d&&t!==d&&(E.current=setTimeout(()=>{Ke(t)},Qt)),_(t),k(t)}function tt(e){const t=g?.current;t!=null&&(t.selectionStart?(t.focus(),t.selectionEnd=e):t.focus())}function Lt(e){const t=xn[e];if(t&&g.current){const i=g.current.selectionStart,d=g.current.selectionEnd;if(i===d){const{text:b}=nt(t,i);tt(i+1),k(b)}else{const{text:b}=Ae(t);k(b)}}}function kt(e){const{text:t}=fe(e);k(t)}function Ae(e){let t=g.current?.value??"";if(g.current&&e){const i=g.current.selectionStart,d=g.current.selectionEnd,b=e;if(i===d)return fe(b);{t=v.wrappWildcard(i,d,b,t);const N=v.getHTML(t);return _(t),{text:t,html:N}}}return{text:t,html:t}}function fe(e){const t=g.current?.value??"";if(g.current&&e){const i=g.current.selectionStart,d=g.current.selectionEnd;if(i===d)return nt(e,i)}return{text:t,html:t}}function nt(e,t){let i=g.current?.value??"";i=i.slice(0,t)+e+i.slice(t);const d=v.getHTML(i);return _(i),{text:i,html:d}}r.useEffect(()=>{if(typeof window>"u"||!A)return;const e=Number(sessionStorage.getItem(V)||"0");return Number.isNaN(e)||Ue(e),()=>{sessionStorage.removeItem(V)}},[A,V]),r.useEffect(()=>{if(l){G(!1),h.current&&(clearTimeout(h.current),h.current=null);return}if(R&&p.length>0){G(!1),h.current&&(clearTimeout(h.current),h.current=null);return}const e=!!o.trim()&&o.length>=Ze;if(X.current===null){X.current=e,e&&(h.current=setTimeout(()=>{de.current()},lt));return}if(!e){X.current=!1,G(!1),h.current&&(clearTimeout(h.current),h.current=null);return}const t=!X.current&&e;X.current=!0,t&&de.current(),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{de.current()},lt)},[o,l,Ze,R,p]),r.useEffect(()=>()=>{h.current&&clearTimeout(h.current),W.current&&clearTimeout(W.current),Y.current&&clearTimeout(Y.current),E.current&&clearTimeout(E.current)},[]);const x=p[y]||"",$=r.useMemo(()=>!u||!x?null:`${u}-${y}-${x}`,[x,u,y]),rt=!!($&&me[$]),wt=r.useMemo(()=>v.getHTML(R||""),[R]),jt=r.useMemo(()=>v.getHTML(x),[x]),Ee=p.length<ut,O=!!R&&p.length>0,vt=p.length<=1||y<=0,Ht=p.length<=1||y>=p.length-1;r.useEffect(()=>{if(!O)return;const e=Ye.current;e&&(e.scrollTop=e.scrollHeight)},[x,O,l]);const K=r.useCallback(async(e,t=!1,i,d,b=c.AIActionVariant.DEFAULT)=>{if(!se&&!pe&&(!ge||!he)){D?.("AI configuration missing");return}if(!o.trim())return;const N=Q[e]||q.DEFAULT_AI_ACTION_MIN_CHARS[e]||50;if(o.length<N||l||t&&!Ee)return;const ee=ue[e],F=e===c.AIEditorActionTypes.REPHRASE&&L==="utility"&&b===c.AIActionVariant.REPHRASE?{...ee,label:"Rephrase",basePrompt:Zt}:ee,w=d||ce[e],st=F.tones?.find(B=>B.id===w),Ce=i!==void 0?i:T,ot=Be?.({actionType:e,actionVariant:b,currentText:o,templateType:L,config:F,toneId:w,toneLabel:st?.label,instructionText:Ce||void 0})||at.buildActionPrompt({config:F,currentText:o,selectedToneId:w,instructionText:Ce});Ge(!0),m("ai_action_triggered",{action_type:e,template_id:S,template_category:L});try{const B=se?await se({actionType:e,actionVariant:b,currentText:o,templateType:L,toneId:w,toneLabel:st?.label,instructionText:Ce||void 0,prompt:ot}):await at.requestAISuggestion({apiAdapter:pe,requestExecutor:ge,baseUrl:he,endpointPath:Oe,prompt:ot,intent:je,conversationId:ke,systemId:we,useCase:Ie,storeId:Le}),Te=typeof B=="string"?B.trim():(B?.body||"").trim();if(!Te)return;if(!t){We(o),Xe(e),Re([Te]),z(0);return}Re($t=>{const ct=[...$t,Te].slice(0,ut);return z(ct.length-1),ct})}catch{D?.("Failed to generate AI suggestion")}finally{Ge(!1)}},[ge,he,o,l,Ee,ue,ce,T,m,S,Oe,pe,je,ke,we,Ie,Le,L,D,Q,se,Be]),Pt=r.useCallback(()=>{if(!x||!R||!u)return;_(x),k(x),m("ai_suggestion_accepted",{action_type:u,template_id:S}),ae.current={acceptedText:x,baselineText:R,actionType:u,editedEventEmitted:!1};const e=Se.current,t=ne.computeAiTagOnAccept({baselineText:R,acceptedText:x,initialAiPrefillPhase:e});e&&(Se.current=!1),ie?.({...t,source:"accept"}),Z()},[x,R,u,_,k,m,S,ie,Z]),Mt=r.useCallback(()=>{u&&(m("ai_suggestion_discarded",{action_type:u,template_id:S}),Z())},[Z,m,u,S]),it=r.useCallback(e=>{!u||!$||me[$]||(Ve(t=>({...t,[$]:e})),m("ai_feedback_submitted",{action_type:u,template_id:S,rating:e,candidate_index:y+1}))},[$,m,me,u,y,S]),Dt=r.useMemo(()=>He?[]:ve.map(e=>{const t=ue[e],i=ce[e];return{type:e,label:t.label,isPrimary:e===c.AIEditorActionTypes.REPHRASE,loading:l&&u===e,highlighted:e===c.AIEditorActionTypes.REPHRASE&&qe,disabled:!o.trim()||o.length<(Q[e]||q.DEFAULT_AI_ACTION_MIN_CHARS[e]||50)||l||O&&u===e,showToneDropdown:e===c.AIEditorActionTypes.REPHRASE&&!!t.tones?.length,tones:t.tones,selectedToneId:i}}),[ve,He,ue,ce,l,u,O,qe,o,Q]);return r.useImperativeHandle(Ct,()=>({addTextOrWrap:Ae,addText:fe,get(){return o},setCaretPosition:tt}),[Ae,fe,o]),r.useEffect(()=>{P!==void 0&&_(P||"")},[P,_]),r.useEffect(()=>{if(!M||!D)return;const e=o.length>M?_e:I??"";Je.current!==e&&(Je.current=e,D(e))},[o,I,M,D]),n.jsxs(U.OuterContainer,{children:[n.jsxs(U.EditorFooterRow,{children:[n.jsx(U.EditorFooterTitle,{children:Fe?n.jsx(ye.TitleSmall,{"data-test":"body-text-for-edit-template",children:Fe}):null}),n.jsxs(U.EditorFooterRight,{children:[I&&I!==_e?n.jsxs(n.Fragment,{children:[n.jsx(Gt.default,{width:16,height:16,color:s.COLORS.content.negative}),n.jsx(ye.BodyCaption,{color:s.COLORS.content.negative,children:I})]}):null,M?n.jsxs(ye.BodyCaption,{style:{color:I===_e||o.length>M?s.COLORS.content.negative:s.COLORS.content.secondary},children:[o.length,"/",M]}):null]})]}),n.jsxs(U.Container,{isError:!!I,children:[O?n.jsxs(en,{ref:Ye,children:[n.jsx(tn,{dangerouslySetInnerHTML:{__html:wt}}),l?n.jsx(ft,{"aria-busy":"true",children:n.jsxs(nn,{children:[n.jsx(j,{width:"96%"}),n.jsx(j,{width:"84%"}),n.jsx(j,{width:"68%"})]})}):n.jsx(ft,{dangerouslySetInnerHTML:{__html:jt}}),n.jsxs(rn,{children:[n.jsx(H,{"aria-label":"Previous suggestion",type:"button",disabled:vt,onClick:()=>z(e=>Math.max(0,e-1)),children:n.jsx(Ft.default,{width:14,height:14,color:s.COLORS.content.secondary})}),n.jsxs(sn,{children:[y+1,"/",p.length]}),n.jsx(H,{"aria-label":"Next suggestion",type:"button",disabled:Ht,onClick:()=>z(e=>Math.min(p.length-1,e+1)),children:n.jsx(Bt.default,{width:14,height:14,color:s.COLORS.content.secondary})}),n.jsx(te.Tooltip,{body:"Like",placement:"top",children:n.jsx(H,{"aria-label":"Like suggestion",type:"button",disabled:rt,onClick:()=>it("like"),children:n.jsx(Xt.default,{width:14,height:14,color:s.COLORS.content.secondary})})}),n.jsx(te.Tooltip,{body:"Dislike",placement:"top",children:n.jsx(H,{"aria-label":"Dislike suggestion",type:"button",disabled:rt,onClick:()=>it("dislike"),children:n.jsx(Wt.default,{width:14,height:14,color:s.COLORS.content.secondary})})}),Ee?n.jsx(te.Tooltip,{body:l?"Regenerating…":"Regenerate",placement:"top",children:n.jsx(on,{"aria-label":"Regenerate suggestion","aria-busy":l,type:"button",disabled:l,onClick:()=>{u&&K(u,!0)},children:l?n.jsx(cn,{"aria-hidden":!0}):n.jsx(zt.default,{width:14,height:14})})}):null,n.jsx(te.Tooltip,{body:"Discard",placement:"top",children:n.jsx(H,{"aria-label":"Discard suggestion",type:"button",onClick:Mt,children:n.jsx(qt.default,{width:14,height:14,color:s.COLORS.content.secondary})})}),n.jsx(te.Tooltip,{body:"Accept",placement:"top",children:n.jsx(H,{"aria-label":"Accept suggestion",type:"button",onClick:Pt,children:n.jsx(Nt.default,{width:14,height:14,color:s.COLORS.content.secondary})})})]})]}):l?n.jsxs(Kt,{children:[n.jsx(j,{width:"96%"}),n.jsx(j,{width:"92%"}),n.jsx(j,{width:"88%"}),n.jsx(j,{width:"54%"})]}):n.jsx(U.TextSpace,{ref:g,...Et,value:o,onChange:It,onBlur:e=>{E.current&&(clearTimeout(E.current),E.current=null),Ke(e.target.value),At?.(e)},onPaste:e=>{const t=e.clipboardData.getData("text");if(t.length>dt){e.preventDefault();const i=g.current,d=i?.selectionStart??0,b=i?.selectionEnd??d,N=i?.value??o,ee=N.slice(0,d)+t+N.slice(b);_(ee),k(ee);const F=d+t.length;requestAnimationFrame(()=>{const w=g.current;if(w)try{w.setSelectionRange(F,F)}catch{}})}},rows:Rt}),ze?n.jsxs(an,{children:[n.jsxs(ln,{children:[n.jsx(Ut.default,{width:18,height:18,color:s.COLORS.content.secondary}),n.jsx(un,{value:T,placeholder:"Add specific instructions to refine your message",onChange:e=>oe(e.target.value)}),n.jsxs(dn,{children:[n.jsx(fn,{type:"button",onClick:()=>{oe(""),be(!1)},children:"Cancel"}),n.jsx(gn,{type:"button",onClick:()=>{const e=T.trim();e&&m("ai_instruction_used",{action_type:c.AIEditorActionTypes.REPHRASE,template_id:S,instruction_text:Ot(e)}),be(!1),oe(""),K(c.AIEditorActionTypes.REPHRASE,!1,e)},children:"Improve"})]})]}),T.trim().length>0&&Qe.length>0?n.jsx(hn,{children:Qe.map(e=>n.jsx(pn,{type:"button",selected:T===e,onClick:()=>oe(e),children:e},e))}):null]}):n.jsx(c.WhatsAppTextEditorHeader,{actions:St,ref:g,onActionSelect:Lt,RightComponent:bt,rightActionsDisabled:O||l,onEmojiClick:kt,aiActions:Dt,disableAllActions:O||l,instructionActive:ze,onAIInstructionsClick:()=>be(!0),onAIToneChange:(e,t)=>{yt(i=>({...i,[e]:t})),mt?.(e,t),e===c.AIEditorActionTypes.REPHRASE&&K(e,!1,void 0,t,c.AIActionVariant.DEFAULT)},onAIActionClick:(e,t=c.AIActionVariant.DEFAULT)=>{if(!l){if(O){if(u===e)return;Z(),K(e,!1,void 0,void 0,t);return}K(e,!1,void 0,void 0,t)}}})]})]})});xt.displayName="WhatsAppTextEditor";exports.AI_TAG_CHANGE_RATIO_THRESHOLD=ne.AI_TAG_CHANGE_RATIO_THRESHOLD;exports.computeAiTagOnAccept=ne.computeAiTagOnAccept;exports.levenshteinDistance=ne.levenshteinDistance;exports.WhatsAppTextEditor=xt;
|
|
156
156
|
//# sourceMappingURL=WhatsAppTextEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WhatsAppTextEditor.js","sources":["../../../../src/components/WhatsAppTextEditor/WhatsAppTextEditor.tsx"],"sourcesContent":["import CheckIcon from '@src/assets/icons/check.svg';\nimport ChevronLeftIcon from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRightIcon from '@src/assets/icons/chevronRight.svg';\nimport CrossIcon from '@src/assets/icons/cross.svg';\nimport EditIcon from '@src/assets/icons/edit.svg';\nimport InfoIcon from '@src/assets/icons/info.svg';\nimport RewindIcon from '@src/assets/icons/rewind.svg';\nimport ThumbsDownIcon from '@src/assets/icons/thumb-down-line.svg';\nimport ThumbsUpIcon from '@src/assets/icons/thumb-up-line.svg';\nimport { BaseWhatsappContentLangHelper } from '@src/helpers/BaseWhatsappContentLang.helper';\nimport { stripHtmlTags } from '@src/helpers/sanitize';\nimport React, {\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { COLORS } from '@src/constants/Theme';\nimport type { ApiRequestExecutor } from '../bik-chatbot/types';\nimport type { APIAdapter } from '../bik-chatbot/types/ai';\nimport { Tooltip } from '../tooltips/Tooltip';\nimport { BodyCaption, TitleSmall } from '../TypographyStyle';\nimport {\n\tAIActionPromptConfig,\n\tAIActionPromptRegistry,\n\tDEFAULT_AI_ACTION_MIN_CHARS,\n\tDEFAULT_INSTRUCTION_SUGGESTIONS,\n\tresolveActionPrompts,\n\tTemplateType,\n} from './ai/actionRegistry';\nimport {\n\tAITagPayload,\n\tcomputeAiTagOnAccept,\n\tcomputeAiTagOnPostEdit,\n} from './ai/aiTag';\nimport { buildActionPrompt, requestAISuggestion } from './ai/api';\nimport { AIActionToneOption } from './AIRephraseButton';\nimport {\n\tContainer,\n\tEditorFooterRight,\n\tEditorFooterRow,\n\tEditorFooterTitle,\n\tOuterContainer,\n\tTextSpace,\n} from './CustomEditor.styled';\nimport {\n\tAIActionVariant,\n\tAIEditorActionType,\n\tAIEditorActionTypes,\n\tAIHeaderAction,\n\tEditorActionTypes,\n\tWhatsAppEditorRightSlotProps,\n\tWhatsAppTextEditorHeader,\n} from './WhatsAppTextEditorHeader';\n\nconst LIMIT_REACHED = 'Character limit reached';\nconst REPHRASE_IDLE_MS = 3000;\nconst MAX_REPHRASE_HIGHLIGHTS = 5;\nconst MAX_SUGGESTIONS = 3;\nconst LARGE_INPUT_THRESHOLD = 1200;\nconst AI_TAG_RECOMPUTE_IDLE_MS = 1000;\nconst UTILITY_REPHRASE_PROMPT =\n\t'Rephrase this WhatsApp utility template to improve clarity and readability while preserving variables, intent, and compliance.';\n\nconst skeletonPulse = keyframes`\n\t0% { opacity: 0.55; }\n\t50% { opacity: 1; }\n\t100% { opacity: 0.55; }\n`;\n\nconst EditorSkeletonContainer = styled.div`\n\tpadding: 14px 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tmin-height: 150px;\n`;\n\nconst EditorSkeletonLine = styled.div<{ width: string }>`\n\theight: 16px;\n\tborder-radius: 6px;\n\twidth: ${(props) => props.width};\n\tbackground: #ececef;\n\tanimation: ${skeletonPulse} 1.1s ease-in-out infinite;\n`;\n\nconst SuggestionSessionContainer = styled.div`\n\tpadding: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmax-height: 260px;\n\toverflow-y: scroll;\n\tscrollbar-width: thin;\n\tscrollbar-color: #c8c8cf transparent;\n\t::-webkit-scrollbar {\n\t\twidth: 8px;\n\t}\n\t::-webkit-scrollbar-thumb {\n\t\tbackground: #c8c8cf;\n\t\tborder-radius: 8px;\n\t}\n\t::-webkit-scrollbar-track {\n\t\tbackground: transparent;\n\t}\n`;\n\nconst SuggestionBaselineText = styled.div`\n\ttext-decoration: line-through;\n\tcolor: ${COLORS.content.secondary};\n`;\n\nconst SuggestionCandidateText = styled.div`\n\tcolor: ${COLORS.content.primary};\n`;\n\nconst SuggestionCandidateSkeleton = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\twidth: 100%;\n\tmin-height: 40px;\n`;\n\nconst SuggestionControlsRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n`;\n\nconst SuggestionCounter = styled.span`\n\tcolor: ${COLORS.content.primary};\n\tfont-size: 14px;\n`;\n\nconst SuggestionIconButton = styled.button`\n\tborder: 0;\n\tbackground: transparent;\n\tpadding: 6px;\n\tborder-radius: 6px;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tcursor: pointer;\n\tcolor: ${COLORS.content.primary};\n\ttransition: background-color 0.12s ease;\n\t:not(:disabled):hover {\n\t\tbackground-color: ${COLORS.surface.hovered};\n\t}\n\t:disabled {\n\t\topacity: 0.35;\n\t\tcursor: not-allowed;\n\t}\n`;\n\n/** Regenerate stays full opacity while disabled so the loading shimmer stays visible (same pulse as editor skeleton). */\nconst SuggestionRegenerateButton = styled(SuggestionIconButton)`\n\t:disabled {\n\t\topacity: 1;\n\t\tcursor: wait;\n\t}\n`;\n\nconst RegenerateIconShimmer = styled.div`\n\twidth: 14px;\n\theight: 14px;\n\tborder-radius: 4px;\n\tbackground: #ececef;\n\tflex-shrink: 0;\n\tanimation: ${skeletonPulse} 1.1s ease-in-out infinite;\n`;\n\n/** Same bottom toolbar slot as `WhatsAppTextEditorHeader` — replaces the full icon/AI panel while open. */\nconst InstructionContainer = styled.div`\n\tbackground: ${COLORS.surface.standard};\n\tdisplay: flex;\n\tflex-direction: column;\n\tpadding: 8px 12px;\n\tgap: 10px;\n\tborder-radius: 0 0 4px 4px;\n\tposition: relative;\n`;\n\nconst InstructionInputRow = styled.div`\n\tborder: 1px solid #f5a4c0;\n\tborder-radius: 10px;\n\tpadding: 8px 10px;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tbackground: ${COLORS.surface.standard};\n`;\n\nconst InstructionInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: 0;\n\toutline: none;\n\tfont-size: 14px;\n\tbackground: transparent;\n\tcolor: ${COLORS.content.primary};\n`;\n\nconst InstructionActions = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n`;\n\nconst InstructionCancel = styled.button`\n\tborder: 0;\n\tbackground: transparent;\n\tcolor: ${COLORS.content.secondary};\n\tfont-size: 14px;\n\tfont-weight: 500;\n\tpadding: 0;\n\tcursor: pointer;\n`;\n\nconst InstructionImprove = styled.button`\n\tborder: 1px solid #5d3a72;\n\tcolor: #5d3a72;\n\tbackground: ${COLORS.surface.standard};\n\tborder-radius: 8px;\n\tpadding: 8px 14px;\n\tfont-size: 14px;\n\tline-height: 1.1;\n\tfont-weight: 600;\n\tcursor: pointer;\n`;\n\nconst InstructionSuggestionList = styled.div`\n\tmargin-top: 4px;\n\tborder-radius: 12px;\n\twidth: 331px;\n\tbackground: ${COLORS.surface.standard};\n\tbox-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);\n\toverflow: hidden;\n\tpadding: 4px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n`;\n\nconst InstructionSuggestionButton = styled.button<{ selected?: boolean }>`\n\twidth: 100%;\n\tborder: 0;\n\tborder-radius: 8px;\n\tbackground: ${(props) => (props.selected ? '#e5f3e8' : 'transparent')};\n\tcolor: ${(props) => (props.selected ? '#1e6b34' : COLORS.content.primary)};\n\ttext-align: left;\n\tpadding: 10px 12px;\n\tfont-size: 14px;\n\tline-height: 1.2;\n\tcursor: pointer;\n\t:hover {\n\t\tbackground: ${(props) =>\n\t\t\tprops.selected ? '#d9e8db' : COLORS.surface.subdued};\n\t}\n`;\n\ntype AIEventName =\n\t| 'ai_action_triggered'\n\t| 'ai_feedback_submitted'\n\t| 'ai_suggestion_accepted'\n\t| 'ai_suggestion_discarded'\n\t| 'ai_suggestion_edited'\n\t| 'ai_instruction_used';\n\nenum AIFeedbackRating {\n\tLIKE = 'like',\n\tDISLIKE = 'dislike',\n}\n\ntype AIEventPayload = {\n\taction_type: AIEditorActionType;\n\ttemplate_id?: string | number;\n\ttemplate_category?: TemplateType;\n\trating?: AIFeedbackRating;\n\tcandidate_index?: number;\n\tinstruction_text?: string;\n};\n\ntype AIActionRequestPayload = {\n\tactionType: AIEditorActionType;\n\tactionVariant?: AIActionVariant;\n\tcurrentText: string;\n\ttemplateType: TemplateType;\n\ttoneId?: string;\n\ttoneLabel?: string;\n\tinstructionText?: string;\n\tprompt: string;\n};\n\ntype AIActionPromptBuildPayload = {\n\tactionType: AIEditorActionType;\n\tactionVariant?: AIActionVariant;\n\tcurrentText: string;\n\ttemplateType: TemplateType;\n\tconfig: AIActionPromptConfig;\n\ttoneId?: string;\n\ttoneLabel?: string;\n\tinstructionText?: string;\n};\n\nexport type CustomEditorProps =\n\tReact.TextareaHTMLAttributes<HTMLTextAreaElement> & {\n\t\tonChange?: (text: string, html: string) => void;\n\t\ttext?: string;\n\t\tRightComponent?: React.ComponentType<WhatsAppEditorRightSlotProps>;\n\t\terror?: string;\n\t\tlimit?: number;\n\t\trows?: number;\n\t\tactions?: EditorActionTypes[];\n\n\t\t/**\n\t\t * Calls only for editor only error, not for errors coming from outside\n\t\t */\n\t\tonError?: (err: string) => void;\n\n\t\tonClickVariable?: (variable: string) => void;\n\t\teditorInstanceKey?: string;\n\t\teditorSessionId?: string;\n\t\ttemplateType?: TemplateType;\n\t\ttemplateId?: string | number;\n\t\trequestExecutor?: ApiRequestExecutor;\n\t\tbaseUrl?: string;\n\t\tendpointPath?: string;\n\t\tuseCase?: string;\n\t\tstoreId?: string;\n\t\tapiAdapter?: APIAdapter;\n\t\tconversationId?: string;\n\t\tsystemId?: string;\n\t\tintent?: string;\n\t\tenabledAIActions?: AIEditorActionType[];\n\t\tdisableBuiltInAIActions?: boolean;\n\t\tpromptOverrides?: AIActionPromptRegistry;\n\t\trephraseTones?: AIActionToneOption[];\n\t\taiActionMinChars?: Partial<Record<AIEditorActionType, number>>;\n\t\tinstructionSuggestions?: string[];\n\t\tonAnalyticsEvent?: (name: AIEventName, payload: AIEventPayload) => void;\n\t\t/**\n\t\t * Fires on AI-tag computations:\n\t\t * - `source: \"accept\"` after accepting a suggestion (addition check: >=50% => true)\n\t\t * - `source: \"post_edit_debounce\"` after edit idle/blur (retention check: <50% => true)\n\t\t * Persist `payload.isAiTagged` (or full payload) in host state and send on save.\n\t\t */\n\t\tonAITagComputed?: (payload: AITagPayload) => void;\n\t\t/**\n\t\t * When true, the editor body was loaded as fully AI-generated (prefill).\n\t\t * The first accepted suggestion will set `initialAiPrefillPhase` on the tag payload;\n\t\t * after that, only baseline vs accepted comparison applies.\n\t\t */\n\t\tprefillWasAiGenerated?: boolean;\n\t\t/**\n\t\t * Optional label above the editor (e.g. section title from the host).\n\t\t * When omitted, the left side of that top row is empty; limit/error stay on the right.\n\t\t */\n\t\teditorHeader?: React.ReactNode;\n\t\tonAIToneSelect?: (actionType: AIEditorActionType, toneId: string) => void;\n\t\tonAIActionRequest?: (\n\t\t\tpayload: AIActionRequestPayload,\n\t\t) => Promise<string | { body?: string }>;\n\t\tonBuildAIPrompt?: (payload: AIActionPromptBuildPayload) => string;\n\t\tonBlur?: React.FocusEventHandler<HTMLTextAreaElement>;\n\t};\nexport type CustomEditorRef = {\n\taddTextOrWrap: (textToAdd: string) => {\n\t\ttext: string;\n\t\thtml: string;\n\t};\n\taddText: (textToAdd: string) => {\n\t\ttext: string;\n\t\thtml: string;\n\t};\n\tget: () => string;\n\tsetCaretPosition(caretPos: number): void;\n};\n\nconst baseWhatsappContentLang = new BaseWhatsappContentLangHelper();\n\nconst WildCardMap: { [key in EditorActionTypes]?: string } = {\n\t[EditorActionTypes.BOLD]: '*',\n\t[EditorActionTypes.ITALIC]: '_',\n\t[EditorActionTypes.STRIKETHROUGH]: '~',\n};\n\nfunction getHighlightStorageKey(editorInstanceKey?: string) {\n\treturn `whatsapp-editor-rephrase-highlight-${editorInstanceKey || 'default'}`;\n}\n\nexport const WhatsAppTextEditor = React.forwardRef<\n\tCustomEditorRef,\n\tCustomEditorProps\n>(\n\t(\n\t\t{\n\t\t\tonChange,\n\t\t\tonClickVariable,\n\t\t\ttext: inputValue,\n\t\t\tRightComponent,\n\t\t\terror,\n\t\t\tlimit,\n\t\t\tonError,\n\t\t\trows,\n\t\t\tactions,\n\t\t\teditorInstanceKey,\n\t\t\teditorSessionId,\n\t\t\ttemplateType = 'marketing',\n\t\t\ttemplateId,\n\t\t\trequestExecutor,\n\t\t\tbaseUrl,\n\t\t\tendpointPath,\n\t\t\tuseCase,\n\t\t\tstoreId,\n\t\t\tapiAdapter,\n\t\t\tconversationId = 'whatsapp-template-editor',\n\t\t\tsystemId = 'whatsapp-writer',\n\t\t\tintent = 'default',\n\t\t\tenabledAIActions = [\n\t\t\t\tAIEditorActionTypes.REPHRASE,\n\t\t\t\tAIEditorActionTypes.SHORTEN,\n\t\t\t\tAIEditorActionTypes.EXPAND,\n\t\t\t\tAIEditorActionTypes.EMOJIFY,\n\t\t\t],\n\t\t\tdisableBuiltInAIActions = false,\n\t\t\tpromptOverrides,\n\t\t\trephraseTones,\n\t\t\taiActionMinChars,\n\t\t\tinstructionSuggestions = DEFAULT_INSTRUCTION_SUGGESTIONS,\n\t\t\tonAnalyticsEvent,\n\t\t\tonAITagComputed,\n\t\t\tprefillWasAiGenerated = false,\n\t\t\teditorHeader,\n\t\t\tonAIToneSelect,\n\t\t\tonAIActionRequest,\n\t\t\tonBuildAIPrompt,\n\t\t\tonBlur: textAreaOnBlur,\n\t\t\t...textAreaProps\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst textSpaceRef = useRef<HTMLTextAreaElement>(null);\n\t\tconst [currentText, setCurrentText] = useState(inputValue || '');\n\t\tconst [isRephraseHighlighted, setIsRephraseHighlighted] = useState(false);\n\t\tconst [rephraseHighlightCount, setRephraseHighlightCount] = useState(0);\n\t\tconst [isGenerating, setIsGenerating] = useState(false);\n\t\tconst [isInstructionInputVisible, setIsInstructionInputVisible] =\n\t\t\tuseState(false);\n\t\tconst [instructionText, setInstructionText] = useState('');\n\t\tconst [toneByAction, setToneByAction] = useState<\n\t\t\tPartial<Record<AIEditorActionType, string>>\n\t\t>({});\n\t\tconst [suggestionBaseText, setSuggestionBaseText] = useState<string | null>(\n\t\t\tnull,\n\t\t);\n\t\tconst [suggestionCandidates, setSuggestionCandidates] = useState<string[]>(\n\t\t\t[],\n\t\t);\n\t\tconst [suggestionIndex, setSuggestionIndex] = useState(0);\n\t\tconst [suggestionActionType, setSuggestionActionType] =\n\t\t\tuseState<AIEditorActionType | null>(null);\n\t\tconst suggestionScrollRef = useRef<HTMLDivElement | null>(null);\n\t\tconst rephraseIdleRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\t\tconst highlightResetRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\t\tnull,\n\t\t);\n\t\tconst aiTagRecomputeRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\t\tnull,\n\t\t);\n\t\t/**\n\t\t * Prior eligibility for rephrase nudge (null = not initialized).\n\t\t * Matches the chip: non-empty trim and length ≥ min — same as `aiHeaderActions` disabled rules.\n\t\t */\n\t\tconst prevRephraseEligibleRef = useRef<boolean | null>(null);\n\t\tconst deferredHtmlRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\t\tconst lastEmittedEditorErrorRef = useRef<string | null>(null);\n\t\t/** First accept after full-AI prefill (`prefillWasAiGenerated`); cleared after one accept. */\n\t\tconst initialAiPrefillPhaseRef = useRef(!!prefillWasAiGenerated);\n\t\tconst acceptedSuggestionStateRef = useRef<{\n\t\t\tacceptedText: string;\n\t\t\tbaselineText: string;\n\t\t\tactionType: AIEditorActionType;\n\t\t\teditedEventEmitted: boolean;\n\t\t} | null>(null);\n\t\t/** Original prefill body for AI tag recompute; seeded once, never the live `currentText` fallback. */\n\t\tconst prefillBaselineTextRef = useRef('');\n\t\tconst prefillBaselineCapturedRef = useRef(false);\n\t\tconst [feedbackVotesByCandidate, setFeedbackVotesByCandidate] = useState<\n\t\t\tPartial<Record<string, AIFeedbackRating>>\n\t\t>({});\n\t\tconst mountSessionIdRef = useRef(\n\t\t\t`mount-${Date.now().toString(36)}-${Math.random()\n\t\t\t\t.toString(36)\n\t\t\t\t.slice(2, 8)}`,\n\t\t);\n\t\tconst highlightStorageKey = useMemo(() => {\n\t\t\treturn getHighlightStorageKey(\n\t\t\t\t`${editorInstanceKey || 'default'}-${\n\t\t\t\t\teditorSessionId || mountSessionIdRef.current\n\t\t\t\t}`,\n\t\t\t);\n\t\t}, [editorInstanceKey, editorSessionId]);\n\n\t\tuseEffect(() => {\n\t\t\tinitialAiPrefillPhaseRef.current = !!prefillWasAiGenerated;\n\t\t}, [prefillWasAiGenerated, editorInstanceKey]);\n\n\t\tuseEffect(() => {\n\t\t\tprefillBaselineCapturedRef.current = false;\n\t\t\tprefillBaselineTextRef.current = '';\n\t\t}, [editorInstanceKey, editorSessionId]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!prefillWasAiGenerated) {\n\t\t\t\tprefillBaselineCapturedRef.current = false;\n\t\t\t\tprefillBaselineTextRef.current = '';\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (prefillBaselineCapturedRef.current) return;\n\t\t\tconst seed = inputValue ?? '';\n\t\t\tif (seed.length > 0) {\n\t\t\t\tprefillBaselineTextRef.current = seed;\n\t\t\t\tprefillBaselineCapturedRef.current = true;\n\t\t\t}\n\t\t}, [prefillWasAiGenerated, inputValue, editorInstanceKey, editorSessionId]);\n\n\t\tconst activeActionPrompts = useMemo(() => {\n\t\t\treturn resolveActionPrompts(templateType, promptOverrides, rephraseTones);\n\t\t}, [promptOverrides, rephraseTones, templateType]);\n\n\t\tconst filteredInstructionSuggestions = useMemo(() => {\n\t\t\tconst query = instructionText.trim().toLowerCase();\n\t\t\tif (!query) return [];\n\t\t\treturn instructionSuggestions.filter((suggestion) =>\n\t\t\t\tsuggestion.toLowerCase().includes(query),\n\t\t\t);\n\t\t}, [instructionSuggestions, instructionText]);\n\n\t\tconst minCharsByAction = useMemo(() => {\n\t\t\treturn {\n\t\t\t\t...DEFAULT_AI_ACTION_MIN_CHARS,\n\t\t\t\t...(aiActionMinChars || {}),\n\t\t\t};\n\t\t}, [aiActionMinChars]);\n\n\t\tconst rephraseMinChars =\n\t\t\tminCharsByAction[AIEditorActionTypes.REPHRASE] ||\n\t\t\tDEFAULT_AI_ACTION_MIN_CHARS[AIEditorActionTypes.REPHRASE];\n\n\t\tconst anonymizeInstructionText = useCallback((value: string) => {\n\t\t\tconst normalized = value.trim().replace(/\\s+/g, ' ');\n\t\t\tif (!normalized) return '';\n\t\t\tconst words = normalized.split(' ').length;\n\t\t\treturn `[anonymized:length_${normalized.length}:words_${words}]`;\n\t\t}, []);\n\n\t\tconst emitAIEvent = useCallback(\n\t\t\t(name: AIEventName, payload: AIEventPayload) => {\n\t\t\t\tonAnalyticsEvent?.(name, payload);\n\t\t\t},\n\t\t\t[onAnalyticsEvent],\n\t\t);\n\n\t\tconst setEditorText = useCallback((nextText: string) => {\n\t\t\tsetCurrentText((prev) => (prev === nextText ? prev : nextText));\n\t\t}, []);\n\n\t\tconst emitChangeWithGuard = useCallback(\n\t\t\t(nextText: string) => {\n\t\t\t\tif (deferredHtmlRef.current) {\n\t\t\t\t\tclearTimeout(deferredHtmlRef.current);\n\t\t\t\t}\n\t\t\t\tif (nextText.length > LARGE_INPUT_THRESHOLD) {\n\t\t\t\t\tonChange?.(nextText, nextText);\n\t\t\t\t\tdeferredHtmlRef.current = setTimeout(() => {\n\t\t\t\t\t\tonChange?.(nextText, baseWhatsappContentLang.getHTML(nextText));\n\t\t\t\t\t}, 16);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonChange?.(nextText, baseWhatsappContentLang.getHTML(nextText));\n\t\t\t},\n\t\t\t[onChange],\n\t\t);\n\n\t\tconst emitPostEditAiTagRecompute = useCallback(\n\t\t\t(nextText: string) => {\n\t\t\t\tconst latest = acceptedSuggestionStateRef.current;\n\t\t\t\tconst latestBaseline =\n\t\t\t\t\tlatest?.acceptedText ||\n\t\t\t\t\t(prefillWasAiGenerated ? prefillBaselineTextRef.current : '');\n\t\t\t\tif (!latestBaseline) return;\n\t\t\t\tif (nextText === latestBaseline) return;\n\t\t\t\tconst recomputePayload = computeAiTagOnPostEdit({\n\t\t\t\t\tacceptedAiText: latestBaseline,\n\t\t\t\t\tcurrentEditedText: nextText,\n\t\t\t\t});\n\t\t\t\tonAITagComputed?.({\n\t\t\t\t\t...recomputePayload,\n\t\t\t\t\tsource: 'post_edit_debounce',\n\t\t\t\t});\n\t\t\t},\n\t\t\t[onAITagComputed, prefillWasAiGenerated],\n\t\t);\n\n\t\tconst clearSuggestionSession = useCallback(() => {\n\t\t\tsetSuggestionBaseText(null);\n\t\t\tsetSuggestionCandidates([]);\n\t\t\tsetSuggestionIndex(0);\n\t\t\tsetSuggestionActionType(null);\n\t\t\tsetFeedbackVotesByCandidate({});\n\t\t}, []);\n\n\t\tconst triggerRephraseHighlight = useCallback(() => {\n\t\t\tif (isGenerating) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!!suggestionBaseText && suggestionCandidates.length > 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (rephraseHighlightCount >= MAX_REPHRASE_HIGHLIGHTS) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nextCount = rephraseHighlightCount + 1;\n\t\t\tsetRephraseHighlightCount(nextCount);\n\t\t\tif (typeof window !== 'undefined' && editorInstanceKey) {\n\t\t\t\tsessionStorage.setItem(highlightStorageKey, String(nextCount));\n\t\t\t}\n\t\t\tsetIsRephraseHighlighted(true);\n\t\t\tif (highlightResetRef.current) {\n\t\t\t\tclearTimeout(highlightResetRef.current);\n\t\t\t}\n\t\t\thighlightResetRef.current = setTimeout(() => {\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t}, 1200);\n\t\t}, [\n\t\t\teditorInstanceKey,\n\t\t\thighlightStorageKey,\n\t\t\tisGenerating,\n\t\t\tsuggestionBaseText,\n\t\t\tsuggestionCandidates,\n\t\t\trephraseHighlightCount,\n\t\t]);\n\n\t\tconst triggerRephraseHighlightRef = useRef(triggerRephraseHighlight);\n\t\ttriggerRephraseHighlightRef.current = triggerRephraseHighlight;\n\n\t\tfunction handleOnChange(e: React.ChangeEvent<HTMLTextAreaElement>) {\n\t\t\tconst text = stripHtmlTags(e.target.value);\n\t\t\tconst acceptedSuggestion = acceptedSuggestionStateRef.current;\n\t\t\tif (\n\t\t\t\tacceptedSuggestion &&\n\t\t\t\t!acceptedSuggestion.editedEventEmitted &&\n\t\t\t\ttext !== acceptedSuggestion.acceptedText\n\t\t\t) {\n\t\t\t\tacceptedSuggestionStateRef.current = {\n\t\t\t\t\t...acceptedSuggestion,\n\t\t\t\t\teditedEventEmitted: true,\n\t\t\t\t};\n\t\t\t\temitAIEvent('ai_suggestion_edited', {\n\t\t\t\t\taction_type: acceptedSuggestion.actionType,\n\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (aiTagRecomputeRef.current) {\n\t\t\t\tclearTimeout(aiTagRecomputeRef.current);\n\t\t\t\taiTagRecomputeRef.current = null;\n\t\t\t}\n\t\t\tconst baselineAiTextForRecompute =\n\t\t\t\tacceptedSuggestion?.acceptedText ||\n\t\t\t\t(prefillWasAiGenerated ? prefillBaselineTextRef.current : '');\n\t\t\tif (baselineAiTextForRecompute && text !== baselineAiTextForRecompute) {\n\t\t\t\taiTagRecomputeRef.current = setTimeout(() => {\n\t\t\t\t\temitPostEditAiTagRecompute(text);\n\t\t\t\t}, AI_TAG_RECOMPUTE_IDLE_MS);\n\t\t\t}\n\t\t\tsetEditorText(text);\n\t\t\temitChangeWithGuard(text);\n\t\t}\n\n\t\tfunction setCaretPosition(caretPos: number) {\n\t\t\tconst elem = textSpaceRef?.current;\n\n\t\t\tif (elem != null) {\n\t\t\t\tif (elem.selectionStart) {\n\t\t\t\t\telem.focus();\n\t\t\t\t\telem.selectionEnd = caretPos;\n\t\t\t\t} else elem.focus();\n\t\t\t}\n\t\t}\n\n\t\tfunction onActionSelect(actionType: EditorActionTypes) {\n\t\t\tconst wildCard = WildCardMap[actionType];\n\t\t\tif (wildCard && textSpaceRef.current) {\n\t\t\t\tconst start = textSpaceRef.current.selectionStart;\n\t\t\t\tconst end = textSpaceRef.current.selectionEnd;\n\n\t\t\t\tif (start === end) {\n\t\t\t\t\tconst { text } = insertTextAtIndex(wildCard, start);\n\t\t\t\t\tsetCaretPosition(start + 1);\n\t\t\t\t\temitChangeWithGuard(text);\n\t\t\t\t} else {\n\t\t\t\t\tconst { text } = addTextOrWrap(wildCard);\n\t\t\t\t\temitChangeWithGuard(text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction onEmojiAddition(emoji: string) {\n\t\t\tconst { text } = addText(emoji);\n\t\t\temitChangeWithGuard(text);\n\t\t}\n\n\t\tfunction addTextOrWrap(textToAdd?: string) {\n\t\t\tlet text = textSpaceRef.current?.value ?? '';\n\n\t\t\tif (textSpaceRef.current && textToAdd) {\n\t\t\t\tconst start = textSpaceRef.current.selectionStart;\n\t\t\t\tconst end = textSpaceRef.current.selectionEnd;\n\n\t\t\t\tconst wildCard = textToAdd;\n\t\t\t\tif (start === end) {\n\t\t\t\t\t/** nothing is selected */\n\t\t\t\t\t/** so append the wildcard at the end */\n\n\t\t\t\t\treturn addText(wildCard);\n\t\t\t\t} else {\n\t\t\t\t\ttext = baseWhatsappContentLang.wrappWildcard(\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\tend,\n\t\t\t\t\t\twildCard,\n\t\t\t\t\t\ttext!,\n\t\t\t\t\t);\n\t\t\t\t\tconst html = baseWhatsappContentLang.getHTML(text);\n\t\t\t\t\tsetEditorText(text);\n\t\t\t\t\treturn { text, html };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { text: text!, html: text! };\n\t\t}\n\n\t\tfunction addText(textToAdd: string) {\n\t\t\tconst text = textSpaceRef.current?.value ?? '';\n\n\t\t\tif (textSpaceRef.current && textToAdd) {\n\t\t\t\tconst start = textSpaceRef.current.selectionStart;\n\t\t\t\tconst end = textSpaceRef.current.selectionEnd;\n\t\t\t\tif (start === end) {\n\t\t\t\t\treturn insertTextAtIndex(textToAdd, start);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { text: text!, html: text! };\n\t\t}\n\n\t\tfunction insertTextAtIndex(textToAdd: string, index: number) {\n\t\t\tlet text = textSpaceRef.current?.value ?? '';\n\n\t\t\ttext = text.slice(0, index) + textToAdd + text.slice(index);\n\t\t\tconst html = baseWhatsappContentLang.getHTML(text);\n\t\t\tsetEditorText(text);\n\t\t\treturn { text, html };\n\t\t}\n\n\t\tuseEffect(() => {\n\t\t\tif (typeof window === 'undefined' || !editorInstanceKey) return;\n\t\t\tconst cached = Number(sessionStorage.getItem(highlightStorageKey) || '0');\n\t\t\tif (!Number.isNaN(cached)) {\n\t\t\t\tsetRephraseHighlightCount(cached);\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tsessionStorage.removeItem(highlightStorageKey);\n\t\t\t};\n\t\t}, [editorInstanceKey, highlightStorageKey]);\n\n\t\tuseEffect(() => {\n\t\t\tif (isGenerating) {\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t\t\trephraseIdleRef.current = null;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!!suggestionBaseText && suggestionCandidates.length > 0) {\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t\t\trephraseIdleRef.current = null;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst eligible =\n\t\t\t\t!!currentText.trim() && currentText.length >= rephraseMinChars;\n\n\t\t\tif (prevRephraseEligibleRef.current === null) {\n\t\t\t\tprevRephraseEligibleRef.current = eligible;\n\t\t\t\tif (eligible) {\n\t\t\t\t\trephraseIdleRef.current = setTimeout(() => {\n\t\t\t\t\t\ttriggerRephraseHighlightRef.current();\n\t\t\t\t\t}, REPHRASE_IDLE_MS);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!eligible) {\n\t\t\t\tprevRephraseEligibleRef.current = false;\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t\t\trephraseIdleRef.current = null;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst crossedThreshold = !prevRephraseEligibleRef.current && eligible;\n\t\t\tprevRephraseEligibleRef.current = true;\n\n\t\t\tif (crossedThreshold) {\n\t\t\t\ttriggerRephraseHighlightRef.current();\n\t\t\t}\n\n\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t}\n\t\t\trephraseIdleRef.current = setTimeout(() => {\n\t\t\t\ttriggerRephraseHighlightRef.current();\n\t\t\t}, REPHRASE_IDLE_MS);\n\t\t}, [\n\t\t\tcurrentText,\n\t\t\tisGenerating,\n\t\t\trephraseMinChars,\n\t\t\tsuggestionBaseText,\n\t\t\tsuggestionCandidates,\n\t\t]);\n\n\t\tuseEffect(() => {\n\t\t\treturn () => {\n\t\t\t\tif (rephraseIdleRef.current) clearTimeout(rephraseIdleRef.current);\n\t\t\t\tif (highlightResetRef.current) clearTimeout(highlightResetRef.current);\n\t\t\t\tif (deferredHtmlRef.current) clearTimeout(deferredHtmlRef.current);\n\t\t\t\tif (aiTagRecomputeRef.current) clearTimeout(aiTagRecomputeRef.current);\n\t\t\t};\n\t\t}, []);\n\n\t\tconst activeCandidate = suggestionCandidates[suggestionIndex] || '';\n\t\tconst activeFeedbackCandidateKey = useMemo(() => {\n\t\t\tif (!suggestionActionType || !activeCandidate) return null;\n\t\t\treturn `${suggestionActionType}-${suggestionIndex}-${activeCandidate}`;\n\t\t}, [activeCandidate, suggestionActionType, suggestionIndex]);\n\t\tconst hasFeedbackForActiveCandidate = !!(\n\t\t\tactiveFeedbackCandidateKey &&\n\t\t\tfeedbackVotesByCandidate[activeFeedbackCandidateKey]\n\t\t);\n\t\tconst suggestionBaseHtml = useMemo(\n\t\t\t() => baseWhatsappContentLang.getHTML(suggestionBaseText || ''),\n\t\t\t[suggestionBaseText],\n\t\t);\n\t\tconst activeCandidateHtml = useMemo(\n\t\t\t() => baseWhatsappContentLang.getHTML(activeCandidate),\n\t\t\t[activeCandidate],\n\t\t);\n\t\tconst canRegenerate = suggestionCandidates.length < MAX_SUGGESTIONS;\n\t\tconst shouldShowSuggestionSession =\n\t\t\t!!suggestionBaseText && suggestionCandidates.length > 0;\n\t\tconst isPrevSuggestionDisabled =\n\t\t\tsuggestionCandidates.length <= 1 || suggestionIndex <= 0;\n\t\tconst isNextSuggestionDisabled =\n\t\t\tsuggestionCandidates.length <= 1 ||\n\t\t\tsuggestionIndex >= suggestionCandidates.length - 1;\n\n\t\tuseEffect(() => {\n\t\t\tif (!shouldShowSuggestionSession) return;\n\t\t\tconst node = suggestionScrollRef.current;\n\t\t\tif (!node) return;\n\t\t\tnode.scrollTop = node.scrollHeight;\n\t\t}, [activeCandidate, shouldShowSuggestionSession, isGenerating]);\n\n\t\tconst executeAIAction = useCallback(\n\t\t\tasync (\n\t\t\t\tactionType: AIEditorActionType,\n\t\t\t\tregenerateExisting = false,\n\t\t\t\tinstructionOverride?: string,\n\t\t\t\ttoneOverrideId?: string,\n\t\t\t\tactionVariant: AIActionVariant = AIActionVariant.DEFAULT,\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\t!onAIActionRequest &&\n\t\t\t\t\t!apiAdapter &&\n\t\t\t\t\t(!requestExecutor || !baseUrl)\n\t\t\t\t) {\n\t\t\t\t\tonError?.('AI configuration missing');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!currentText.trim()) return;\n\t\t\t\tconst minCharsForAction =\n\t\t\t\t\tminCharsByAction[actionType] ||\n\t\t\t\t\tDEFAULT_AI_ACTION_MIN_CHARS[actionType] ||\n\t\t\t\t\t50;\n\t\t\t\tif (currentText.length < minCharsForAction) return;\n\t\t\t\tif (isGenerating) return;\n\t\t\t\tif (regenerateExisting && !canRegenerate) return;\n\n\t\t\t\tconst baseConfig = activeActionPrompts[actionType];\n\t\t\t\tconst config =\n\t\t\t\t\tactionType === AIEditorActionTypes.REPHRASE &&\n\t\t\t\t\ttemplateType === 'utility' &&\n\t\t\t\t\tactionVariant === AIActionVariant.REPHRASE\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...baseConfig,\n\t\t\t\t\t\t\t\tlabel: 'Rephrase',\n\t\t\t\t\t\t\t\tbasePrompt: UTILITY_REPHRASE_PROMPT,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: baseConfig;\n\t\t\t\t// Tone is sent only after explicit user selection (or explicit override),\n\t\t\t\t// not from default tone metadata.\n\t\t\t\tconst selectedToneId = toneOverrideId || toneByAction[actionType];\n\t\t\t\tconst selectedTone = config.tones?.find(\n\t\t\t\t\t(tone) => tone.id === selectedToneId,\n\t\t\t\t);\n\t\t\t\tconst instructionForPrompt =\n\t\t\t\t\tinstructionOverride !== undefined\n\t\t\t\t\t\t? instructionOverride\n\t\t\t\t\t\t: instructionText;\n\t\t\t\tconst prompt =\n\t\t\t\t\tonBuildAIPrompt?.({\n\t\t\t\t\t\tactionType,\n\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\tcurrentText,\n\t\t\t\t\t\ttemplateType,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\ttoneId: selectedToneId,\n\t\t\t\t\t\ttoneLabel: selectedTone?.label,\n\t\t\t\t\t\tinstructionText: instructionForPrompt || undefined,\n\t\t\t\t\t}) ||\n\t\t\t\t\tbuildActionPrompt({\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tcurrentText,\n\t\t\t\t\t\tselectedToneId,\n\t\t\t\t\t\tinstructionText: instructionForPrompt,\n\t\t\t\t\t});\n\n\t\t\t\tsetIsGenerating(true);\n\t\t\t\temitAIEvent('ai_action_triggered', {\n\t\t\t\t\taction_type: actionType,\n\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t\ttemplate_category: templateType,\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tconst result = onAIActionRequest\n\t\t\t\t\t\t? await onAIActionRequest({\n\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\t\t\tcurrentText,\n\t\t\t\t\t\t\t\ttemplateType,\n\t\t\t\t\t\t\t\ttoneId: selectedToneId,\n\t\t\t\t\t\t\t\ttoneLabel: selectedTone?.label,\n\t\t\t\t\t\t\t\tinstructionText: instructionForPrompt || undefined,\n\t\t\t\t\t\t\t\tprompt,\n\t\t\t\t\t\t })\n\t\t\t\t\t\t: await requestAISuggestion({\n\t\t\t\t\t\t\t\tapiAdapter,\n\t\t\t\t\t\t\t\trequestExecutor,\n\t\t\t\t\t\t\t\tbaseUrl,\n\t\t\t\t\t\t\t\tendpointPath,\n\t\t\t\t\t\t\t\tprompt,\n\t\t\t\t\t\t\t\tintent,\n\t\t\t\t\t\t\t\tconversationId,\n\t\t\t\t\t\t\t\tsystemId,\n\t\t\t\t\t\t\t\tuseCase,\n\t\t\t\t\t\t\t\tstoreId,\n\t\t\t\t\t\t });\n\t\t\t\t\tconst candidate =\n\t\t\t\t\t\ttypeof result === 'string'\n\t\t\t\t\t\t\t? result.trim()\n\t\t\t\t\t\t\t: (result?.body || '').trim();\n\t\t\t\t\tif (!candidate) return;\n\t\t\t\t\tif (!regenerateExisting) {\n\t\t\t\t\t\tsetSuggestionBaseText(currentText);\n\t\t\t\t\t\tsetSuggestionActionType(actionType);\n\t\t\t\t\t\tsetSuggestionCandidates([candidate]);\n\t\t\t\t\t\tsetSuggestionIndex(0);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tsetSuggestionCandidates((prev) => {\n\t\t\t\t\t\tconst next = [...prev, candidate].slice(0, MAX_SUGGESTIONS);\n\t\t\t\t\t\tsetSuggestionIndex(next.length - 1);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t} catch (e) {\n\t\t\t\t\tonError?.('Failed to generate AI suggestion');\n\t\t\t\t} finally {\n\t\t\t\t\tsetIsGenerating(false);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[\n\t\t\t\trequestExecutor,\n\t\t\t\tbaseUrl,\n\t\t\t\tcurrentText,\n\t\t\t\tisGenerating,\n\t\t\t\tcanRegenerate,\n\t\t\t\tactiveActionPrompts,\n\t\t\t\ttoneByAction,\n\t\t\t\tinstructionText,\n\t\t\t\temitAIEvent,\n\t\t\t\ttemplateId,\n\t\t\t\tendpointPath,\n\t\t\t\tapiAdapter,\n\t\t\t\tintent,\n\t\t\t\tconversationId,\n\t\t\t\tsystemId,\n\t\t\t\tuseCase,\n\t\t\t\tstoreId,\n\t\t\t\ttemplateType,\n\t\t\t\tonError,\n\t\t\t\tminCharsByAction,\n\t\t\t\tonAIActionRequest,\n\t\t\t\tonBuildAIPrompt,\n\t\t\t],\n\t\t);\n\n\t\tconst handleAcceptSuggestion = useCallback(() => {\n\t\t\tif (!activeCandidate || !suggestionBaseText || !suggestionActionType)\n\t\t\t\treturn;\n\t\t\tsetEditorText(activeCandidate);\n\t\t\temitChangeWithGuard(activeCandidate);\n\t\t\temitAIEvent('ai_suggestion_accepted', {\n\t\t\t\taction_type: suggestionActionType,\n\t\t\t\ttemplate_id: templateId,\n\t\t\t});\n\t\t\tacceptedSuggestionStateRef.current = {\n\t\t\t\tacceptedText: activeCandidate,\n\t\t\t\tbaselineText: suggestionBaseText,\n\t\t\t\tactionType: suggestionActionType,\n\t\t\t\teditedEventEmitted: false,\n\t\t\t};\n\n\t\t\tconst inInitialAiPhase = initialAiPrefillPhaseRef.current;\n\t\t\tconst tagPayload = computeAiTagOnAccept({\n\t\t\t\tbaselineText: suggestionBaseText,\n\t\t\t\tacceptedText: activeCandidate,\n\t\t\t\tinitialAiPrefillPhase: inInitialAiPhase,\n\t\t\t});\n\t\t\tif (inInitialAiPhase) {\n\t\t\t\tinitialAiPrefillPhaseRef.current = false;\n\t\t\t}\n\t\t\tonAITagComputed?.({\n\t\t\t\t...tagPayload,\n\t\t\t\tsource: 'accept',\n\t\t\t});\n\t\t\tclearSuggestionSession();\n\t\t}, [\n\t\t\tactiveCandidate,\n\t\t\tsuggestionBaseText,\n\t\t\tsuggestionActionType,\n\t\t\tsetEditorText,\n\t\t\temitChangeWithGuard,\n\t\t\temitAIEvent,\n\t\t\ttemplateId,\n\t\t\tonAITagComputed,\n\t\t\tclearSuggestionSession,\n\t\t]);\n\n\t\tconst handleRejectSuggestion = useCallback(() => {\n\t\t\tif (!suggestionActionType) return;\n\t\t\temitAIEvent('ai_suggestion_discarded', {\n\t\t\t\taction_type: suggestionActionType,\n\t\t\t\ttemplate_id: templateId,\n\t\t\t});\n\t\t\tclearSuggestionSession();\n\t\t}, [clearSuggestionSession, emitAIEvent, suggestionActionType, templateId]);\n\n\t\tconst handleFeedback = useCallback(\n\t\t\t(rating: AIFeedbackRating) => {\n\t\t\t\tif (!suggestionActionType || !activeFeedbackCandidateKey) return;\n\t\t\t\tif (feedbackVotesByCandidate[activeFeedbackCandidateKey]) return;\n\t\t\t\tsetFeedbackVotesByCandidate((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\t[activeFeedbackCandidateKey]: rating,\n\t\t\t\t}));\n\t\t\t\temitAIEvent('ai_feedback_submitted', {\n\t\t\t\t\taction_type: suggestionActionType,\n\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t\trating,\n\t\t\t\t\tcandidate_index: suggestionIndex + 1,\n\t\t\t\t});\n\t\t\t},\n\t\t\t[\n\t\t\t\tactiveFeedbackCandidateKey,\n\t\t\t\temitAIEvent,\n\t\t\t\tfeedbackVotesByCandidate,\n\t\t\t\tsuggestionActionType,\n\t\t\t\tsuggestionIndex,\n\t\t\t\ttemplateId,\n\t\t\t],\n\t\t);\n\n\t\tconst aiHeaderActions: AIHeaderAction[] = useMemo(() => {\n\t\t\tif (disableBuiltInAIActions) return [];\n\t\t\treturn enabledAIActions.map((actionType) => {\n\t\t\t\tconst actionConfig = activeActionPrompts[actionType];\n\t\t\t\tconst toneId = toneByAction[actionType];\n\t\t\t\treturn {\n\t\t\t\t\ttype: actionType,\n\t\t\t\t\tlabel: actionConfig.label,\n\t\t\t\t\tisPrimary: actionType === AIEditorActionTypes.REPHRASE,\n\t\t\t\t\tloading: isGenerating && suggestionActionType === actionType,\n\t\t\t\t\thighlighted:\n\t\t\t\t\t\tactionType === AIEditorActionTypes.REPHRASE &&\n\t\t\t\t\t\tisRephraseHighlighted,\n\t\t\t\t\tdisabled:\n\t\t\t\t\t\t!currentText.trim() ||\n\t\t\t\t\t\tcurrentText.length <\n\t\t\t\t\t\t\t(minCharsByAction[actionType] ||\n\t\t\t\t\t\t\t\tDEFAULT_AI_ACTION_MIN_CHARS[actionType] ||\n\t\t\t\t\t\t\t\t50) ||\n\t\t\t\t\t\tisGenerating ||\n\t\t\t\t\t\t(shouldShowSuggestionSession &&\n\t\t\t\t\t\t\tsuggestionActionType === actionType),\n\t\t\t\t\tshowToneDropdown:\n\t\t\t\t\t\tactionType === AIEditorActionTypes.REPHRASE &&\n\t\t\t\t\t\t!!actionConfig.tones?.length,\n\t\t\t\t\ttones: actionConfig.tones,\n\t\t\t\t\tselectedToneId: toneId,\n\t\t\t\t};\n\t\t\t});\n\t\t}, [\n\t\t\tenabledAIActions,\n\t\t\tdisableBuiltInAIActions,\n\t\t\tactiveActionPrompts,\n\t\t\ttoneByAction,\n\t\t\tisGenerating,\n\t\t\tsuggestionActionType,\n\t\t\tshouldShowSuggestionSession,\n\t\t\tisRephraseHighlighted,\n\t\t\tcurrentText,\n\t\t\tminCharsByAction,\n\t\t]);\n\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => {\n\t\t\t\treturn {\n\t\t\t\t\taddTextOrWrap,\n\t\t\t\t\taddText,\n\t\t\t\t\tget() {\n\t\t\t\t\t\treturn currentText;\n\t\t\t\t\t},\n\t\t\t\t\tsetCaretPosition,\n\t\t\t\t};\n\t\t\t},\n\t\t\t[addTextOrWrap, addText, currentText],\n\t\t);\n\n\t\tuseEffect(() => {\n\t\t\tif (inputValue === undefined) return;\n\t\t\tsetEditorText(inputValue || '');\n\t\t}, [inputValue, setEditorText]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!limit || !onError) return;\n\t\t\tconst nextError =\n\t\t\t\tcurrentText.length > limit ? LIMIT_REACHED : error ?? '';\n\t\t\tif (lastEmittedEditorErrorRef.current === nextError) return;\n\t\t\tlastEmittedEditorErrorRef.current = nextError;\n\t\t\tonError(nextError);\n\t\t}, [currentText, error, limit, onError]);\n\n\t\treturn (\n\t\t\t<OuterContainer>\n\t\t\t\t<EditorFooterRow>\n\t\t\t\t\t<EditorFooterTitle>\n\t\t\t\t\t\t{editorHeader ? (\n\t\t\t\t\t\t\t<TitleSmall data-test=\"body-text-for-edit-template\">\n\t\t\t\t\t\t\t\t{editorHeader}\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</EditorFooterTitle>\n\t\t\t\t\t<EditorFooterRight>\n\t\t\t\t\t\t{error && error !== LIMIT_REACHED ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<InfoIcon\n\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.content.negative}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.negative}>\n\t\t\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{limit ? (\n\t\t\t\t\t\t\t<BodyCaption\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tcolor:\n\t\t\t\t\t\t\t\t\t\terror === LIMIT_REACHED || currentText.length > limit\n\t\t\t\t\t\t\t\t\t\t\t? COLORS.content.negative\n\t\t\t\t\t\t\t\t\t\t\t: COLORS.content.secondary,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{currentText.length}/{limit}\n\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</EditorFooterRight>\n\t\t\t\t</EditorFooterRow>\n\t\t\t\t<Container isError={!!error}>\n\t\t\t\t\t{shouldShowSuggestionSession ? (\n\t\t\t\t\t\t<SuggestionSessionContainer ref={suggestionScrollRef}>\n\t\t\t\t\t\t\t<SuggestionBaselineText\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: suggestionBaseHtml }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{isGenerating ? (\n\t\t\t\t\t\t\t\t<SuggestionCandidateText aria-busy=\"true\">\n\t\t\t\t\t\t\t\t\t<SuggestionCandidateSkeleton>\n\t\t\t\t\t\t\t\t\t\t<EditorSkeletonLine width=\"96%\" />\n\t\t\t\t\t\t\t\t\t\t<EditorSkeletonLine width=\"84%\" />\n\t\t\t\t\t\t\t\t\t\t<EditorSkeletonLine width=\"68%\" />\n\t\t\t\t\t\t\t\t\t</SuggestionCandidateSkeleton>\n\t\t\t\t\t\t\t\t</SuggestionCandidateText>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<SuggestionCandidateText\n\t\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t\t__html: activeCandidateHtml,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<SuggestionControlsRow>\n\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\taria-label=\"Previous suggestion\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={isPrevSuggestionDisabled}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tsetSuggestionIndex((idx) => Math.max(0, idx - 1))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ChevronLeftIcon\n\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t<SuggestionCounter>\n\t\t\t\t\t\t\t\t\t{suggestionIndex + 1}/{suggestionCandidates.length}\n\t\t\t\t\t\t\t\t</SuggestionCounter>\n\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\taria-label=\"Next suggestion\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={isNextSuggestionDisabled}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tsetSuggestionIndex((idx) =>\n\t\t\t\t\t\t\t\t\t\t\tMath.min(suggestionCandidates.length - 1, idx + 1),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ChevronRightIcon\n\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t<Tooltip body=\"Like\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Like suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdisabled={hasFeedbackForActiveCandidate}\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleFeedback(AIFeedbackRating.LIKE)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<ThumbsUpIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t<Tooltip body=\"Dislike\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Dislike suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdisabled={hasFeedbackForActiveCandidate}\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleFeedback(AIFeedbackRating.DISLIKE)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<ThumbsDownIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t{canRegenerate ? (\n\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\tbody={isGenerating ? 'Regenerating…' : 'Regenerate'}\n\t\t\t\t\t\t\t\t\t\tplacement=\"top\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<SuggestionRegenerateButton\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Regenerate suggestion\"\n\t\t\t\t\t\t\t\t\t\t\taria-busy={isGenerating}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tdisabled={isGenerating}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tif (suggestionActionType) {\n\t\t\t\t\t\t\t\t\t\t\t\t\texecuteAIAction(suggestionActionType, true);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{isGenerating ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<RegenerateIconShimmer aria-hidden />\n\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<RewindIcon width={14} height={14} />\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</SuggestionRegenerateButton>\n\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t<Tooltip body=\"Discard\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Discard suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleRejectSuggestion}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<CrossIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t<Tooltip body=\"Accept\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Accept suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleAcceptSuggestion}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<CheckIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t</SuggestionControlsRow>\n\t\t\t\t\t\t</SuggestionSessionContainer>\n\t\t\t\t\t) : isGenerating ? (\n\t\t\t\t\t\t<EditorSkeletonContainer>\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"96%\" />\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"92%\" />\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"88%\" />\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"54%\" />\n\t\t\t\t\t\t</EditorSkeletonContainer>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<TextSpace\n\t\t\t\t\t\t\tref={textSpaceRef}\n\t\t\t\t\t\t\t{...textAreaProps}\n\t\t\t\t\t\t\tvalue={currentText}\n\t\t\t\t\t\t\tonChange={handleOnChange}\n\t\t\t\t\t\t\tonBlur={(e) => {\n\t\t\t\t\t\t\t\tif (aiTagRecomputeRef.current) {\n\t\t\t\t\t\t\t\t\tclearTimeout(aiTagRecomputeRef.current);\n\t\t\t\t\t\t\t\t\taiTagRecomputeRef.current = null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\temitPostEditAiTagRecompute(e.target.value);\n\t\t\t\t\t\t\t\ttextAreaOnBlur?.(e);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonPaste={(e) => {\n\t\t\t\t\t\t\t\tconst pastedText = e.clipboardData.getData('text');\n\t\t\t\t\t\t\t\tif (pastedText.length > LARGE_INPUT_THRESHOLD) {\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\tconst el = textSpaceRef.current;\n\t\t\t\t\t\t\t\t\tconst start = el?.selectionStart ?? 0;\n\t\t\t\t\t\t\t\t\tconst end = el?.selectionEnd ?? start;\n\t\t\t\t\t\t\t\t\t// Prefer live DOM value — `currentText` can lag the textarea for big pastes.\n\t\t\t\t\t\t\t\t\tconst base = el?.value ?? currentText;\n\t\t\t\t\t\t\t\t\tconst nextText =\n\t\t\t\t\t\t\t\t\t\tbase.slice(0, start) + pastedText + base.slice(end);\n\t\t\t\t\t\t\t\t\tsetEditorText(nextText);\n\t\t\t\t\t\t\t\t\temitChangeWithGuard(nextText);\n\t\t\t\t\t\t\t\t\tconst caret = start + pastedText.length;\n\t\t\t\t\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\t\t\t\t\tconst ta = textSpaceRef.current;\n\t\t\t\t\t\t\t\t\t\tif (!ta) return;\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tta.setSelectionRange(caret, caret);\n\t\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t\t// ignore invalid range in edge browsers\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\trows={rows}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{isInstructionInputVisible ? (\n\t\t\t\t\t\t<InstructionContainer>\n\t\t\t\t\t\t\t<InstructionInputRow>\n\t\t\t\t\t\t\t\t<EditIcon\n\t\t\t\t\t\t\t\t\twidth={18}\n\t\t\t\t\t\t\t\t\theight={18}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<InstructionInput\n\t\t\t\t\t\t\t\t\tvalue={instructionText}\n\t\t\t\t\t\t\t\t\tplaceholder=\"Add specific instructions to refine your message\"\n\t\t\t\t\t\t\t\t\tonChange={(e) =>\n\t\t\t\t\t\t\t\t\t\tsetInstructionText(stripHtmlTags(e.target.value))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<InstructionActions>\n\t\t\t\t\t\t\t\t\t<InstructionCancel\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\tsetInstructionText('');\n\t\t\t\t\t\t\t\t\t\t\tsetIsInstructionInputVisible(false);\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t\t</InstructionCancel>\n\t\t\t\t\t\t\t\t\t<InstructionImprove\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\tconst instructionToApply = instructionText.trim();\n\t\t\t\t\t\t\t\t\t\t\tif (instructionToApply) {\n\t\t\t\t\t\t\t\t\t\t\t\temitAIEvent('ai_instruction_used', {\n\t\t\t\t\t\t\t\t\t\t\t\t\taction_type: AIEditorActionTypes.REPHRASE,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t\t\t\t\t\t\t\t\t\tinstruction_text:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tanonymizeInstructionText(instructionToApply),\n\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tsetIsInstructionInputVisible(false);\n\t\t\t\t\t\t\t\t\t\t\tsetInstructionText('');\n\t\t\t\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\t\t\t\tAIEditorActionTypes.REPHRASE,\n\t\t\t\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\t\t\tinstructionToApply,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tImprove\n\t\t\t\t\t\t\t\t\t</InstructionImprove>\n\t\t\t\t\t\t\t\t</InstructionActions>\n\t\t\t\t\t\t\t</InstructionInputRow>\n\t\t\t\t\t\t\t{instructionText.trim().length > 0 &&\n\t\t\t\t\t\t\tfilteredInstructionSuggestions.length > 0 ? (\n\t\t\t\t\t\t\t\t<InstructionSuggestionList>\n\t\t\t\t\t\t\t\t\t{filteredInstructionSuggestions.map((suggestion) => (\n\t\t\t\t\t\t\t\t\t\t<InstructionSuggestionButton\n\t\t\t\t\t\t\t\t\t\t\tkey={suggestion}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tselected={instructionText === suggestion}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => setInstructionText(suggestion)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{suggestion}\n\t\t\t\t\t\t\t\t\t\t</InstructionSuggestionButton>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</InstructionSuggestionList>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</InstructionContainer>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<WhatsAppTextEditorHeader\n\t\t\t\t\t\t\tactions={actions}\n\t\t\t\t\t\t\tref={textSpaceRef}\n\t\t\t\t\t\t\tonActionSelect={onActionSelect}\n\t\t\t\t\t\t\tRightComponent={RightComponent}\n\t\t\t\t\t\t\trightActionsDisabled={shouldShowSuggestionSession || isGenerating}\n\t\t\t\t\t\t\tonEmojiClick={onEmojiAddition}\n\t\t\t\t\t\t\taiActions={aiHeaderActions}\n\t\t\t\t\t\t\tdisableAllActions={shouldShowSuggestionSession || isGenerating}\n\t\t\t\t\t\t\tinstructionActive={isInstructionInputVisible}\n\t\t\t\t\t\t\tonAIInstructionsClick={() => setIsInstructionInputVisible(true)}\n\t\t\t\t\t\t\tonAIToneChange={(actionType, toneId) => {\n\t\t\t\t\t\t\t\tsetToneByAction((prev) => ({ ...prev, [actionType]: toneId }));\n\t\t\t\t\t\t\t\tonAIToneSelect?.(actionType, toneId);\n\t\t\t\t\t\t\t\tif (actionType === AIEditorActionTypes.REPHRASE) {\n\t\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\ttoneId,\n\t\t\t\t\t\t\t\t\t\tAIActionVariant.DEFAULT,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonAIActionClick={(\n\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\tactionVariant = AIActionVariant.DEFAULT,\n\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\tif (isGenerating) return;\n\n\t\t\t\t\t\t\t\tif (shouldShowSuggestionSession) {\n\t\t\t\t\t\t\t\t\tif (suggestionActionType === actionType) {\n\t\t\t\t\t\t\t\t\t\t// Same action should not retrigger from chip;\n\t\t\t\t\t\t\t\t\t\t// regenerate is only via explicit regenerate control.\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// New action starts a fresh suggestion session.\n\t\t\t\t\t\t\t\t\tclearSuggestionSession();\n\t\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</Container>\n\t\t\t</OuterContainer>\n\t\t);\n\t},\n);\n\nWhatsAppTextEditor.displayName = 'WhatsAppTextEditor';\n\nexport type { AITagPayload } from './ai/aiTag';\nexport {\n\tAI_TAG_CHANGE_RATIO_THRESHOLD,\n\tcomputeAiTagOnAccept,\n\tlevenshteinDistance,\n} from './ai/aiTag';\n"],"names":["LIMIT_REACHED","REPHRASE_IDLE_MS","MAX_REPHRASE_HIGHLIGHTS","MAX_SUGGESTIONS","LARGE_INPUT_THRESHOLD","AI_TAG_RECOMPUTE_IDLE_MS","UTILITY_REPHRASE_PROMPT","skeletonPulse","keyframes","EditorSkeletonContainer","styled","EditorSkeletonLine","props","SuggestionSessionContainer","SuggestionBaselineText","COLORS","SuggestionCandidateText","SuggestionCandidateSkeleton","SuggestionControlsRow","SuggestionCounter","SuggestionIconButton","SuggestionRegenerateButton","RegenerateIconShimmer","InstructionContainer","InstructionInputRow","InstructionInput","InstructionActions","InstructionCancel","InstructionImprove","InstructionSuggestionList","InstructionSuggestionButton","baseWhatsappContentLang","BaseWhatsappContentLangHelper","WildCardMap","EditorActionTypes","getHighlightStorageKey","editorInstanceKey","WhatsAppTextEditor","React","onChange","onClickVariable","inputValue","RightComponent","error","limit","onError","rows","actions","editorSessionId","templateType","templateId","requestExecutor","baseUrl","endpointPath","useCase","storeId","apiAdapter","conversationId","systemId","intent","enabledAIActions","AIEditorActionTypes","disableBuiltInAIActions","promptOverrides","rephraseTones","aiActionMinChars","instructionSuggestions","DEFAULT_INSTRUCTION_SUGGESTIONS","onAnalyticsEvent","onAITagComputed","prefillWasAiGenerated","editorHeader","onAIToneSelect","onAIActionRequest","onBuildAIPrompt","textAreaOnBlur","textAreaProps","ref","textSpaceRef","useRef","currentText","setCurrentText","useState","isRephraseHighlighted","setIsRephraseHighlighted","rephraseHighlightCount","setRephraseHighlightCount","isGenerating","setIsGenerating","isInstructionInputVisible","setIsInstructionInputVisible","instructionText","setInstructionText","toneByAction","setToneByAction","suggestionBaseText","setSuggestionBaseText","suggestionCandidates","setSuggestionCandidates","suggestionIndex","setSuggestionIndex","suggestionActionType","setSuggestionActionType","suggestionScrollRef","rephraseIdleRef","highlightResetRef","aiTagRecomputeRef","prevRephraseEligibleRef","deferredHtmlRef","lastEmittedEditorErrorRef","initialAiPrefillPhaseRef","acceptedSuggestionStateRef","prefillBaselineTextRef","prefillBaselineCapturedRef","feedbackVotesByCandidate","setFeedbackVotesByCandidate","mountSessionIdRef","highlightStorageKey","useMemo","useEffect","seed","activeActionPrompts","resolveActionPrompts","filteredInstructionSuggestions","query","suggestion","minCharsByAction","DEFAULT_AI_ACTION_MIN_CHARS","rephraseMinChars","anonymizeInstructionText","useCallback","value","normalized","words","emitAIEvent","name","payload","setEditorText","nextText","prev","emitChangeWithGuard","emitPostEditAiTagRecompute","latestBaseline","recomputePayload","computeAiTagOnPostEdit","clearSuggestionSession","triggerRephraseHighlight","nextCount","triggerRephraseHighlightRef","handleOnChange","text","stripHtmlTags","acceptedSuggestion","baselineAiTextForRecompute","setCaretPosition","caretPos","elem","onActionSelect","actionType","wildCard","start","end","insertTextAtIndex","addTextOrWrap","onEmojiAddition","emoji","addText","textToAdd","html","index","cached","eligible","crossedThreshold","activeCandidate","activeFeedbackCandidateKey","hasFeedbackForActiveCandidate","suggestionBaseHtml","activeCandidateHtml","canRegenerate","shouldShowSuggestionSession","isPrevSuggestionDisabled","isNextSuggestionDisabled","node","executeAIAction","regenerateExisting","instructionOverride","toneOverrideId","actionVariant","AIActionVariant","minCharsForAction","baseConfig","config","selectedToneId","selectedTone","tone","instructionForPrompt","prompt","buildActionPrompt","result","requestAISuggestion","candidate","next","handleAcceptSuggestion","inInitialAiPhase","tagPayload","computeAiTagOnAccept","handleRejectSuggestion","handleFeedback","rating","aiHeaderActions","actionConfig","toneId","useImperativeHandle","nextError","OuterContainer","jsxs","EditorFooterRow","jsx","EditorFooterTitle","TitleSmall","EditorFooterRight","Fragment","InfoIcon","BodyCaption","Container","idx","ChevronLeftIcon","ChevronRightIcon","Tooltip","ThumbsUpIcon","ThumbsDownIcon","RewindIcon","CrossIcon","CheckIcon","TextSpace","pastedText","el","base","caret","ta","EditIcon","instructionToApply","WhatsAppTextEditorHeader"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WhatsAppTextEditor.js","sources":["../../../../src/components/WhatsAppTextEditor/WhatsAppTextEditor.tsx"],"sourcesContent":["import CheckIcon from '@src/assets/icons/check.svg';\nimport ChevronLeftIcon from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRightIcon from '@src/assets/icons/chevronRight.svg';\nimport CrossIcon from '@src/assets/icons/cross.svg';\nimport EditIcon from '@src/assets/icons/edit.svg';\nimport InfoIcon from '@src/assets/icons/info.svg';\nimport RewindIcon from '@src/assets/icons/rewind.svg';\nimport ThumbsDownIcon from '@src/assets/icons/thumb-down-line.svg';\nimport ThumbsUpIcon from '@src/assets/icons/thumb-up-line.svg';\nimport { BaseWhatsappContentLangHelper } from '@src/helpers/BaseWhatsappContentLang.helper';\nimport React, {\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { COLORS } from '@src/constants/Theme';\nimport type { ApiRequestExecutor } from '../bik-chatbot/types';\nimport type { APIAdapter } from '../bik-chatbot/types/ai';\nimport { Tooltip } from '../tooltips/Tooltip';\nimport { BodyCaption, TitleSmall } from '../TypographyStyle';\nimport {\n\tAIActionPromptConfig,\n\tAIActionPromptRegistry,\n\tDEFAULT_AI_ACTION_MIN_CHARS,\n\tDEFAULT_INSTRUCTION_SUGGESTIONS,\n\tresolveActionPrompts,\n\tTemplateType,\n} from './ai/actionRegistry';\nimport {\n\tAITagPayload,\n\tcomputeAiTagOnAccept,\n\tcomputeAiTagOnPostEdit,\n} from './ai/aiTag';\nimport { buildActionPrompt, requestAISuggestion } from './ai/api';\nimport { AIActionToneOption } from './AIRephraseButton';\nimport {\n\tContainer,\n\tEditorFooterRight,\n\tEditorFooterRow,\n\tEditorFooterTitle,\n\tOuterContainer,\n\tTextSpace,\n} from './CustomEditor.styled';\nimport {\n\tAIActionVariant,\n\tAIEditorActionType,\n\tAIEditorActionTypes,\n\tAIHeaderAction,\n\tEditorActionTypes,\n\tWhatsAppEditorRightSlotProps,\n\tWhatsAppTextEditorHeader,\n} from './WhatsAppTextEditorHeader';\n\nconst LIMIT_REACHED = 'Character limit reached';\nconst REPHRASE_IDLE_MS = 3000;\nconst MAX_REPHRASE_HIGHLIGHTS = 5;\nconst MAX_SUGGESTIONS = 3;\nconst LARGE_INPUT_THRESHOLD = 1200;\nconst AI_TAG_RECOMPUTE_IDLE_MS = 1000;\nconst UTILITY_REPHRASE_PROMPT =\n\t'Rephrase this WhatsApp utility template to improve clarity and readability while preserving variables, intent, and compliance.';\n\nconst skeletonPulse = keyframes`\n\t0% { opacity: 0.55; }\n\t50% { opacity: 1; }\n\t100% { opacity: 0.55; }\n`;\n\nconst EditorSkeletonContainer = styled.div`\n\tpadding: 14px 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tmin-height: 150px;\n`;\n\nconst EditorSkeletonLine = styled.div<{ width: string }>`\n\theight: 16px;\n\tborder-radius: 6px;\n\twidth: ${(props) => props.width};\n\tbackground: #ececef;\n\tanimation: ${skeletonPulse} 1.1s ease-in-out infinite;\n`;\n\nconst SuggestionSessionContainer = styled.div`\n\tpadding: 12px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmax-height: 260px;\n\toverflow-y: scroll;\n\tscrollbar-width: thin;\n\tscrollbar-color: #c8c8cf transparent;\n\t::-webkit-scrollbar {\n\t\twidth: 8px;\n\t}\n\t::-webkit-scrollbar-thumb {\n\t\tbackground: #c8c8cf;\n\t\tborder-radius: 8px;\n\t}\n\t::-webkit-scrollbar-track {\n\t\tbackground: transparent;\n\t}\n`;\n\nconst SuggestionBaselineText = styled.div`\n\ttext-decoration: line-through;\n\tcolor: ${COLORS.content.secondary};\n`;\n\nconst SuggestionCandidateText = styled.div`\n\tcolor: ${COLORS.content.primary};\n`;\n\nconst SuggestionCandidateSkeleton = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\twidth: 100%;\n\tmin-height: 40px;\n`;\n\nconst SuggestionControlsRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n`;\n\nconst SuggestionCounter = styled.span`\n\tcolor: ${COLORS.content.primary};\n\tfont-size: 14px;\n`;\n\nconst SuggestionIconButton = styled.button`\n\tborder: 0;\n\tbackground: transparent;\n\tpadding: 6px;\n\tborder-radius: 6px;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tcursor: pointer;\n\tcolor: ${COLORS.content.primary};\n\ttransition: background-color 0.12s ease;\n\t:not(:disabled):hover {\n\t\tbackground-color: ${COLORS.surface.hovered};\n\t}\n\t:disabled {\n\t\topacity: 0.35;\n\t\tcursor: not-allowed;\n\t}\n`;\n\n/** Regenerate stays full opacity while disabled so the loading shimmer stays visible (same pulse as editor skeleton). */\nconst SuggestionRegenerateButton = styled(SuggestionIconButton)`\n\t:disabled {\n\t\topacity: 1;\n\t\tcursor: wait;\n\t}\n`;\n\nconst RegenerateIconShimmer = styled.div`\n\twidth: 14px;\n\theight: 14px;\n\tborder-radius: 4px;\n\tbackground: #ececef;\n\tflex-shrink: 0;\n\tanimation: ${skeletonPulse} 1.1s ease-in-out infinite;\n`;\n\n/** Same bottom toolbar slot as `WhatsAppTextEditorHeader` — replaces the full icon/AI panel while open. */\nconst InstructionContainer = styled.div`\n\tbackground: ${COLORS.surface.standard};\n\tdisplay: flex;\n\tflex-direction: column;\n\tpadding: 8px 12px;\n\tgap: 10px;\n\tborder-radius: 0 0 4px 4px;\n\tposition: relative;\n`;\n\nconst InstructionInputRow = styled.div`\n\tborder: 1px solid #f5a4c0;\n\tborder-radius: 10px;\n\tpadding: 8px 10px;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tbackground: ${COLORS.surface.standard};\n`;\n\nconst InstructionInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: 0;\n\toutline: none;\n\tfont-size: 14px;\n\tbackground: transparent;\n\tcolor: ${COLORS.content.primary};\n`;\n\nconst InstructionActions = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n`;\n\nconst InstructionCancel = styled.button`\n\tborder: 0;\n\tbackground: transparent;\n\tcolor: ${COLORS.content.secondary};\n\tfont-size: 14px;\n\tfont-weight: 500;\n\tpadding: 0;\n\tcursor: pointer;\n`;\n\nconst InstructionImprove = styled.button`\n\tborder: 1px solid #5d3a72;\n\tcolor: #5d3a72;\n\tbackground: ${COLORS.surface.standard};\n\tborder-radius: 8px;\n\tpadding: 8px 14px;\n\tfont-size: 14px;\n\tline-height: 1.1;\n\tfont-weight: 600;\n\tcursor: pointer;\n`;\n\nconst InstructionSuggestionList = styled.div`\n\tmargin-top: 4px;\n\tborder-radius: 12px;\n\twidth: 331px;\n\tbackground: ${COLORS.surface.standard};\n\tbox-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);\n\toverflow: hidden;\n\tpadding: 4px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n`;\n\nconst InstructionSuggestionButton = styled.button<{ selected?: boolean }>`\n\twidth: 100%;\n\tborder: 0;\n\tborder-radius: 8px;\n\tbackground: ${(props) => (props.selected ? '#e5f3e8' : 'transparent')};\n\tcolor: ${(props) => (props.selected ? '#1e6b34' : COLORS.content.primary)};\n\ttext-align: left;\n\tpadding: 10px 12px;\n\tfont-size: 14px;\n\tline-height: 1.2;\n\tcursor: pointer;\n\t:hover {\n\t\tbackground: ${(props) =>\n\t\t\tprops.selected ? '#d9e8db' : COLORS.surface.subdued};\n\t}\n`;\n\ntype AIEventName =\n\t| 'ai_action_triggered'\n\t| 'ai_feedback_submitted'\n\t| 'ai_suggestion_accepted'\n\t| 'ai_suggestion_discarded'\n\t| 'ai_suggestion_edited'\n\t| 'ai_instruction_used';\n\nenum AIFeedbackRating {\n\tLIKE = 'like',\n\tDISLIKE = 'dislike',\n}\n\ntype AIEventPayload = {\n\taction_type: AIEditorActionType;\n\ttemplate_id?: string | number;\n\ttemplate_category?: TemplateType;\n\trating?: AIFeedbackRating;\n\tcandidate_index?: number;\n\tinstruction_text?: string;\n};\n\ntype AIActionRequestPayload = {\n\tactionType: AIEditorActionType;\n\tactionVariant?: AIActionVariant;\n\tcurrentText: string;\n\ttemplateType: TemplateType;\n\ttoneId?: string;\n\ttoneLabel?: string;\n\tinstructionText?: string;\n\tprompt: string;\n};\n\ntype AIActionPromptBuildPayload = {\n\tactionType: AIEditorActionType;\n\tactionVariant?: AIActionVariant;\n\tcurrentText: string;\n\ttemplateType: TemplateType;\n\tconfig: AIActionPromptConfig;\n\ttoneId?: string;\n\ttoneLabel?: string;\n\tinstructionText?: string;\n};\n\nexport type CustomEditorProps =\n\tReact.TextareaHTMLAttributes<HTMLTextAreaElement> & {\n\t\tonChange?: (text: string, html: string) => void;\n\t\ttext?: string;\n\t\tRightComponent?: React.ComponentType<WhatsAppEditorRightSlotProps>;\n\t\terror?: string;\n\t\tlimit?: number;\n\t\trows?: number;\n\t\tactions?: EditorActionTypes[];\n\n\t\t/**\n\t\t * Calls only for editor only error, not for errors coming from outside\n\t\t */\n\t\tonError?: (err: string) => void;\n\n\t\tonClickVariable?: (variable: string) => void;\n\t\teditorInstanceKey?: string;\n\t\teditorSessionId?: string;\n\t\ttemplateType?: TemplateType;\n\t\ttemplateId?: string | number;\n\t\trequestExecutor?: ApiRequestExecutor;\n\t\tbaseUrl?: string;\n\t\tendpointPath?: string;\n\t\tuseCase?: string;\n\t\tstoreId?: string;\n\t\tapiAdapter?: APIAdapter;\n\t\tconversationId?: string;\n\t\tsystemId?: string;\n\t\tintent?: string;\n\t\tenabledAIActions?: AIEditorActionType[];\n\t\tdisableBuiltInAIActions?: boolean;\n\t\tpromptOverrides?: AIActionPromptRegistry;\n\t\trephraseTones?: AIActionToneOption[];\n\t\taiActionMinChars?: Partial<Record<AIEditorActionType, number>>;\n\t\tinstructionSuggestions?: string[];\n\t\tonAnalyticsEvent?: (name: AIEventName, payload: AIEventPayload) => void;\n\t\t/**\n\t\t * Fires on AI-tag computations:\n\t\t * - `source: \"accept\"` after accepting a suggestion (addition check: >=50% => true)\n\t\t * - `source: \"post_edit_debounce\"` after edit idle/blur (retention check: <50% => true)\n\t\t * Persist `payload.isAiTagged` (or full payload) in host state and send on save.\n\t\t */\n\t\tonAITagComputed?: (payload: AITagPayload) => void;\n\t\t/**\n\t\t * When true, the editor body was loaded as fully AI-generated (prefill).\n\t\t * The first accepted suggestion will set `initialAiPrefillPhase` on the tag payload;\n\t\t * after that, only baseline vs accepted comparison applies.\n\t\t */\n\t\tprefillWasAiGenerated?: boolean;\n\t\t/**\n\t\t * Optional label above the editor (e.g. section title from the host).\n\t\t * When omitted, the left side of that top row is empty; limit/error stay on the right.\n\t\t */\n\t\teditorHeader?: React.ReactNode;\n\t\tonAIToneSelect?: (actionType: AIEditorActionType, toneId: string) => void;\n\t\tonAIActionRequest?: (\n\t\t\tpayload: AIActionRequestPayload,\n\t\t) => Promise<string | { body?: string }>;\n\t\tonBuildAIPrompt?: (payload: AIActionPromptBuildPayload) => string;\n\t\tonBlur?: React.FocusEventHandler<HTMLTextAreaElement>;\n\t};\nexport type CustomEditorRef = {\n\taddTextOrWrap: (textToAdd: string) => {\n\t\ttext: string;\n\t\thtml: string;\n\t};\n\taddText: (textToAdd: string) => {\n\t\ttext: string;\n\t\thtml: string;\n\t};\n\tget: () => string;\n\tsetCaretPosition(caretPos: number): void;\n};\n\nconst baseWhatsappContentLang = new BaseWhatsappContentLangHelper();\n\nconst WildCardMap: { [key in EditorActionTypes]?: string } = {\n\t[EditorActionTypes.BOLD]: '*',\n\t[EditorActionTypes.ITALIC]: '_',\n\t[EditorActionTypes.STRIKETHROUGH]: '~',\n};\n\nfunction getHighlightStorageKey(editorInstanceKey?: string) {\n\treturn `whatsapp-editor-rephrase-highlight-${editorInstanceKey || 'default'}`;\n}\n\nexport const WhatsAppTextEditor = React.forwardRef<\n\tCustomEditorRef,\n\tCustomEditorProps\n>(\n\t(\n\t\t{\n\t\t\tonChange,\n\t\t\tonClickVariable,\n\t\t\ttext: inputValue,\n\t\t\tRightComponent,\n\t\t\terror,\n\t\t\tlimit,\n\t\t\tonError,\n\t\t\trows,\n\t\t\tactions,\n\t\t\teditorInstanceKey,\n\t\t\teditorSessionId,\n\t\t\ttemplateType = 'marketing',\n\t\t\ttemplateId,\n\t\t\trequestExecutor,\n\t\t\tbaseUrl,\n\t\t\tendpointPath,\n\t\t\tuseCase,\n\t\t\tstoreId,\n\t\t\tapiAdapter,\n\t\t\tconversationId = 'whatsapp-template-editor',\n\t\t\tsystemId = 'whatsapp-writer',\n\t\t\tintent = 'default',\n\t\t\tenabledAIActions = [\n\t\t\t\tAIEditorActionTypes.REPHRASE,\n\t\t\t\tAIEditorActionTypes.SHORTEN,\n\t\t\t\tAIEditorActionTypes.EXPAND,\n\t\t\t\tAIEditorActionTypes.EMOJIFY,\n\t\t\t],\n\t\t\tdisableBuiltInAIActions = false,\n\t\t\tpromptOverrides,\n\t\t\trephraseTones,\n\t\t\taiActionMinChars,\n\t\t\tinstructionSuggestions = DEFAULT_INSTRUCTION_SUGGESTIONS,\n\t\t\tonAnalyticsEvent,\n\t\t\tonAITagComputed,\n\t\t\tprefillWasAiGenerated = false,\n\t\t\teditorHeader,\n\t\t\tonAIToneSelect,\n\t\t\tonAIActionRequest,\n\t\t\tonBuildAIPrompt,\n\t\t\tonBlur: textAreaOnBlur,\n\t\t\t...textAreaProps\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst textSpaceRef = useRef<HTMLTextAreaElement>(null);\n\t\tconst [currentText, setCurrentText] = useState(inputValue || '');\n\t\tconst [isRephraseHighlighted, setIsRephraseHighlighted] = useState(false);\n\t\tconst [rephraseHighlightCount, setRephraseHighlightCount] = useState(0);\n\t\tconst [isGenerating, setIsGenerating] = useState(false);\n\t\tconst [isInstructionInputVisible, setIsInstructionInputVisible] =\n\t\t\tuseState(false);\n\t\tconst [instructionText, setInstructionText] = useState('');\n\t\tconst [toneByAction, setToneByAction] = useState<\n\t\t\tPartial<Record<AIEditorActionType, string>>\n\t\t>({});\n\t\tconst [suggestionBaseText, setSuggestionBaseText] = useState<string | null>(\n\t\t\tnull,\n\t\t);\n\t\tconst [suggestionCandidates, setSuggestionCandidates] = useState<string[]>(\n\t\t\t[],\n\t\t);\n\t\tconst [suggestionIndex, setSuggestionIndex] = useState(0);\n\t\tconst [suggestionActionType, setSuggestionActionType] =\n\t\t\tuseState<AIEditorActionType | null>(null);\n\t\tconst suggestionScrollRef = useRef<HTMLDivElement | null>(null);\n\t\tconst rephraseIdleRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\t\tconst highlightResetRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\t\tnull,\n\t\t);\n\t\tconst aiTagRecomputeRef = useRef<ReturnType<typeof setTimeout> | null>(\n\t\t\tnull,\n\t\t);\n\t\t/**\n\t\t * Prior eligibility for rephrase nudge (null = not initialized).\n\t\t * Matches the chip: non-empty trim and length ≥ min — same as `aiHeaderActions` disabled rules.\n\t\t */\n\t\tconst prevRephraseEligibleRef = useRef<boolean | null>(null);\n\t\tconst deferredHtmlRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\t\tconst lastEmittedEditorErrorRef = useRef<string | null>(null);\n\t\t/** First accept after full-AI prefill (`prefillWasAiGenerated`); cleared after one accept. */\n\t\tconst initialAiPrefillPhaseRef = useRef(!!prefillWasAiGenerated);\n\t\tconst acceptedSuggestionStateRef = useRef<{\n\t\t\tacceptedText: string;\n\t\t\tbaselineText: string;\n\t\t\tactionType: AIEditorActionType;\n\t\t\teditedEventEmitted: boolean;\n\t\t} | null>(null);\n\t\t/** Original prefill body for AI tag recompute; seeded once, never the live `currentText` fallback. */\n\t\tconst prefillBaselineTextRef = useRef('');\n\t\tconst prefillBaselineCapturedRef = useRef(false);\n\t\tconst [feedbackVotesByCandidate, setFeedbackVotesByCandidate] = useState<\n\t\t\tPartial<Record<string, AIFeedbackRating>>\n\t\t>({});\n\t\tconst mountSessionIdRef = useRef(\n\t\t\t`mount-${Date.now().toString(36)}-${Math.random()\n\t\t\t\t.toString(36)\n\t\t\t\t.slice(2, 8)}`,\n\t\t);\n\t\tconst highlightStorageKey = useMemo(() => {\n\t\t\treturn getHighlightStorageKey(\n\t\t\t\t`${editorInstanceKey || 'default'}-${\n\t\t\t\t\teditorSessionId || mountSessionIdRef.current\n\t\t\t\t}`,\n\t\t\t);\n\t\t}, [editorInstanceKey, editorSessionId]);\n\n\t\tuseEffect(() => {\n\t\t\tinitialAiPrefillPhaseRef.current = !!prefillWasAiGenerated;\n\t\t}, [prefillWasAiGenerated, editorInstanceKey]);\n\n\t\tuseEffect(() => {\n\t\t\tprefillBaselineCapturedRef.current = false;\n\t\t\tprefillBaselineTextRef.current = '';\n\t\t}, [editorInstanceKey, editorSessionId]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!prefillWasAiGenerated) {\n\t\t\t\tprefillBaselineCapturedRef.current = false;\n\t\t\t\tprefillBaselineTextRef.current = '';\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (prefillBaselineCapturedRef.current) return;\n\t\t\tconst seed = inputValue ?? '';\n\t\t\tif (seed.length > 0) {\n\t\t\t\tprefillBaselineTextRef.current = seed;\n\t\t\t\tprefillBaselineCapturedRef.current = true;\n\t\t\t}\n\t\t}, [prefillWasAiGenerated, inputValue, editorInstanceKey, editorSessionId]);\n\n\t\tconst activeActionPrompts = useMemo(() => {\n\t\t\treturn resolveActionPrompts(templateType, promptOverrides, rephraseTones);\n\t\t}, [promptOverrides, rephraseTones, templateType]);\n\n\t\tconst filteredInstructionSuggestions = useMemo(() => {\n\t\t\tconst query = instructionText.trim().toLowerCase();\n\t\t\tif (!query) return [];\n\t\t\treturn instructionSuggestions.filter((suggestion) =>\n\t\t\t\tsuggestion.toLowerCase().includes(query),\n\t\t\t);\n\t\t}, [instructionSuggestions, instructionText]);\n\n\t\tconst minCharsByAction = useMemo(() => {\n\t\t\treturn {\n\t\t\t\t...DEFAULT_AI_ACTION_MIN_CHARS,\n\t\t\t\t...(aiActionMinChars || {}),\n\t\t\t};\n\t\t}, [aiActionMinChars]);\n\n\t\tconst rephraseMinChars =\n\t\t\tminCharsByAction[AIEditorActionTypes.REPHRASE] ||\n\t\t\tDEFAULT_AI_ACTION_MIN_CHARS[AIEditorActionTypes.REPHRASE];\n\n\t\tconst anonymizeInstructionText = useCallback((value: string) => {\n\t\t\tconst normalized = value.trim().replace(/\\s+/g, ' ');\n\t\t\tif (!normalized) return '';\n\t\t\tconst words = normalized.split(' ').length;\n\t\t\treturn `[anonymized:length_${normalized.length}:words_${words}]`;\n\t\t}, []);\n\n\t\tconst emitAIEvent = useCallback(\n\t\t\t(name: AIEventName, payload: AIEventPayload) => {\n\t\t\t\tonAnalyticsEvent?.(name, payload);\n\t\t\t},\n\t\t\t[onAnalyticsEvent],\n\t\t);\n\n\t\tconst setEditorText = useCallback((nextText: string) => {\n\t\t\tsetCurrentText((prev) => (prev === nextText ? prev : nextText));\n\t\t}, []);\n\n\t\tconst emitChangeWithGuard = useCallback(\n\t\t\t(nextText: string) => {\n\t\t\t\tif (deferredHtmlRef.current) {\n\t\t\t\t\tclearTimeout(deferredHtmlRef.current);\n\t\t\t\t}\n\t\t\t\tif (nextText.length > LARGE_INPUT_THRESHOLD) {\n\t\t\t\t\tonChange?.(nextText, nextText);\n\t\t\t\t\tdeferredHtmlRef.current = setTimeout(() => {\n\t\t\t\t\t\tonChange?.(nextText, baseWhatsappContentLang.getHTML(nextText));\n\t\t\t\t\t}, 16);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonChange?.(nextText, baseWhatsappContentLang.getHTML(nextText));\n\t\t\t},\n\t\t\t[onChange],\n\t\t);\n\n\t\tconst emitPostEditAiTagRecompute = useCallback(\n\t\t\t(nextText: string) => {\n\t\t\t\tconst latest = acceptedSuggestionStateRef.current;\n\t\t\t\tconst latestBaseline =\n\t\t\t\t\tlatest?.acceptedText ||\n\t\t\t\t\t(prefillWasAiGenerated ? prefillBaselineTextRef.current : '');\n\t\t\t\tif (!latestBaseline) return;\n\t\t\t\tif (nextText === latestBaseline) return;\n\t\t\t\tconst recomputePayload = computeAiTagOnPostEdit({\n\t\t\t\t\tacceptedAiText: latestBaseline,\n\t\t\t\t\tcurrentEditedText: nextText,\n\t\t\t\t});\n\t\t\t\tonAITagComputed?.({\n\t\t\t\t\t...recomputePayload,\n\t\t\t\t\tsource: 'post_edit_debounce',\n\t\t\t\t});\n\t\t\t},\n\t\t\t[onAITagComputed, prefillWasAiGenerated],\n\t\t);\n\n\t\tconst clearSuggestionSession = useCallback(() => {\n\t\t\tsetSuggestionBaseText(null);\n\t\t\tsetSuggestionCandidates([]);\n\t\t\tsetSuggestionIndex(0);\n\t\t\tsetSuggestionActionType(null);\n\t\t\tsetFeedbackVotesByCandidate({});\n\t\t}, []);\n\n\t\tconst triggerRephraseHighlight = useCallback(() => {\n\t\t\tif (isGenerating) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!!suggestionBaseText && suggestionCandidates.length > 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (rephraseHighlightCount >= MAX_REPHRASE_HIGHLIGHTS) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nextCount = rephraseHighlightCount + 1;\n\t\t\tsetRephraseHighlightCount(nextCount);\n\t\t\tif (typeof window !== 'undefined' && editorInstanceKey) {\n\t\t\t\tsessionStorage.setItem(highlightStorageKey, String(nextCount));\n\t\t\t}\n\t\t\tsetIsRephraseHighlighted(true);\n\t\t\tif (highlightResetRef.current) {\n\t\t\t\tclearTimeout(highlightResetRef.current);\n\t\t\t}\n\t\t\thighlightResetRef.current = setTimeout(() => {\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t}, 1200);\n\t\t}, [\n\t\t\teditorInstanceKey,\n\t\t\thighlightStorageKey,\n\t\t\tisGenerating,\n\t\t\tsuggestionBaseText,\n\t\t\tsuggestionCandidates,\n\t\t\trephraseHighlightCount,\n\t\t]);\n\n\t\tconst triggerRephraseHighlightRef = useRef(triggerRephraseHighlight);\n\t\ttriggerRephraseHighlightRef.current = triggerRephraseHighlight;\n\n\t\tfunction handleOnChange(e: React.ChangeEvent<HTMLTextAreaElement>) {\n\t\t\tconst text = e.target.value;\n\t\t\tconst acceptedSuggestion = acceptedSuggestionStateRef.current;\n\t\t\tif (\n\t\t\t\tacceptedSuggestion &&\n\t\t\t\t!acceptedSuggestion.editedEventEmitted &&\n\t\t\t\ttext !== acceptedSuggestion.acceptedText\n\t\t\t) {\n\t\t\t\tacceptedSuggestionStateRef.current = {\n\t\t\t\t\t...acceptedSuggestion,\n\t\t\t\t\teditedEventEmitted: true,\n\t\t\t\t};\n\t\t\t\temitAIEvent('ai_suggestion_edited', {\n\t\t\t\t\taction_type: acceptedSuggestion.actionType,\n\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (aiTagRecomputeRef.current) {\n\t\t\t\tclearTimeout(aiTagRecomputeRef.current);\n\t\t\t\taiTagRecomputeRef.current = null;\n\t\t\t}\n\t\t\tconst baselineAiTextForRecompute =\n\t\t\t\tacceptedSuggestion?.acceptedText ||\n\t\t\t\t(prefillWasAiGenerated ? prefillBaselineTextRef.current : '');\n\t\t\tif (baselineAiTextForRecompute && text !== baselineAiTextForRecompute) {\n\t\t\t\taiTagRecomputeRef.current = setTimeout(() => {\n\t\t\t\t\temitPostEditAiTagRecompute(text);\n\t\t\t\t}, AI_TAG_RECOMPUTE_IDLE_MS);\n\t\t\t}\n\t\t\tsetEditorText(text);\n\t\t\temitChangeWithGuard(text);\n\t\t}\n\n\t\tfunction setCaretPosition(caretPos: number) {\n\t\t\tconst elem = textSpaceRef?.current;\n\n\t\t\tif (elem != null) {\n\t\t\t\tif (elem.selectionStart) {\n\t\t\t\t\telem.focus();\n\t\t\t\t\telem.selectionEnd = caretPos;\n\t\t\t\t} else elem.focus();\n\t\t\t}\n\t\t}\n\n\t\tfunction onActionSelect(actionType: EditorActionTypes) {\n\t\t\tconst wildCard = WildCardMap[actionType];\n\t\t\tif (wildCard && textSpaceRef.current) {\n\t\t\t\tconst start = textSpaceRef.current.selectionStart;\n\t\t\t\tconst end = textSpaceRef.current.selectionEnd;\n\n\t\t\t\tif (start === end) {\n\t\t\t\t\tconst { text } = insertTextAtIndex(wildCard, start);\n\t\t\t\t\tsetCaretPosition(start + 1);\n\t\t\t\t\temitChangeWithGuard(text);\n\t\t\t\t} else {\n\t\t\t\t\tconst { text } = addTextOrWrap(wildCard);\n\t\t\t\t\temitChangeWithGuard(text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction onEmojiAddition(emoji: string) {\n\t\t\tconst { text } = addText(emoji);\n\t\t\temitChangeWithGuard(text);\n\t\t}\n\n\t\tfunction addTextOrWrap(textToAdd?: string) {\n\t\t\tlet text = textSpaceRef.current?.value ?? '';\n\n\t\t\tif (textSpaceRef.current && textToAdd) {\n\t\t\t\tconst start = textSpaceRef.current.selectionStart;\n\t\t\t\tconst end = textSpaceRef.current.selectionEnd;\n\n\t\t\t\tconst wildCard = textToAdd;\n\t\t\t\tif (start === end) {\n\t\t\t\t\t/** nothing is selected */\n\t\t\t\t\t/** so append the wildcard at the end */\n\n\t\t\t\t\treturn addText(wildCard);\n\t\t\t\t} else {\n\t\t\t\t\ttext = baseWhatsappContentLang.wrappWildcard(\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\tend,\n\t\t\t\t\t\twildCard,\n\t\t\t\t\t\ttext!,\n\t\t\t\t\t);\n\t\t\t\t\tconst html = baseWhatsappContentLang.getHTML(text);\n\t\t\t\t\tsetEditorText(text);\n\t\t\t\t\treturn { text, html };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { text: text!, html: text! };\n\t\t}\n\n\t\tfunction addText(textToAdd: string) {\n\t\t\tconst text = textSpaceRef.current?.value ?? '';\n\n\t\t\tif (textSpaceRef.current && textToAdd) {\n\t\t\t\tconst start = textSpaceRef.current.selectionStart;\n\t\t\t\tconst end = textSpaceRef.current.selectionEnd;\n\t\t\t\tif (start === end) {\n\t\t\t\t\treturn insertTextAtIndex(textToAdd, start);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { text: text!, html: text! };\n\t\t}\n\n\t\tfunction insertTextAtIndex(textToAdd: string, index: number) {\n\t\t\tlet text = textSpaceRef.current?.value ?? '';\n\n\t\t\ttext = text.slice(0, index) + textToAdd + text.slice(index);\n\t\t\tconst html = baseWhatsappContentLang.getHTML(text);\n\t\t\tsetEditorText(text);\n\t\t\treturn { text, html };\n\t\t}\n\n\t\tuseEffect(() => {\n\t\t\tif (typeof window === 'undefined' || !editorInstanceKey) return;\n\t\t\tconst cached = Number(sessionStorage.getItem(highlightStorageKey) || '0');\n\t\t\tif (!Number.isNaN(cached)) {\n\t\t\t\tsetRephraseHighlightCount(cached);\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tsessionStorage.removeItem(highlightStorageKey);\n\t\t\t};\n\t\t}, [editorInstanceKey, highlightStorageKey]);\n\n\t\tuseEffect(() => {\n\t\t\tif (isGenerating) {\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t\t\trephraseIdleRef.current = null;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!!suggestionBaseText && suggestionCandidates.length > 0) {\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t\t\trephraseIdleRef.current = null;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst eligible =\n\t\t\t\t!!currentText.trim() && currentText.length >= rephraseMinChars;\n\n\t\t\tif (prevRephraseEligibleRef.current === null) {\n\t\t\t\tprevRephraseEligibleRef.current = eligible;\n\t\t\t\tif (eligible) {\n\t\t\t\t\trephraseIdleRef.current = setTimeout(() => {\n\t\t\t\t\t\ttriggerRephraseHighlightRef.current();\n\t\t\t\t\t}, REPHRASE_IDLE_MS);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!eligible) {\n\t\t\t\tprevRephraseEligibleRef.current = false;\n\t\t\t\tsetIsRephraseHighlighted(false);\n\t\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t\t\trephraseIdleRef.current = null;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst crossedThreshold = !prevRephraseEligibleRef.current && eligible;\n\t\t\tprevRephraseEligibleRef.current = true;\n\n\t\t\tif (crossedThreshold) {\n\t\t\t\ttriggerRephraseHighlightRef.current();\n\t\t\t}\n\n\t\t\tif (rephraseIdleRef.current) {\n\t\t\t\tclearTimeout(rephraseIdleRef.current);\n\t\t\t}\n\t\t\trephraseIdleRef.current = setTimeout(() => {\n\t\t\t\ttriggerRephraseHighlightRef.current();\n\t\t\t}, REPHRASE_IDLE_MS);\n\t\t}, [\n\t\t\tcurrentText,\n\t\t\tisGenerating,\n\t\t\trephraseMinChars,\n\t\t\tsuggestionBaseText,\n\t\t\tsuggestionCandidates,\n\t\t]);\n\n\t\tuseEffect(() => {\n\t\t\treturn () => {\n\t\t\t\tif (rephraseIdleRef.current) clearTimeout(rephraseIdleRef.current);\n\t\t\t\tif (highlightResetRef.current) clearTimeout(highlightResetRef.current);\n\t\t\t\tif (deferredHtmlRef.current) clearTimeout(deferredHtmlRef.current);\n\t\t\t\tif (aiTagRecomputeRef.current) clearTimeout(aiTagRecomputeRef.current);\n\t\t\t};\n\t\t}, []);\n\n\t\tconst activeCandidate = suggestionCandidates[suggestionIndex] || '';\n\t\tconst activeFeedbackCandidateKey = useMemo(() => {\n\t\t\tif (!suggestionActionType || !activeCandidate) return null;\n\t\t\treturn `${suggestionActionType}-${suggestionIndex}-${activeCandidate}`;\n\t\t}, [activeCandidate, suggestionActionType, suggestionIndex]);\n\t\tconst hasFeedbackForActiveCandidate = !!(\n\t\t\tactiveFeedbackCandidateKey &&\n\t\t\tfeedbackVotesByCandidate[activeFeedbackCandidateKey]\n\t\t);\n\t\tconst suggestionBaseHtml = useMemo(\n\t\t\t() => baseWhatsappContentLang.getHTML(suggestionBaseText || ''),\n\t\t\t[suggestionBaseText],\n\t\t);\n\t\tconst activeCandidateHtml = useMemo(\n\t\t\t() => baseWhatsappContentLang.getHTML(activeCandidate),\n\t\t\t[activeCandidate],\n\t\t);\n\t\tconst canRegenerate = suggestionCandidates.length < MAX_SUGGESTIONS;\n\t\tconst shouldShowSuggestionSession =\n\t\t\t!!suggestionBaseText && suggestionCandidates.length > 0;\n\t\tconst isPrevSuggestionDisabled =\n\t\t\tsuggestionCandidates.length <= 1 || suggestionIndex <= 0;\n\t\tconst isNextSuggestionDisabled =\n\t\t\tsuggestionCandidates.length <= 1 ||\n\t\t\tsuggestionIndex >= suggestionCandidates.length - 1;\n\n\t\tuseEffect(() => {\n\t\t\tif (!shouldShowSuggestionSession) return;\n\t\t\tconst node = suggestionScrollRef.current;\n\t\t\tif (!node) return;\n\t\t\tnode.scrollTop = node.scrollHeight;\n\t\t}, [activeCandidate, shouldShowSuggestionSession, isGenerating]);\n\n\t\tconst executeAIAction = useCallback(\n\t\t\tasync (\n\t\t\t\tactionType: AIEditorActionType,\n\t\t\t\tregenerateExisting = false,\n\t\t\t\tinstructionOverride?: string,\n\t\t\t\ttoneOverrideId?: string,\n\t\t\t\tactionVariant: AIActionVariant = AIActionVariant.DEFAULT,\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\t!onAIActionRequest &&\n\t\t\t\t\t!apiAdapter &&\n\t\t\t\t\t(!requestExecutor || !baseUrl)\n\t\t\t\t) {\n\t\t\t\t\tonError?.('AI configuration missing');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!currentText.trim()) return;\n\t\t\t\tconst minCharsForAction =\n\t\t\t\t\tminCharsByAction[actionType] ||\n\t\t\t\t\tDEFAULT_AI_ACTION_MIN_CHARS[actionType] ||\n\t\t\t\t\t50;\n\t\t\t\tif (currentText.length < minCharsForAction) return;\n\t\t\t\tif (isGenerating) return;\n\t\t\t\tif (regenerateExisting && !canRegenerate) return;\n\n\t\t\t\tconst baseConfig = activeActionPrompts[actionType];\n\t\t\t\tconst config =\n\t\t\t\t\tactionType === AIEditorActionTypes.REPHRASE &&\n\t\t\t\t\ttemplateType === 'utility' &&\n\t\t\t\t\tactionVariant === AIActionVariant.REPHRASE\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...baseConfig,\n\t\t\t\t\t\t\t\tlabel: 'Rephrase',\n\t\t\t\t\t\t\t\tbasePrompt: UTILITY_REPHRASE_PROMPT,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: baseConfig;\n\t\t\t\t// Tone is sent only after explicit user selection (or explicit override),\n\t\t\t\t// not from default tone metadata.\n\t\t\t\tconst selectedToneId = toneOverrideId || toneByAction[actionType];\n\t\t\t\tconst selectedTone = config.tones?.find(\n\t\t\t\t\t(tone) => tone.id === selectedToneId,\n\t\t\t\t);\n\t\t\t\tconst instructionForPrompt =\n\t\t\t\t\tinstructionOverride !== undefined\n\t\t\t\t\t\t? instructionOverride\n\t\t\t\t\t\t: instructionText;\n\t\t\t\tconst prompt =\n\t\t\t\t\tonBuildAIPrompt?.({\n\t\t\t\t\t\tactionType,\n\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\tcurrentText,\n\t\t\t\t\t\ttemplateType,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\ttoneId: selectedToneId,\n\t\t\t\t\t\ttoneLabel: selectedTone?.label,\n\t\t\t\t\t\tinstructionText: instructionForPrompt || undefined,\n\t\t\t\t\t}) ||\n\t\t\t\t\tbuildActionPrompt({\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tcurrentText,\n\t\t\t\t\t\tselectedToneId,\n\t\t\t\t\t\tinstructionText: instructionForPrompt,\n\t\t\t\t\t});\n\n\t\t\t\tsetIsGenerating(true);\n\t\t\t\temitAIEvent('ai_action_triggered', {\n\t\t\t\t\taction_type: actionType,\n\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t\ttemplate_category: templateType,\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tconst result = onAIActionRequest\n\t\t\t\t\t\t? await onAIActionRequest({\n\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\t\t\tcurrentText,\n\t\t\t\t\t\t\t\ttemplateType,\n\t\t\t\t\t\t\t\ttoneId: selectedToneId,\n\t\t\t\t\t\t\t\ttoneLabel: selectedTone?.label,\n\t\t\t\t\t\t\t\tinstructionText: instructionForPrompt || undefined,\n\t\t\t\t\t\t\t\tprompt,\n\t\t\t\t\t\t })\n\t\t\t\t\t\t: await requestAISuggestion({\n\t\t\t\t\t\t\t\tapiAdapter,\n\t\t\t\t\t\t\t\trequestExecutor,\n\t\t\t\t\t\t\t\tbaseUrl,\n\t\t\t\t\t\t\t\tendpointPath,\n\t\t\t\t\t\t\t\tprompt,\n\t\t\t\t\t\t\t\tintent,\n\t\t\t\t\t\t\t\tconversationId,\n\t\t\t\t\t\t\t\tsystemId,\n\t\t\t\t\t\t\t\tuseCase,\n\t\t\t\t\t\t\t\tstoreId,\n\t\t\t\t\t\t });\n\t\t\t\t\tconst candidate =\n\t\t\t\t\t\ttypeof result === 'string'\n\t\t\t\t\t\t\t? result.trim()\n\t\t\t\t\t\t\t: (result?.body || '').trim();\n\t\t\t\t\tif (!candidate) return;\n\t\t\t\t\tif (!regenerateExisting) {\n\t\t\t\t\t\tsetSuggestionBaseText(currentText);\n\t\t\t\t\t\tsetSuggestionActionType(actionType);\n\t\t\t\t\t\tsetSuggestionCandidates([candidate]);\n\t\t\t\t\t\tsetSuggestionIndex(0);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tsetSuggestionCandidates((prev) => {\n\t\t\t\t\t\tconst next = [...prev, candidate].slice(0, MAX_SUGGESTIONS);\n\t\t\t\t\t\tsetSuggestionIndex(next.length - 1);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t} catch (e) {\n\t\t\t\t\tonError?.('Failed to generate AI suggestion');\n\t\t\t\t} finally {\n\t\t\t\t\tsetIsGenerating(false);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[\n\t\t\t\trequestExecutor,\n\t\t\t\tbaseUrl,\n\t\t\t\tcurrentText,\n\t\t\t\tisGenerating,\n\t\t\t\tcanRegenerate,\n\t\t\t\tactiveActionPrompts,\n\t\t\t\ttoneByAction,\n\t\t\t\tinstructionText,\n\t\t\t\temitAIEvent,\n\t\t\t\ttemplateId,\n\t\t\t\tendpointPath,\n\t\t\t\tapiAdapter,\n\t\t\t\tintent,\n\t\t\t\tconversationId,\n\t\t\t\tsystemId,\n\t\t\t\tuseCase,\n\t\t\t\tstoreId,\n\t\t\t\ttemplateType,\n\t\t\t\tonError,\n\t\t\t\tminCharsByAction,\n\t\t\t\tonAIActionRequest,\n\t\t\t\tonBuildAIPrompt,\n\t\t\t],\n\t\t);\n\n\t\tconst handleAcceptSuggestion = useCallback(() => {\n\t\t\tif (!activeCandidate || !suggestionBaseText || !suggestionActionType)\n\t\t\t\treturn;\n\t\t\tsetEditorText(activeCandidate);\n\t\t\temitChangeWithGuard(activeCandidate);\n\t\t\temitAIEvent('ai_suggestion_accepted', {\n\t\t\t\taction_type: suggestionActionType,\n\t\t\t\ttemplate_id: templateId,\n\t\t\t});\n\t\t\tacceptedSuggestionStateRef.current = {\n\t\t\t\tacceptedText: activeCandidate,\n\t\t\t\tbaselineText: suggestionBaseText,\n\t\t\t\tactionType: suggestionActionType,\n\t\t\t\teditedEventEmitted: false,\n\t\t\t};\n\n\t\t\tconst inInitialAiPhase = initialAiPrefillPhaseRef.current;\n\t\t\tconst tagPayload = computeAiTagOnAccept({\n\t\t\t\tbaselineText: suggestionBaseText,\n\t\t\t\tacceptedText: activeCandidate,\n\t\t\t\tinitialAiPrefillPhase: inInitialAiPhase,\n\t\t\t});\n\t\t\tif (inInitialAiPhase) {\n\t\t\t\tinitialAiPrefillPhaseRef.current = false;\n\t\t\t}\n\t\t\tonAITagComputed?.({\n\t\t\t\t...tagPayload,\n\t\t\t\tsource: 'accept',\n\t\t\t});\n\t\t\tclearSuggestionSession();\n\t\t}, [\n\t\t\tactiveCandidate,\n\t\t\tsuggestionBaseText,\n\t\t\tsuggestionActionType,\n\t\t\tsetEditorText,\n\t\t\temitChangeWithGuard,\n\t\t\temitAIEvent,\n\t\t\ttemplateId,\n\t\t\tonAITagComputed,\n\t\t\tclearSuggestionSession,\n\t\t]);\n\n\t\tconst handleRejectSuggestion = useCallback(() => {\n\t\t\tif (!suggestionActionType) return;\n\t\t\temitAIEvent('ai_suggestion_discarded', {\n\t\t\t\taction_type: suggestionActionType,\n\t\t\t\ttemplate_id: templateId,\n\t\t\t});\n\t\t\tclearSuggestionSession();\n\t\t}, [clearSuggestionSession, emitAIEvent, suggestionActionType, templateId]);\n\n\t\tconst handleFeedback = useCallback(\n\t\t\t(rating: AIFeedbackRating) => {\n\t\t\t\tif (!suggestionActionType || !activeFeedbackCandidateKey) return;\n\t\t\t\tif (feedbackVotesByCandidate[activeFeedbackCandidateKey]) return;\n\t\t\t\tsetFeedbackVotesByCandidate((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\t[activeFeedbackCandidateKey]: rating,\n\t\t\t\t}));\n\t\t\t\temitAIEvent('ai_feedback_submitted', {\n\t\t\t\t\taction_type: suggestionActionType,\n\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t\trating,\n\t\t\t\t\tcandidate_index: suggestionIndex + 1,\n\t\t\t\t});\n\t\t\t},\n\t\t\t[\n\t\t\t\tactiveFeedbackCandidateKey,\n\t\t\t\temitAIEvent,\n\t\t\t\tfeedbackVotesByCandidate,\n\t\t\t\tsuggestionActionType,\n\t\t\t\tsuggestionIndex,\n\t\t\t\ttemplateId,\n\t\t\t],\n\t\t);\n\n\t\tconst aiHeaderActions: AIHeaderAction[] = useMemo(() => {\n\t\t\tif (disableBuiltInAIActions) return [];\n\t\t\treturn enabledAIActions.map((actionType) => {\n\t\t\t\tconst actionConfig = activeActionPrompts[actionType];\n\t\t\t\tconst toneId = toneByAction[actionType];\n\t\t\t\treturn {\n\t\t\t\t\ttype: actionType,\n\t\t\t\t\tlabel: actionConfig.label,\n\t\t\t\t\tisPrimary: actionType === AIEditorActionTypes.REPHRASE,\n\t\t\t\t\tloading: isGenerating && suggestionActionType === actionType,\n\t\t\t\t\thighlighted:\n\t\t\t\t\t\tactionType === AIEditorActionTypes.REPHRASE &&\n\t\t\t\t\t\tisRephraseHighlighted,\n\t\t\t\t\tdisabled:\n\t\t\t\t\t\t!currentText.trim() ||\n\t\t\t\t\t\tcurrentText.length <\n\t\t\t\t\t\t\t(minCharsByAction[actionType] ||\n\t\t\t\t\t\t\t\tDEFAULT_AI_ACTION_MIN_CHARS[actionType] ||\n\t\t\t\t\t\t\t\t50) ||\n\t\t\t\t\t\tisGenerating ||\n\t\t\t\t\t\t(shouldShowSuggestionSession &&\n\t\t\t\t\t\t\tsuggestionActionType === actionType),\n\t\t\t\t\tshowToneDropdown:\n\t\t\t\t\t\tactionType === AIEditorActionTypes.REPHRASE &&\n\t\t\t\t\t\t!!actionConfig.tones?.length,\n\t\t\t\t\ttones: actionConfig.tones,\n\t\t\t\t\tselectedToneId: toneId,\n\t\t\t\t};\n\t\t\t});\n\t\t}, [\n\t\t\tenabledAIActions,\n\t\t\tdisableBuiltInAIActions,\n\t\t\tactiveActionPrompts,\n\t\t\ttoneByAction,\n\t\t\tisGenerating,\n\t\t\tsuggestionActionType,\n\t\t\tshouldShowSuggestionSession,\n\t\t\tisRephraseHighlighted,\n\t\t\tcurrentText,\n\t\t\tminCharsByAction,\n\t\t]);\n\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => {\n\t\t\t\treturn {\n\t\t\t\t\taddTextOrWrap,\n\t\t\t\t\taddText,\n\t\t\t\t\tget() {\n\t\t\t\t\t\treturn currentText;\n\t\t\t\t\t},\n\t\t\t\t\tsetCaretPosition,\n\t\t\t\t};\n\t\t\t},\n\t\t\t[addTextOrWrap, addText, currentText],\n\t\t);\n\n\t\tuseEffect(() => {\n\t\t\tif (inputValue === undefined) return;\n\t\t\tsetEditorText(inputValue || '');\n\t\t}, [inputValue, setEditorText]);\n\n\t\tuseEffect(() => {\n\t\t\tif (!limit || !onError) return;\n\t\t\tconst nextError =\n\t\t\t\tcurrentText.length > limit ? LIMIT_REACHED : error ?? '';\n\t\t\tif (lastEmittedEditorErrorRef.current === nextError) return;\n\t\t\tlastEmittedEditorErrorRef.current = nextError;\n\t\t\tonError(nextError);\n\t\t}, [currentText, error, limit, onError]);\n\n\t\treturn (\n\t\t\t<OuterContainer>\n\t\t\t\t<EditorFooterRow>\n\t\t\t\t\t<EditorFooterTitle>\n\t\t\t\t\t\t{editorHeader ? (\n\t\t\t\t\t\t\t<TitleSmall data-test=\"body-text-for-edit-template\">\n\t\t\t\t\t\t\t\t{editorHeader}\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</EditorFooterTitle>\n\t\t\t\t\t<EditorFooterRight>\n\t\t\t\t\t\t{error && error !== LIMIT_REACHED ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<InfoIcon\n\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.content.negative}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.negative}>\n\t\t\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{limit ? (\n\t\t\t\t\t\t\t<BodyCaption\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tcolor:\n\t\t\t\t\t\t\t\t\t\terror === LIMIT_REACHED || currentText.length > limit\n\t\t\t\t\t\t\t\t\t\t\t? COLORS.content.negative\n\t\t\t\t\t\t\t\t\t\t\t: COLORS.content.secondary,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{currentText.length}/{limit}\n\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</EditorFooterRight>\n\t\t\t\t</EditorFooterRow>\n\t\t\t\t<Container isError={!!error}>\n\t\t\t\t\t{shouldShowSuggestionSession ? (\n\t\t\t\t\t\t<SuggestionSessionContainer ref={suggestionScrollRef}>\n\t\t\t\t\t\t\t<SuggestionBaselineText\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: suggestionBaseHtml }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{isGenerating ? (\n\t\t\t\t\t\t\t\t<SuggestionCandidateText aria-busy=\"true\">\n\t\t\t\t\t\t\t\t\t<SuggestionCandidateSkeleton>\n\t\t\t\t\t\t\t\t\t\t<EditorSkeletonLine width=\"96%\" />\n\t\t\t\t\t\t\t\t\t\t<EditorSkeletonLine width=\"84%\" />\n\t\t\t\t\t\t\t\t\t\t<EditorSkeletonLine width=\"68%\" />\n\t\t\t\t\t\t\t\t\t</SuggestionCandidateSkeleton>\n\t\t\t\t\t\t\t\t</SuggestionCandidateText>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<SuggestionCandidateText\n\t\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t\t__html: activeCandidateHtml,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<SuggestionControlsRow>\n\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\taria-label=\"Previous suggestion\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={isPrevSuggestionDisabled}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tsetSuggestionIndex((idx) => Math.max(0, idx - 1))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ChevronLeftIcon\n\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t<SuggestionCounter>\n\t\t\t\t\t\t\t\t\t{suggestionIndex + 1}/{suggestionCandidates.length}\n\t\t\t\t\t\t\t\t</SuggestionCounter>\n\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\taria-label=\"Next suggestion\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={isNextSuggestionDisabled}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tsetSuggestionIndex((idx) =>\n\t\t\t\t\t\t\t\t\t\t\tMath.min(suggestionCandidates.length - 1, idx + 1),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ChevronRightIcon\n\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t<Tooltip body=\"Like\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Like suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdisabled={hasFeedbackForActiveCandidate}\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleFeedback(AIFeedbackRating.LIKE)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<ThumbsUpIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t<Tooltip body=\"Dislike\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Dislike suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdisabled={hasFeedbackForActiveCandidate}\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleFeedback(AIFeedbackRating.DISLIKE)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<ThumbsDownIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t{canRegenerate ? (\n\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\tbody={isGenerating ? 'Regenerating…' : 'Regenerate'}\n\t\t\t\t\t\t\t\t\t\tplacement=\"top\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<SuggestionRegenerateButton\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Regenerate suggestion\"\n\t\t\t\t\t\t\t\t\t\t\taria-busy={isGenerating}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tdisabled={isGenerating}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tif (suggestionActionType) {\n\t\t\t\t\t\t\t\t\t\t\t\t\texecuteAIAction(suggestionActionType, true);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{isGenerating ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<RegenerateIconShimmer aria-hidden />\n\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<RewindIcon width={14} height={14} />\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</SuggestionRegenerateButton>\n\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t<Tooltip body=\"Discard\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Discard suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleRejectSuggestion}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<CrossIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t<Tooltip body=\"Accept\" placement=\"top\">\n\t\t\t\t\t\t\t\t\t<SuggestionIconButton\n\t\t\t\t\t\t\t\t\t\taria-label=\"Accept suggestion\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleAcceptSuggestion}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<CheckIcon\n\t\t\t\t\t\t\t\t\t\t\twidth={14}\n\t\t\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</SuggestionIconButton>\n\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t</SuggestionControlsRow>\n\t\t\t\t\t\t</SuggestionSessionContainer>\n\t\t\t\t\t) : isGenerating ? (\n\t\t\t\t\t\t<EditorSkeletonContainer>\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"96%\" />\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"92%\" />\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"88%\" />\n\t\t\t\t\t\t\t<EditorSkeletonLine width=\"54%\" />\n\t\t\t\t\t\t</EditorSkeletonContainer>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<TextSpace\n\t\t\t\t\t\t\tref={textSpaceRef}\n\t\t\t\t\t\t\t{...textAreaProps}\n\t\t\t\t\t\t\tvalue={currentText}\n\t\t\t\t\t\t\tonChange={handleOnChange}\n\t\t\t\t\t\t\tonBlur={(e) => {\n\t\t\t\t\t\t\t\tif (aiTagRecomputeRef.current) {\n\t\t\t\t\t\t\t\t\tclearTimeout(aiTagRecomputeRef.current);\n\t\t\t\t\t\t\t\t\taiTagRecomputeRef.current = null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\temitPostEditAiTagRecompute(e.target.value);\n\t\t\t\t\t\t\t\ttextAreaOnBlur?.(e);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonPaste={(e) => {\n\t\t\t\t\t\t\t\tconst pastedText = e.clipboardData.getData('text');\n\t\t\t\t\t\t\t\tif (pastedText.length > LARGE_INPUT_THRESHOLD) {\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\tconst el = textSpaceRef.current;\n\t\t\t\t\t\t\t\t\tconst start = el?.selectionStart ?? 0;\n\t\t\t\t\t\t\t\t\tconst end = el?.selectionEnd ?? start;\n\t\t\t\t\t\t\t\t\t// Prefer live DOM value — `currentText` can lag the textarea for big pastes.\n\t\t\t\t\t\t\t\t\tconst base = el?.value ?? currentText;\n\t\t\t\t\t\t\t\t\tconst nextText =\n\t\t\t\t\t\t\t\t\t\tbase.slice(0, start) + pastedText + base.slice(end);\n\t\t\t\t\t\t\t\t\tsetEditorText(nextText);\n\t\t\t\t\t\t\t\t\temitChangeWithGuard(nextText);\n\t\t\t\t\t\t\t\t\tconst caret = start + pastedText.length;\n\t\t\t\t\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\t\t\t\t\tconst ta = textSpaceRef.current;\n\t\t\t\t\t\t\t\t\t\tif (!ta) return;\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tta.setSelectionRange(caret, caret);\n\t\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t\t// ignore invalid range in edge browsers\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\trows={rows}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{isInstructionInputVisible ? (\n\t\t\t\t\t\t<InstructionContainer>\n\t\t\t\t\t\t\t<InstructionInputRow>\n\t\t\t\t\t\t\t\t<EditIcon\n\t\t\t\t\t\t\t\t\twidth={18}\n\t\t\t\t\t\t\t\t\theight={18}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<InstructionInput\n\t\t\t\t\t\t\t\t\tvalue={instructionText}\n\t\t\t\t\t\t\t\t\tplaceholder=\"Add specific instructions to refine your message\"\n\t\t\t\t\t\t\t\t\tonChange={(e) => setInstructionText(e.target.value)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<InstructionActions>\n\t\t\t\t\t\t\t\t\t<InstructionCancel\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\tsetInstructionText('');\n\t\t\t\t\t\t\t\t\t\t\tsetIsInstructionInputVisible(false);\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t\t</InstructionCancel>\n\t\t\t\t\t\t\t\t\t<InstructionImprove\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\tconst instructionToApply = instructionText.trim();\n\t\t\t\t\t\t\t\t\t\t\tif (instructionToApply) {\n\t\t\t\t\t\t\t\t\t\t\t\temitAIEvent('ai_instruction_used', {\n\t\t\t\t\t\t\t\t\t\t\t\t\taction_type: AIEditorActionTypes.REPHRASE,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttemplate_id: templateId,\n\t\t\t\t\t\t\t\t\t\t\t\t\tinstruction_text:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tanonymizeInstructionText(instructionToApply),\n\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tsetIsInstructionInputVisible(false);\n\t\t\t\t\t\t\t\t\t\t\tsetInstructionText('');\n\t\t\t\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\t\t\t\tAIEditorActionTypes.REPHRASE,\n\t\t\t\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\t\t\tinstructionToApply,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tImprove\n\t\t\t\t\t\t\t\t\t</InstructionImprove>\n\t\t\t\t\t\t\t\t</InstructionActions>\n\t\t\t\t\t\t\t</InstructionInputRow>\n\t\t\t\t\t\t\t{instructionText.trim().length > 0 &&\n\t\t\t\t\t\t\tfilteredInstructionSuggestions.length > 0 ? (\n\t\t\t\t\t\t\t\t<InstructionSuggestionList>\n\t\t\t\t\t\t\t\t\t{filteredInstructionSuggestions.map((suggestion) => (\n\t\t\t\t\t\t\t\t\t\t<InstructionSuggestionButton\n\t\t\t\t\t\t\t\t\t\t\tkey={suggestion}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tselected={instructionText === suggestion}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => setInstructionText(suggestion)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{suggestion}\n\t\t\t\t\t\t\t\t\t\t</InstructionSuggestionButton>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</InstructionSuggestionList>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</InstructionContainer>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<WhatsAppTextEditorHeader\n\t\t\t\t\t\t\tactions={actions}\n\t\t\t\t\t\t\tref={textSpaceRef}\n\t\t\t\t\t\t\tonActionSelect={onActionSelect}\n\t\t\t\t\t\t\tRightComponent={RightComponent}\n\t\t\t\t\t\t\trightActionsDisabled={shouldShowSuggestionSession || isGenerating}\n\t\t\t\t\t\t\tonEmojiClick={onEmojiAddition}\n\t\t\t\t\t\t\taiActions={aiHeaderActions}\n\t\t\t\t\t\t\tdisableAllActions={shouldShowSuggestionSession || isGenerating}\n\t\t\t\t\t\t\tinstructionActive={isInstructionInputVisible}\n\t\t\t\t\t\t\tonAIInstructionsClick={() => setIsInstructionInputVisible(true)}\n\t\t\t\t\t\t\tonAIToneChange={(actionType, toneId) => {\n\t\t\t\t\t\t\t\tsetToneByAction((prev) => ({ ...prev, [actionType]: toneId }));\n\t\t\t\t\t\t\t\tonAIToneSelect?.(actionType, toneId);\n\t\t\t\t\t\t\t\tif (actionType === AIEditorActionTypes.REPHRASE) {\n\t\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\ttoneId,\n\t\t\t\t\t\t\t\t\t\tAIActionVariant.DEFAULT,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonAIActionClick={(\n\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\tactionVariant = AIActionVariant.DEFAULT,\n\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\tif (isGenerating) return;\n\n\t\t\t\t\t\t\t\tif (shouldShowSuggestionSession) {\n\t\t\t\t\t\t\t\t\tif (suggestionActionType === actionType) {\n\t\t\t\t\t\t\t\t\t\t// Same action should not retrigger from chip;\n\t\t\t\t\t\t\t\t\t\t// regenerate is only via explicit regenerate control.\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// New action starts a fresh suggestion session.\n\t\t\t\t\t\t\t\t\tclearSuggestionSession();\n\t\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\texecuteAIAction(\n\t\t\t\t\t\t\t\t\tactionType,\n\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\tactionVariant,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</Container>\n\t\t\t</OuterContainer>\n\t\t);\n\t},\n);\n\nWhatsAppTextEditor.displayName = 'WhatsAppTextEditor';\n\nexport type { AITagPayload } from './ai/aiTag';\nexport {\n\tAI_TAG_CHANGE_RATIO_THRESHOLD,\n\tcomputeAiTagOnAccept,\n\tlevenshteinDistance,\n} from './ai/aiTag';\n"],"names":["LIMIT_REACHED","REPHRASE_IDLE_MS","MAX_REPHRASE_HIGHLIGHTS","MAX_SUGGESTIONS","LARGE_INPUT_THRESHOLD","AI_TAG_RECOMPUTE_IDLE_MS","UTILITY_REPHRASE_PROMPT","skeletonPulse","keyframes","EditorSkeletonContainer","styled","EditorSkeletonLine","props","SuggestionSessionContainer","SuggestionBaselineText","COLORS","SuggestionCandidateText","SuggestionCandidateSkeleton","SuggestionControlsRow","SuggestionCounter","SuggestionIconButton","SuggestionRegenerateButton","RegenerateIconShimmer","InstructionContainer","InstructionInputRow","InstructionInput","InstructionActions","InstructionCancel","InstructionImprove","InstructionSuggestionList","InstructionSuggestionButton","baseWhatsappContentLang","BaseWhatsappContentLangHelper","WildCardMap","EditorActionTypes","getHighlightStorageKey","editorInstanceKey","WhatsAppTextEditor","React","onChange","onClickVariable","inputValue","RightComponent","error","limit","onError","rows","actions","editorSessionId","templateType","templateId","requestExecutor","baseUrl","endpointPath","useCase","storeId","apiAdapter","conversationId","systemId","intent","enabledAIActions","AIEditorActionTypes","disableBuiltInAIActions","promptOverrides","rephraseTones","aiActionMinChars","instructionSuggestions","DEFAULT_INSTRUCTION_SUGGESTIONS","onAnalyticsEvent","onAITagComputed","prefillWasAiGenerated","editorHeader","onAIToneSelect","onAIActionRequest","onBuildAIPrompt","textAreaOnBlur","textAreaProps","ref","textSpaceRef","useRef","currentText","setCurrentText","useState","isRephraseHighlighted","setIsRephraseHighlighted","rephraseHighlightCount","setRephraseHighlightCount","isGenerating","setIsGenerating","isInstructionInputVisible","setIsInstructionInputVisible","instructionText","setInstructionText","toneByAction","setToneByAction","suggestionBaseText","setSuggestionBaseText","suggestionCandidates","setSuggestionCandidates","suggestionIndex","setSuggestionIndex","suggestionActionType","setSuggestionActionType","suggestionScrollRef","rephraseIdleRef","highlightResetRef","aiTagRecomputeRef","prevRephraseEligibleRef","deferredHtmlRef","lastEmittedEditorErrorRef","initialAiPrefillPhaseRef","acceptedSuggestionStateRef","prefillBaselineTextRef","prefillBaselineCapturedRef","feedbackVotesByCandidate","setFeedbackVotesByCandidate","mountSessionIdRef","highlightStorageKey","useMemo","useEffect","seed","activeActionPrompts","resolveActionPrompts","filteredInstructionSuggestions","query","suggestion","minCharsByAction","DEFAULT_AI_ACTION_MIN_CHARS","rephraseMinChars","anonymizeInstructionText","useCallback","value","normalized","words","emitAIEvent","name","payload","setEditorText","nextText","prev","emitChangeWithGuard","emitPostEditAiTagRecompute","latestBaseline","recomputePayload","computeAiTagOnPostEdit","clearSuggestionSession","triggerRephraseHighlight","nextCount","triggerRephraseHighlightRef","handleOnChange","text","acceptedSuggestion","baselineAiTextForRecompute","setCaretPosition","caretPos","elem","onActionSelect","actionType","wildCard","start","end","insertTextAtIndex","addTextOrWrap","onEmojiAddition","emoji","addText","textToAdd","html","index","cached","eligible","crossedThreshold","activeCandidate","activeFeedbackCandidateKey","hasFeedbackForActiveCandidate","suggestionBaseHtml","activeCandidateHtml","canRegenerate","shouldShowSuggestionSession","isPrevSuggestionDisabled","isNextSuggestionDisabled","node","executeAIAction","regenerateExisting","instructionOverride","toneOverrideId","actionVariant","AIActionVariant","minCharsForAction","baseConfig","config","selectedToneId","selectedTone","tone","instructionForPrompt","prompt","buildActionPrompt","result","requestAISuggestion","candidate","next","handleAcceptSuggestion","inInitialAiPhase","tagPayload","computeAiTagOnAccept","handleRejectSuggestion","handleFeedback","rating","aiHeaderActions","actionConfig","toneId","useImperativeHandle","nextError","OuterContainer","jsxs","EditorFooterRow","jsx","EditorFooterTitle","TitleSmall","EditorFooterRight","Fragment","InfoIcon","BodyCaption","Container","idx","ChevronLeftIcon","ChevronRightIcon","Tooltip","ThumbsUpIcon","ThumbsDownIcon","RewindIcon","CrossIcon","CheckIcon","TextSpace","pastedText","el","base","caret","ta","EditIcon","instructionToApply","WhatsAppTextEditorHeader"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),A=require("
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),A=require("react"),n=require("../../TypographyStyle.js"),l=require("../../../constants/Theme.js"),t=require("../AgentBuilder.styled.js"),j=({label:c,value:r,onChange:i,maxLength:s,placeholder:a,minHeight:u,disabled:d,...x})=>{const[h,o]=A.useState(!1);return e.jsxs(t.FieldBlock,{children:[e.jsxs(t.FieldLabelRow,{children:[e.jsx(n.TitleSmall,{color:l.COLORS.content.primary,children:c}),e.jsxs(n.BodyCaption,{color:l.COLORS.content.secondary,children:[r.length,"/",s]})]}),e.jsx(t.AiTextAreaShell,{focused:h,minHeight:u,children:e.jsx(t.AiTextAreaInput,{"data-test":x["data-test"],value:r,placeholder:a,maxLength:s,disabled:d,onFocus:()=>o(!0),onBlur:()=>o(!1),onChange:y=>i(y.target.value)})})]})};exports.AiTextArea=j;
|
|
2
2
|
//# sourceMappingURL=AiTextArea.js.map
|