-
-
Notifications
You must be signed in to change notification settings - Fork 7
feat(Vditor): add Vditor component #466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
dc2bf00
chore: 增加组件资源
ArgoZhang 8cfd0e1
feat: 增加 Vditor 组件
ArgoZhang 1a1f82b
chore: 增加 Vditor 工程
ArgoZhang 3d74a20
feat: 完善组件功能
ArgoZhang 5f3cf80
fix: 修复插入值逻辑
ArgoZhang 8f8ded8
refactor: 更新获得选择值方法名称
ArgoZhang 170be15
refactor: 更正 disabled 方法名
ArgoZhang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/components/BootstrapBlazor.Vditor/BootstrapBlazor.Vditor.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk.Razor"> | ||
|
|
||
| <PropertyGroup> | ||
| <Version>9.0.0</Version> | ||
| </PropertyGroup> | ||
|
|
||
| <PropertyGroup> | ||
| <PackageTags>Bootstrap Blazor WebAssembly wasm UI Components Vditor Markdown</PackageTags> | ||
| <Description>Bootstrap UI components extensions of Vditor Markdown</Description> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="BootstrapBlazor" Version="$(BBVersion)" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <Using Include="Microsoft.JSInterop" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| @namespace BootstrapBlazor.Components | ||
| @inherits ValidateBase<string> | ||
| @attribute [JSModuleAutoLoader("./_content/BootstrapBlazor.Vditor/Vditor.razor.js", JSObjectReference = true)] | ||
|
|
||
| <div @attributes="@AdditionalAttributes" class="@ClassString" id="@Id"></div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,341 @@ | ||
| // Copyright (c) Argo Zhang (argo@163.com). All rights reserved. | ||
| // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
| // Website: https://www.blazor.zone or https://argozhang.github.io/ | ||
|
|
||
| using Microsoft.AspNetCore.Components; | ||
|
|
||
| namespace BootstrapBlazor.Components; | ||
|
|
||
| /// <summary> | ||
| /// Vditor markdown component | ||
| /// </summary> | ||
| public partial class Vditor | ||
| { | ||
| /// <summary> | ||
| /// 获得/设置 组件 <see cref="VditorOptions"/> 实例 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public VditorOptions? Options { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 组件渲染完毕回调方法 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<Task>? OnRenderedAsync { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 组件输入时回调方法 高频触发 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<string, Task>? OnInputAsync { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 组件获得焦点时回调方法 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<string, Task>? OnFocusAsync { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 组件失去焦点时回调方法 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<string, Task>? OnBlurAsync { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 组件选择内容时回调方法 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<string, Task>? OnSelectAsync { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 组件按 ESC 案件时回调方法 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<string, Task>? OnEscapeAsync { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// 获得/设置 组件按 Ctrl + Enter 组合案件时回调方法 默认 null | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<string, Task>? OnCtrlEnterAsync { get; set; } | ||
|
|
||
| private string? ClassString => CssBuilder.Default("bb-vditor") | ||
| .AddClassFromAttributes(AdditionalAttributes) | ||
| .Build(); | ||
|
|
||
| private string? _lastValue; | ||
| private IJSObjectReference? _vditor; | ||
|
|
||
| /// <summary> | ||
| /// <inheritdoc/> | ||
| /// </summary> | ||
| /// <param name="firstRender"></param> | ||
| /// <returns></returns> | ||
| protected override async Task OnAfterRenderAsync(bool firstRender) | ||
| { | ||
| await base.OnAfterRenderAsync(firstRender); | ||
|
|
||
| if (firstRender) | ||
| { | ||
| _lastValue = Value; | ||
| return; | ||
| } | ||
|
|
||
| if (_lastValue != Value) | ||
| { | ||
| _lastValue = Value; | ||
| if (_vditor != null) | ||
| { | ||
| await _vditor.InvokeVoidAsync("setValue", Value, true); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// <inheritdoc/> | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| protected override async Task InvokeInitAsync() | ||
| { | ||
| _vditor = await InvokeAsync<IJSObjectReference>("init", Id, Interop, new | ||
| { | ||
| Options, | ||
| Value | ||
| }); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 重新设置编辑器方法 | ||
| /// </summary> | ||
| /// <param name="value"></param> | ||
| /// <param name="options"></param> | ||
| /// <returns></returns> | ||
| public async Task Reset(string value, VditorOptions options) | ||
| { | ||
| if (!string.IsNullOrEmpty(value)) | ||
| { | ||
| Value = value; | ||
| } | ||
| _vditor = await InvokeAsync<IJSObjectReference>("reset", Id, Value, Options); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 在焦点处插入内容,并默认进行 Markdown 渲染 | ||
| /// </summary> | ||
| /// <param name="value">要插入的 markdown 值</param> | ||
| /// <param name="render">是否渲染</param> | ||
| public async ValueTask InsertValueAsync(string? value, bool render = true) | ||
| { | ||
| if (_vditor != null) | ||
| { | ||
| await _vditor.InvokeVoidAsync("insertValue", value, render); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 获取编辑器的 markdown 内容 | ||
| /// </summary> | ||
| public async ValueTask<string?> GetValueAsync() | ||
| { | ||
| string? ret = null; | ||
| if (_vditor != null) | ||
| { | ||
| ret = await _vditor.InvokeAsync<string?>("getValue"); | ||
| } | ||
| return ret; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 获取 markdown 渲染后的 HTML | ||
| /// </summary> | ||
| public async ValueTask<string?> GetHtmlAsync() | ||
| { | ||
| string? ret = null; | ||
| if (_vditor != null) | ||
| { | ||
| ret = await _vditor.InvokeAsync<string?>("getHTML"); | ||
| } | ||
| return ret; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 返回选中的字符串 | ||
| /// </summary> | ||
| public async ValueTask<string?> GetSelectionAsync() | ||
| { | ||
| string? ret = null; | ||
| if (_vditor != null) | ||
| { | ||
| ret = await _vditor.InvokeAsync<string?>("getSelection"); | ||
| } | ||
| return ret; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 解除编辑器禁用 | ||
| /// </summary> | ||
| public async ValueTask EnableAsync() | ||
| { | ||
| if (_vditor != null) | ||
| { | ||
| await _vditor.InvokeVoidAsync("enable"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 禁用编辑器 | ||
| /// </summary> | ||
| public async ValueTask DisableAsync() | ||
| { | ||
| if (_vditor != null) | ||
| { | ||
| await _vditor.InvokeVoidAsync("disabled"); | ||
|
Comment on lines
+188
to
+192
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Calling incorrect Vditor API method for disabling Use |
||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 聚焦编辑器 | ||
| /// </summary> | ||
| public async ValueTask FocusAsync() | ||
| { | ||
| if (_vditor != null) | ||
| { | ||
| await _vditor.InvokeVoidAsync("focus"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 让编辑器失去焦点 | ||
| /// </summary> | ||
| public async ValueTask BlurAsync() | ||
| { | ||
| if (_vditor != null) | ||
| { | ||
| await _vditor.InvokeAsync<string?>("blur"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 客户端渲染完毕回调方法由 JavaScript 调用 | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerRenderedAsync() | ||
| { | ||
| if (OnRenderedAsync != null) | ||
| { | ||
| await OnRenderedAsync(); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 组件录入时回调方法由 JavaScript 调用 | ||
| /// </summary> | ||
| /// <param name="value"></param> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerInputAsync(string value) | ||
| { | ||
| if (OnInputAsync != null) | ||
| { | ||
| _lastValue = value; | ||
| CurrentValue = value; | ||
| await OnInputAsync(value); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 触发 Value 值改变回调方法由 JavaScript 调用 | ||
| /// </summary> | ||
| /// <param name="value"></param> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerFocusAsync(string value) | ||
| { | ||
| if (OnFocusAsync != null) | ||
| { | ||
| await OnFocusAsync(value); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 触发 Value 值改变回调方法由 JavaScript 调用 | ||
| /// </summary> | ||
| /// <param name="value"></param> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerBlurAsync(string value) | ||
| { | ||
| if (OnBlurAsync != null) | ||
| { | ||
| _lastValue = value; | ||
| CurrentValue = value; | ||
| await OnBlurAsync(value); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 触发 Value 值改变回调方法由 JavaScript 调用 | ||
| /// </summary> | ||
| /// <param name="value"></param> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerSelectAsync(string value) | ||
| { | ||
| if (OnSelectAsync != null) | ||
| { | ||
| await OnSelectAsync(value); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 触发 Value 值改变回调方法由 JavaScript 调用 | ||
| /// </summary> | ||
| /// <param name="value"></param> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerEscapeAsync(string value) | ||
| { | ||
| if (OnEscapeAsync != null) | ||
| { | ||
| _lastValue = value; | ||
| CurrentValue = value; | ||
| await OnEscapeAsync(value); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// 触发 Value 值改变回调方法由 JavaScript 调用 | ||
| /// </summary> | ||
| /// <param name="value"></param> | ||
| /// <returns></returns> | ||
| [JSInvokable] | ||
| public async Task TriggerCtrlEnterAsync(string value) | ||
| { | ||
| if (OnCtrlEnterAsync != null) | ||
| { | ||
| _lastValue = value; | ||
| CurrentValue = value; | ||
| await OnCtrlEnterAsync(value); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// <inheritdoc/> | ||
| /// </summary> | ||
| /// <param name="disposing"></param> | ||
| /// <returns></returns> | ||
| protected override async ValueTask DisposeAsync(bool disposing) | ||
| { | ||
| if (disposing) | ||
| { | ||
| if (_vditor != null) | ||
| { | ||
| await _vditor.DisposeAsync(); | ||
| _vditor = null; | ||
| } | ||
|
|
||
| await base.DisposeAsync(disposing); | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Reset uses the
Optionsproperty instead of the passed-in parameterPass the
optionsparameter to JS instead of the component'sOptionsproperty, or update the property before invoking JS to ensure the correct configuration is used.