Files
sufi-blazor/docs/components/forms/SbRichTextEditor.md
T
2026-05-18 15:53:59 +03:30

8.3 KiB

SbRichTextEditor

A rich text editor component for creating and editing formatted content.

Parameters

Parameter Type Default Description
Value string? null The HTML content (two-way bindable)
ValueChanged EventCallback<string?> - Callback when content changes
Mode SbEditorMode SbEditorMode.Html Editor mode (e.g. Html)
ToolbarItems IReadOnlyList<SbEditorToolbarItem>? null Custom toolbar items (when null, default toolbar is used)
Placeholder string? null Placeholder text when empty
ReadOnly bool false Whether the editor is read-only
Disabled bool false Whether the editor is disabled
RightToLeft bool false Whether the editor is RTL
Height string? "300px" Editor content area height
HideToolbar bool false When true, hides the toolbar
ShowCharacterCount bool false Whether to show character count in footer
ShowWordCount bool false Whether to show word count in footer
UseToolbarContributors bool false Enable toolbar items from registered contributor services
IncludeDefaultToolbarItems bool true Whether to include default toolbar items
Class string? null Additional CSS classes

Additional parameters for dialogs and accessibility (e.g. ToolbarAriaLabel, EditorAriaLabel, LinkDialogTitle, ImageDialogTitle, WordCountFormat, CharacterCountFormat, and various link/image dialog labels) are available; when null or not set, defaults are used.

Events

Event Type Description
ValueChanged EventCallback<string?> Fired when the content changes
OnChange EventCallback<string?> Fired when content changes (receives current HTML)
OnFocus EventCallback Fired when editor gains focus
OnBlur EventCallback Fired when editor loses focus

CSS Classes

  • sb-editor - Base class
  • sb-editor__toolbar - Toolbar container
  • sb-editor__toolbar-separator - Toolbar separator
  • sb-editor__toolbar-select - Toolbar dropdown (e.g. headings)
  • sb-editor__toolbar-btn - Toolbar button
  • sb-editor__toolbar-btn--active - Active format button
  • sb-editor__toolbar-icon - Toolbar icon
  • sb-editor__content - Editable content area
  • sb-editor__footer - Footer (word/character count)
  • sb-editor__count - Count display
  • sb-editor__link-dialog - Link/Image dialog container
  • sb-editor__link-dialog-field - Dialog field
  • sb-editor__link-input - Dialog input
  • sb-editor--disabled - Disabled state
  • sb-editor--readonly - Read-only state
  • sb-editor--rtl - Right-to-left state

Examples

Basic Usage

<SbRichTextEditor @bind-Value="content" />

With Placeholder

<SbRichTextEditor @bind-Value="description" 
                  Placeholder="Enter description..." />

Custom Height

<SbRichTextEditor @bind-Value="articleContent" 
                  Height="400px" />

Without Toolbar

<SbRichTextEditor @bind-Value="note" 
                  HideToolbar="true"
                  Height="200px" />

Read-Only Display

<SbRichTextEditor Value="@displayContent" ReadOnly="true" />

With Form Field

<SbFormField Label="Description" Required="true">
    <SbRichTextEditor @bind-Value="model.Description" 
                      Placeholder="Enter a detailed description..." />
    <SbFieldError For="() => model.Description" />
</SbFormField>

Toolbar Extensibility

The SbRichTextEditor supports extending the toolbar with custom buttons from external modules using the contributor pattern.

Enabling Toolbar Contributors

To use toolbar contributors, set UseToolbarContributors="true" on the component:

<SbRichTextEditor @bind-Value="content" 
                  UseToolbarContributors="true" />

Implementing a Toolbar Contributor

Create a class that implements IRteToolbarContributor:

using SufiChain.SufiBlazor.Contracts.Editors;

public class MediaToolbarContributor : IRteToolbarContributor
{
    // Items with lower Order appear first. Default items use 0-100.
    // Use > 100 to add after defaults, negative values to add before.
    public int Order => 150;

    public Task ConfigureToolbarAsync(RteToolbarContext context)
    {
        // Add an "Insert Media" button
        context.Items.Add(new RteToolbarContributedItem
        {
            Id = "insert-media",
            Label = "Insert Media",
            Icon = "image",
            Tooltip = "Insert media from library",
            Group = "insert",  // Groups: history, heading, formatting, list, alignment, insert, blocks, custom, actions
            Order = 10,
            OnClickAsync = async (actionContext) =>
            {
                // Access services via DI
                var mediaService = actionContext.ServiceProvider.GetService<IMediaService>();
                
                // Get current selection if needed
                var selection = await actionContext.GetSelectionAsync?.Invoke()!;
                
                // Insert HTML at cursor position
                var html = "<img src=\"/media/example.jpg\" alt=\"Example\" />";
                await actionContext.InsertHtmlAsync?.Invoke(html)!;
            },
            // Conditionally show/hide
            IsVisible = () => true,
            // Conditionally enable/disable
            IsEnabled = () => true
        });

        return Task.CompletedTask;
    }
}

Registering Toolbar Contributors

Register your contributor in Program.cs or your module's service configuration:

// Method 1: Using the generic extension method
services.AddSufiBlazor();
services.AddRteToolbarContributor<MediaToolbarContributor>();

// Method 2: Multiple contributors
services.AddSufiBlazor();
services.AddRteToolbarContributor<MediaToolbarContributor>();
services.AddRteToolbarContributor<EmojiToolbarContributor>();

// Method 3: Using RteToolbarOptions configuration
services.AddSufiBlazor(options =>
{
    options.AddContributor<MediaToolbarContributor>();
    options.AddContributor<EmojiToolbarContributor>();
    
    // Optionally disable default toolbar items
    options.IncludeDefaultItems = false;
    
    // Customize group order
    options.GroupOrder = new List<string>
    {
        "formatting",
        "insert",
        "custom",
        "actions"
    };
});

RteToolbarActionContext

The OnClickAsync callback receives an RteToolbarActionContext with useful actions:

Property Type Description
EditorId string The unique editor instance ID
ServiceProvider IServiceProvider DI service provider
InsertHtmlAsync Func<string, Task> Insert HTML at cursor
InsertImageAsync Func<string, string?, Task> Insert image (src, alt)
InsertLinkAsync Func<string, string?, Task> Insert link (url, text)
GetSelectionAsync Func<Task<string?>> Get selected text
GetHtmlAsync Func<Task<string?>> Get editor HTML content

Toolbar Groups

Items are organized into groups. Use the Group property to place your item:

Group Description
history Undo/Redo buttons
heading Header formatting (H1-H6)
formatting Bold, Italic, Underline, etc.
list Ordered/Unordered lists
alignment Text alignment
insert Links, Images, Files
blocks Blockquote, Code blocks
custom Default group for contributed items
actions Clear formatting, etc.

Complete Example: Emoji Picker Contributor

public class EmojiToolbarContributor : IRteToolbarContributor
{
    public int Order => 200;

    public Task ConfigureToolbarAsync(RteToolbarContext context)
    {
        var emojis = new[] { "😀", "😊", "👍", "❤️", "🎉" };

        foreach (var (emoji, index) in emojis.Select((e, i) => (e, i)))
        {
            context.Items.Add(new RteToolbarContributedItem
            {
                Id = $"emoji-{index}",
                Label = emoji,
                Tooltip = $"Insert {emoji}",
                Group = "insert",
                Order = 100 + index,
                OnClickAsync = async (actionContext) =>
                {
                    await actionContext.InsertHtmlAsync?.Invoke(emoji)!;
                }
            });
        }

        return Task.CompletedTask;
    }
}