Skip to content

Commit

Permalink
Release 0.1.0 version (#1)
Browse files Browse the repository at this point in the history
* Initial code

* Add i18n support

* Add Viewer component
  • Loading branch information
ling921 committed Jul 8, 2023
1 parent 0dc26b4 commit 2fa7648
Show file tree
Hide file tree
Showing 108 changed files with 8,173 additions and 2 deletions.
123 changes: 121 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,121 @@
# tui.editor.blazor
A Blazor component that provides a Markdown editor based on the ToastUI Editor library.
# ToastUI Editor Blazor

`ToastUIEditor.Blazor` is a Blazor component that provides a Markdown editor based on the [tui.editor](https://github.com/nhn/tui.editor) library.

## Installation

Install the package using following command:

``` Package Manager
Install-Package ToastUIEditor.Blazor
```

or

``` powershell
dotnet add package ToastUIEditor.Blazor
```

or just use nuget package manager.

## Usage

1. Add the following import statement to your `_Imports.razor` file

``` razor
@using ToastUI
```

2. Use the `Editor` component in your Blazor page or component

``` razor
<Editor @bind-Value="content" Options="@options" />
```

- `@bind-Value`: Binds the editor's content to a string property in your Blazor component.
- `Options`: Sets the configuration options for the editor. Refer to the `EditorOptions` class for available options.

3. Use the `Viewer` component in your Blazor page or component

``` razor
<Viewer Value="@content" />
```

- `Value`: Sets the content to be displayed in the viewer. It will update automatically when `content` changes.

1. Handle the available events by specifying event callbacks

``` razor
<Editor @bind-Value="content"
OnLoad="HandleLoad"
OnChange="HandleChange"
OnCaretChange="HandleCaretChange"
OnFocus="HandleFocus"
OnBlur="HandleBlur"
OnKeydown="HandleKeydown"
OnKeyup="HandleKeyup"
BeforePreviewRender="HandleBeforePreviewRender"
BeforeConvertWysiwygToMarkdown="HandleBeforeConvertWysiwygToMarkdown" />
<Viewer Value="content"
OnLoad="HandleLoad"
OnChange="HandleChange"
OnCaretChange="HandleCaretChange"
OnFocus="HandleFocus"
OnBlur="HandleBlur" />
```

These events are the same as the native public events, and the parameters are detailed in the code comments.

> Notes: It seems that events for `Viewer` are not working in original library.
5. Access the `Editor` or `Viewer` instance to invoke methods

``` razor
<Editor @ref="editorRef" @bind-Value="markdown" Options="@options" />
<Editor @ref="viewerRef" Value="markdown" />
<button @onclick="HandlePreview">Preview</button>
<Editor @ref="viewerRef2"/>
@code {
Editor editorRef = default!;
Viewer viewerRef = default!;
Viewer viewerRef2 = default!;
string markdown = string.Empty;
async Task HandlePreview()
{
var markdown = await editorRef.GetMarkdown();
await viewerRef2.SetMarkdown(markdown);
}
}
```

Most of all native methods have been implemented. Refer to the Editor class for available methods.

6. Add custom language

Use `EditorLanguage.Add` method to add custom language.

You can check `EditorLanguage` class for more details.

## Implemented Features

- [x] `Editor` and `Viewer` basic usage
- [x] `Editor` and `Viewer` events
- [x] Language setting and custom language
- [x] `Editor` and `Viewer` instance methods
- [ ] Toolbar with custom button
- [ ] Add command and execute command
- [ ] Add widget and set widget rules
- [ ] Link attributes
- [ ] Custom markdown renderer
- [ ] Custom HTML renderer
- [ ] Custom HTML Sanitizer

## License

This software is licensed under the [MIT License](LICENSE)
60 changes: 60 additions & 0 deletions ToastUIEditor.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3EFCFD32-EC2A-40B3-9A4D-32DD3FD98A29}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToastUIEditor", "src\ToastUIEditor\ToastUIEditor.csproj", "{8D6E935A-3EDC-4774-95ED-1D4C2D7C71F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.WebAssembly", "samples\Sample.WebAssembly\Sample.WebAssembly.csproj", "{AF550182-86F1-4A49-960A-80CB77B0DA2D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{73CA8193-E7DD-47DD-91E9-A3183F63AF53}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Server", "samples\Sample.Server\Sample.Server.csproj", "{3A6D3576-0D9F-4342-A9C2-C6C782DC3C69}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "git", "git", "{F6BA15F6-D725-4678-B0DC-EB51B9D8A0C3}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ToastUIEditor.Generators", "src\ToastUIEditor.Generators\ToastUIEditor.Generators.csproj", "{F3C426CF-BC81-4EB3-A765-D535B545F889}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8D6E935A-3EDC-4774-95ED-1D4C2D7C71F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D6E935A-3EDC-4774-95ED-1D4C2D7C71F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D6E935A-3EDC-4774-95ED-1D4C2D7C71F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D6E935A-3EDC-4774-95ED-1D4C2D7C71F0}.Release|Any CPU.Build.0 = Release|Any CPU
{AF550182-86F1-4A49-960A-80CB77B0DA2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF550182-86F1-4A49-960A-80CB77B0DA2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF550182-86F1-4A49-960A-80CB77B0DA2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF550182-86F1-4A49-960A-80CB77B0DA2D}.Release|Any CPU.Build.0 = Release|Any CPU
{3A6D3576-0D9F-4342-A9C2-C6C782DC3C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A6D3576-0D9F-4342-A9C2-C6C782DC3C69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A6D3576-0D9F-4342-A9C2-C6C782DC3C69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A6D3576-0D9F-4342-A9C2-C6C782DC3C69}.Release|Any CPU.Build.0 = Release|Any CPU
{F3C426CF-BC81-4EB3-A765-D535B545F889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3C426CF-BC81-4EB3-A765-D535B545F889}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3C426CF-BC81-4EB3-A765-D535B545F889}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3C426CF-BC81-4EB3-A765-D535B545F889}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8D6E935A-3EDC-4774-95ED-1D4C2D7C71F0} = {3EFCFD32-EC2A-40B3-9A4D-32DD3FD98A29}
{AF550182-86F1-4A49-960A-80CB77B0DA2D} = {73CA8193-E7DD-47DD-91E9-A3183F63AF53}
{3A6D3576-0D9F-4342-A9C2-C6C782DC3C69} = {73CA8193-E7DD-47DD-91E9-A3183F63AF53}
{F3C426CF-BC81-4EB3-A765-D535B545F889} = {3EFCFD32-EC2A-40B3-9A4D-32DD3FD98A29}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0061DAEB-12EF-4726-8823-079AA281A99A}
EndGlobalSection
EndGlobal
Binary file added resources/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions samples/Sample.Server/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
13 changes: 13 additions & 0 deletions samples/Sample.Server/Data/WeatherForecast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Sample.Server.Data
{
public class WeatherForecast
{
public DateOnly Date { get; set; }

public int TemperatureC { get; set; }

public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

public string? Summary { get; set; }
}
}
20 changes: 20 additions & 0 deletions samples/Sample.Server/Data/WeatherForecastService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Sample.Server.Data
{
public class WeatherForecastService
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

public Task<WeatherForecast[]> GetForecastAsync(DateOnly startDate)
{
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray());
}
}
}
18 changes: 18 additions & 0 deletions samples/Sample.Server/Pages/Counter.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
private int currentCount = 0;

private void IncrementCount()
{
currentCount++;
}
}
42 changes: 42 additions & 0 deletions samples/Sample.Server/Pages/Error.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@page
@model Sample.Server.Pages.ErrorModel

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Error</title>
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
</head>

<body>
<div class="main">
<div class="content px-4">
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
</div>
</div>
</body>

</html>
27 changes: 27 additions & 0 deletions samples/Sample.Server/Pages/Error.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;

namespace Sample.Server.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

private readonly ILogger<ErrorModel> _logger;

public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}

public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
47 changes: 47 additions & 0 deletions samples/Sample.Server/Pages/FetchData.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@page "/fetchdata"
@using Sample.Server.Data
@inject WeatherForecastService ForecastService

<PageTitle>Weather forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from a service.</p>

@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}

@code {
private WeatherForecast[]? forecasts;

protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
}
}
Loading

0 comments on commit 2fa7648

Please sign in to comment.