fixed regression issue

This commit is contained in:
Mark Gregory
2026-06-24 17:51:50 +01:00
parent 5b4b81eb4d
commit 0701713823
5 changed files with 142 additions and 23 deletions
@@ -3,34 +3,122 @@
'label' => 'Details',
'placeholder' => 'Describe the ticket, include steps to reproduce, expected result, actual result and any useful technical details.',
'rows' => 10,
'editorDusk' => null,
])
<div class="space-y-2">
<div
class="space-y-2"
x-data="{
model: @js($model),
value: @entangle($model).defer,
init() {
this.$nextTick(() => {
this.writeEditorValue(this.value || '');
});
},
writeEditorValue(value) {
if (!this.$refs.editor) {
return;
}
this.$refs.editor.textContent = value || '';
},
syncToLivewire(live = false) {
const value = this.$refs.editor?.innerText || '';
this.value = value;
this.$refs.input.value = value;
this.$refs.input.dispatchEvent(new Event('input', { bubbles: true }));
this.$wire.set(this.model, this.value, live);
},
resetEditor() {
this.value = '';
this.writeEditorValue('');
this.syncToLivewire(false);
},
runCommand(command) {
this.$refs.editor?.focus();
document.execCommand(command, false, null);
this.syncToLivewire(false);
},
wrapBlock(tagName) {
this.$refs.editor?.focus();
document.execCommand('formatBlock', false, tagName);
this.syncToLivewire(false);
},
}"
x-on:helpdesk-editor-sync.window="if (($event.detail?.model || model) === model) syncToLivewire(false)"
x-on:helpdesk-editor-reset.window="if (($event.detail?.model || model) === model) resetEditor()"
>
<label for="{{ $model }}-editor" class="block text-sm font-semibold text-zinc-200">
{{ $label }}
</label>
<div class="overflow-hidden rounded-2xl border border-zinc-700 bg-zinc-950 shadow-sm">
<div class="flex flex-wrap items-center gap-2 border-b border-zinc-700 bg-zinc-900/80 px-4 py-2 text-sm text-zinc-300">
<span class="rounded-lg bg-zinc-800 px-2 py-1 font-semibold text-zinc-100">Spellcheck enabled</span>
<span class="text-zinc-500">Use Markdown for formatting, lists, quotes, code and links.</span>
<div class="flex flex-wrap items-center gap-1.5 border-b border-zinc-700 bg-zinc-900/80 px-4 py-2 text-sm text-zinc-300">
<span class="mr-2 rounded-lg bg-zinc-800 px-2 py-1 text-xs font-black uppercase tracking-wide text-zinc-100">Spellcheck enabled</span>
<button type="button" x-on:click="runCommand('bold')"
class="inline-flex min-h-8 items-center justify-center rounded-lg border border-zinc-700 bg-zinc-950 px-3 py-1.5 text-xs font-black text-zinc-100 shadow-sm transition hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-blue-400/70"
aria-label="Bold selected text">
B
</button>
<button type="button" x-on:click="runCommand('italic')"
class="inline-flex min-h-8 items-center justify-center rounded-lg border border-zinc-700 bg-zinc-950 px-3 py-1.5 text-xs font-black italic text-zinc-100 shadow-sm transition hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-blue-400/70"
aria-label="Italic selected text">
I
</button>
<button type="button" x-on:click="runCommand('underline')"
class="inline-flex min-h-8 items-center justify-center rounded-lg border border-zinc-700 bg-zinc-950 px-3 py-1.5 text-xs font-black underline text-zinc-100 shadow-sm transition hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-blue-400/70"
aria-label="Underline selected text">
U
</button>
<button type="button" x-on:click="runCommand('insertUnorderedList')"
class="inline-flex min-h-8 items-center justify-center rounded-lg border border-zinc-700 bg-zinc-950 px-3 py-1.5 text-xs font-black text-zinc-100 shadow-sm transition hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-blue-400/70">
• List
</button>
<button type="button" x-on:click="runCommand('insertOrderedList')"
class="inline-flex min-h-8 items-center justify-center rounded-lg border border-zinc-700 bg-zinc-950 px-3 py-1.5 text-xs font-black text-zinc-100 shadow-sm transition hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-blue-400/70">
1. List
</button>
<button type="button" x-on:click="wrapBlock('blockquote')"
class="inline-flex min-h-8 items-center justify-center rounded-lg border border-zinc-700 bg-zinc-950 px-3 py-1.5 text-xs font-black text-zinc-100 shadow-sm transition hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-blue-400/70">
Quote
</button>
<button type="button" x-on:click="wrapBlock('pre')"
class="inline-flex min-h-8 items-center justify-center rounded-lg border border-zinc-700 bg-zinc-950 px-3 py-1.5 text-xs font-black text-zinc-100 shadow-sm transition hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-blue-400/70">
Code
</button>
</div>
<textarea
<div
id="{{ $model }}-editor"
wire:model.defer="{{ $model }}"
rows="{{ $rows }}"
placeholder="{{ $placeholder }}"
x-ref="editor"
contenteditable="true"
spellcheck="true"
lang="en-GB"
autocorrect="on"
autocomplete="off"
autocomplete="on"
autocapitalize="sentences"
inputmode="text"
class="block min-h-[14rem] w-full resize-y border-0 bg-zinc-950 px-5 py-4 text-base leading-7 text-zinc-100 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-blue-500"
role="textbox"
aria-multiline="true"
data-placeholder="{{ $placeholder }}"
@if ($editorDusk) data-dusk="{{ $editorDusk }}" dusk="{{ $editorDusk }}" @endif
x-on:blur="syncToLivewire(false)"
class="helpdesk-rich-editor block min-h-[14rem] w-full overflow-y-auto whitespace-pre-wrap break-words border-0 bg-zinc-950 px-5 py-4 text-base leading-7 text-zinc-100 outline-none transition placeholder:text-zinc-500 empty:before:pointer-events-none empty:before:text-zinc-500 empty:before:content-[attr(data-placeholder)] focus:ring-2 focus:ring-blue-500"
></div>
<textarea
x-ref="input"
wire:model.defer="{{ $model }}"
class="sr-only"
tabindex="-1"
aria-hidden="true"
></textarea>
</div>
<p class="text-xs font-semibold text-zinc-400">
Browser spellcheck is handled by the native editor and remains active after punctuation such as commas.
Browser spellcheck stays active in the native editable area. Formatting is synchronised only on blur and submit to avoid Livewire keypress regressions.
</p>
</div>
@@ -245,10 +245,10 @@
<div class="lg:col-span-3 xl:col-span-6">
<x-helpdesk::html-editor
model="body"
label="Details"
rows="12"
placeholder="Describe the issue, expected outcome, steps to reproduce and any useful context..."
wire:model="body"
editor-dusk="ticket-body-editor"
/>
@@ -330,25 +330,28 @@
@enderror
</div>
</div>
<div class="flex items-center justify-end gap-3 border-t border-zinc-700 bg-zinc-900 px-6 py-4">
</div>
<div class="flex flex-col-reverse gap-2 border-t border-zinc-700 bg-zinc-900 px-6 py-4 sm:flex-row sm:items-center sm:justify-end">
<button type="button" wire:click="clearForm" wire:loading.attr="disabled" wire:target="clearForm"
class="inline-flex items-center gap-2 rounded-xl bg-red-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-700 disabled:cursor-not-allowed disabled:opacity-50"
class="inline-flex min-h-10 items-center justify-center rounded-lg bg-red-600 px-4 py-2 text-xs font-black text-white shadow-sm transition hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-400/70 disabled:cursor-not-allowed disabled:opacity-50"
data-dusk="ticket-create-clear" dusk="ticket-create-clear">
<i class="fa-solid fa-eraser" aria-hidden="true"></i>
<i class="fa-solid fa-eraser mr-2" aria-hidden="true"></i>
<span wire:loading.remove wire:target="clearForm">Clear</span>
<span wire:loading wire:target="clearForm">Clearing...</span>
</button>
<a href="{{ route('helpdesk.tickets.index') }}" wire:navigate
class="rounded-xl bg-blue-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-blue-700">
class="inline-flex min-h-10 items-center justify-center rounded-lg bg-blue-600 px-4 py-2 text-xs font-black text-white shadow-sm transition hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400/70">
<i class="fa-solid fa-arrow-left mr-2" aria-hidden="true"></i>
Cancel
</a>
<button type="submit"
class="inline-flex items-center gap-2 rounded-xl bg-green-600 px-5 py-2 text-sm font-semibold text-white shadow-sm hover:bg-green-700 disabled:cursor-not-allowed disabled:opacity-50"
class="inline-flex min-h-10 items-center justify-center rounded-lg bg-emerald-600 px-4 py-2 text-xs font-black text-white shadow-sm transition hover:bg-emerald-700 focus:outline-none focus:ring-2 focus:ring-emerald-400/70 disabled:cursor-not-allowed disabled:opacity-50"
data-dusk="ticket-create-submit" dusk="ticket-create-submit" wire:loading.attr="disabled" wire:target="save,attachments" x-bind:disabled="helpdeskAttachmentsUploading" wire:dirty.class="ring-2 ring-amber-400/40">
<i class="fa-regular fa-floppy-disk" aria-hidden="true"></i>
<span wire:loading.remove wire:target="save,attachments">Create Ticket</span>
<i class="fa-regular fa-floppy-disk mr-2" aria-hidden="true"></i>
<span wire:loading.remove wire:target="save,attachments">Create ticket</span>
<span wire:loading wire:target="attachments">Uploading...</span>
<span wire:loading wire:target="save">Creating...</span>
</button>