Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion samples/BlazorServer/Pages/EditorView.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@
<MudButton OnClick="AddParagraph" Size="Size.Small">Add Paragraph</MudButton>
<MudButton OnClick="OnCancel" Size="Size.Small">Cancel</MudButton>
<MudButton OnClick="Reset" Size="Size.Small">Reset</MudButton>
<MudButton OnClick="Focus" Size="Size.Small">Focus</MudButton>
<MudButton OnClick="Blur" Size="Size.Small">Blur</MudButton>
<MudSwitch T="bool" @bind-Value="disabled" Label="Disabled"></MudSwitch>
<MudSwitch T="bool" @bind-Value="isReadOnly" Label="ReadOnly"></MudSwitch>
<MudButton Color="Color.Primary" OnClick="SaveChanges" Size="Size.Small" StartIcon="@Icons.Material.Filled.Save" Variant="Variant.Filled">Save Changes</MudButton>
</MudStack>

<MudHtmlEditor @ref="_editor" @bind-Html="@_html" />
<MudHtmlEditor @ref="_editor" @bind-Html="@_html" ReadOnly="isReadOnly" Disabled="disabled" />

@code {
private MudHtmlEditor _editor = default!;
private string _html = "";

bool isReadOnly = false;
bool disabled = false;

[Parameter]
public string InitialHtml { get; set; } = "";

Expand All @@ -29,6 +36,14 @@
{
await _editor.Reset();
}
private async Task Blur()
{
await _editor.Blur();
}
private async Task Focus()
{
await _editor.Focus();
}

private async Task SaveChanges()
{
Expand Down
4 changes: 2 additions & 2 deletions src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="html-editor html-content-wrapper @(Outlined ? "is-outlined" : "")" @attributes="UserAttributes">
<div class="html-editor html-content-wrapper @(Outlined ? "is-outlined" : "") @(Disabled ? "mudhtmleditor-disabled" : "") @(Class)" @attributes="UserAttributes">
<div @ref="_toolbar">
@if (ChildContent is null)
{
Expand All @@ -10,4 +10,4 @@
}
</div>
<div class="@(Resizable ? "is-resizable" : "")" @ref="_editor"></div>
</div>
</div>
71 changes: 69 additions & 2 deletions src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Runtime.InteropServices;

namespace Tizzani.MudBlazor.HtmlEditor;

Expand All @@ -9,13 +10,18 @@ public sealed partial class MudHtmlEditor : IAsyncDisposable
private IJSObjectReference? _quill;
private ElementReference _toolbar;
private ElementReference _editor;
private bool isReadOnly;
private bool disabled;

[Inject]
private IJSRuntime JS { get; set; } = default!;

[Parameter]
public RenderFragment? ChildContent { get; set; }

[Parameter]
public string Class { get; set; }

/// <summary>
/// Whether or not to ourline the editor. Default value is <see langword="true" />.
/// </summary>
Expand All @@ -34,6 +40,36 @@ public sealed partial class MudHtmlEditor : IAsyncDisposable
[Parameter]
public string Html { get; set; } = "";

[Parameter]
public bool ReadOnly
{
get => isReadOnly;
set
{
if (isReadOnly != value)
{
isReadOnly = value;
if (_quill is not null)
{
_ = InvokeAsync(async () => await SetReadOnly(value));
}
}
}
}

[Parameter]
public bool Disabled
{
get => this.disabled;
set
{
if (value != disabled)
{
this.disabled = value;
}
}
}

/// <summary>
/// Raised when the <see cref="Html"/> property changes.
/// </summary>
Expand Down Expand Up @@ -64,7 +100,6 @@ public sealed partial class MudHtmlEditor : IAsyncDisposable
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object?>? UserAttributes { get; set; }


/// <summary>
/// Clears the content of the editor.
/// </summary>
Expand Down Expand Up @@ -107,6 +142,38 @@ public async Task<string> GetText()
return "";
}

private async Task SetReadOnly(bool isReadOnly)
{
if (_quill is not null)
{
await _quill.InvokeVoidAsync("enable", !isReadOnly);
}
this.isReadOnly = isReadOnly;
}

public async Task Focus()
{
if (_quill is not null)
await _quill.InvokeVoidAsync("focus");
}

public async Task<bool> GetHasFocus()
{
if (_quill is not null)
return await _quill.InvokeAsync<bool>("hasFocus");
throw new Exception("Quill instance is not initialized.");
}

/// <summary>
/// Removes focus from the editor.
/// </summary>
/// <returns></returns>
public async Task Blur()
{
if (_quill is not null)
await _quill.InvokeVoidAsync("blur");
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
Expand All @@ -117,12 +184,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
_quill = await module.InvokeAsync<IJSObjectReference>("createQuillInterop", _dotNetRef, _editor, _toolbar, Placeholder);

await SetHtml(Html);
await SetReadOnly(ReadOnly);

StateHasChanged();
}
}


[JSInvokable]
public async void HandleHtmlContentChanged(string html)
{
Expand Down
23 changes: 21 additions & 2 deletions src/Tizzani.MudBlazor.HtmlEditor/MudHtmlEditor.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Quill.register(Divider, true);

try {
Quill.register('modules/blotFormatter', QuillBlotFormatter.default);
} catch { }
} catch { }

export function createQuillInterop(dotNetRef, editorRef, toolbarRef, placeholder) {
var quill = new Quill(editorRef, {
Expand Down Expand Up @@ -65,8 +65,27 @@ export class MudQuillInterop {
}
};

focus = () => {
this.quill.focus();
}

hasFocus = () => {
return this.quill.hasFocus();
}

enable = (isEnabled) => {
this.quill.enable(isEnabled);
}

/**
* Removes focus from the editor.
*/
blur = () => {
this.quill.blur();
}

/**
*
*
* @param {Delta} delta
* @param {Delta} oldDelta
* @param {any} source
Expand Down
10 changes: 10 additions & 0 deletions src/Tizzani.MudBlazor.HtmlEditor/wwwroot/MudHtmlEditor.css
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
@import url('quill.snow.min.css');
@import url('MudHtmlEditor.Core.css');


.mudhtmleditor-disabled {
pointer-events: none;
cursor: not-allowed;
}

.mudhtmleditor-disabled .ql-toolbar.ql-snow * {
opacity: 0.85;
}