@props([
'name' => 'message',
'value' => '',
'placeholder' => 'Type a message…',
'rows' => 5,
'maxlength' => 1024,
'id' => null,
'showCounter' => true,
'showFormatBar' => true,
'showVariableInsert' => true,
'showEmoji' => true,
'showAi' => true,
'hint' => null,
'required' => false,
])
@php
$composeId = $id ?? 'compose-textarea-' . \Illuminate\Support\Str::random(8);
// Read once so every compose-textarea on the page picks up the
// user's "Auto AI summarize" toggle without each caller having to
// pass it. The wa-editor JS decides whether to debounce-trigger
// the review automatically based on this flag.
$autoAiOn = (bool) (auth()->user()?->auto_ai_summarize_enabled ?? false);
@endphp
{{--
Reusable compose-style textarea — visually mirrors the canonical
"INITIAL MESSAGE / Reply text" pattern used inline in:
- resources/views/user/auto-reply/create.blade.php (#reply-text)
- resources/views/user/scheduled/create.blade.php (#msg-content)
- resources/views/user/templates/create.blade.php (#tpl-body)
- resources/views/user/templates/edit.blade.php (#tpl-body)
Toolbar is on TOP (B / I / S / { } / emoji + format-syntax hint right-aligned).
Character counter sits at the bottom-right (font-mono, 10.5px, ink-500).
Drop into any form:
--}}
{{-- Hooks `wa-editor.js`: [data-wa-editor] is the root, .wa-editor-textarea
is the input, .wa-editor-emoji is the emoji-panel mount, and each
toolbar button carries data-wa-cmd="bold|italic|strike|code|emoji"
so the editor JS finds them and wires them up. --}}
@if ($showFormatBar)
@if ($showVariableInsert)
@endif
@if ($showEmoji)
{{-- The relative wrapper anchors the popup to the emoji
button specifically — not the whole compose box —
so the picker appears right above the icon instead
of floating in the middle of the screen. --}}
@endif
@if ($showAi)
{{-- AI review trigger — manual fire. When the user has
"Auto AI summarize" on, wa-editor.js also fires this
automatically on debounce. The button stays clickable
either way so the user can force a refresh. --}}
@endif
*bold*_italic_~strike~`code`
@endif
{{-- Positional-placeholder map. The attribute-picker JS records
{ "1": "order_id", "2": "promo_key" } here whenever the operator
inserts an attribute via `/`. The reply / template-store handlers
read this to resolve {{1}} → actual attribute value before
dispatching the message. --}}
{{-- The wrapper carries data-attr-form so attribute-picker.js'
recordMapping() can find the hidden field above. --}}
@if ($showCounter)
{{ strlen($value) }}/{{ $maxlength }}
@endif
@if ($showAi)
{{-- AI review panel — wa-editor.js paints into [data-ai-panel]
whenever a review returns. Hidden by default; shown after the
first fire. Score chip + good/bad bullets + best-version
preview with "Append now" button that replaces the textarea
contents. --}}