mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-11-29 18:49:08 +08:00
doc(Website): use web app template (#2386)
* refactor: 更新 App/Routes 组件 * chore: 更新 Program 文件 * refactor: 临时取消登录集成 * refactor: 增加 MVC 路由表 * chore: 更新路由配置 * chore: 合并工程 * refactor: 修改命名空间 * chore: 更新 nginx 配置文件 * chore: remove dist folder * doc: 更正单词拼写错误 * chore: 更新解决方案 * refactor: 更新命名空间 * chore: 更新命名空间 * chore: 更新命名空间 * chore: 整理命名空间 * chore: 更新命名空间 * chore: 更正脚本路径 * chore: 精简依赖 * refactor: 禁用授权 * refactor: 移除渲染方式 * refactor: 更改为服务器端渲染模式 * chore: 更新字典 * doc: 重构代码 * refactor: 增加 BootstrapBlazorRoot 组件 * doc: 更新 responsive 脚本 --------- Co-authored-by: zhangpeihang <948869991@qq.com>
This commit is contained in:
parent
14a46b0f43
commit
55957c39a9
@ -26,14 +26,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "windows", "windows", "{4A52
|
||||
scripts\windows\push.ps1 = scripts\windows\push.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dist", "dist", "{63E887C6-4610-4ED3-91F4-62EFDE7F442F}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
dist\.gitattributes = dist\.gitattributes
|
||||
dist\.nojekyll = dist\.nojekyll
|
||||
dist\.spa = dist\.spa
|
||||
dist\404.html = dist\404.html
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wasm", "wasm", "{B84D315E-967D-4FBF-9B72-1F3128155CB0}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
scripts\wasm\sync.cmd = scripts\wasm\sync.cmd
|
||||
@ -56,8 +48,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapBlazor.Markdown",
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapBlazor.TableExport", "src\Extensions\Components\BootstrapBlazor.TableExport\BootstrapBlazor.TableExport.csproj", "{5ED0DD16-1583-4FC3-B2E9-FE5DBA98BD47}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapBlazor.Shared", "src\BootstrapBlazor.Shared\BootstrapBlazor.Shared.csproj", "{C63F35FD-FE14-4517-9457-9DA43F0DCB9E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapBlazor.Server", "src\BootstrapBlazor.Server\BootstrapBlazor.Server.csproj", "{1ED371F3-2B28-4B2D-91B8-0C00DA42CB65}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapBlazor.WebAssembly.ClientHost", "src\Wasm\BootstrapBlazor.WebAssembly.ClientHost\BootstrapBlazor.WebAssembly.ClientHost.csproj", "{0556D9AB-8673-4248-8817-4D99F4DCC568}"
|
||||
@ -155,10 +145,6 @@ Global
|
||||
{5ED0DD16-1583-4FC3-B2E9-FE5DBA98BD47}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5ED0DD16-1583-4FC3-B2E9-FE5DBA98BD47}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5ED0DD16-1583-4FC3-B2E9-FE5DBA98BD47}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C63F35FD-FE14-4517-9457-9DA43F0DCB9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C63F35FD-FE14-4517-9457-9DA43F0DCB9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C63F35FD-FE14-4517-9457-9DA43F0DCB9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C63F35FD-FE14-4517-9457-9DA43F0DCB9E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1ED371F3-2B28-4B2D-91B8-0C00DA42CB65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1ED371F3-2B28-4B2D-91B8-0C00DA42CB65}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1ED371F3-2B28-4B2D-91B8-0C00DA42CB65}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -296,7 +282,6 @@ Global
|
||||
{337FABF3-4318-408E-8544-C0F20D0197A1} = {CD062AB6-244D-402A-8F33-C37DAC5856CC}
|
||||
{EEB9751A-5C06-4725-8037-FA9C0F140018} = {CD062AB6-244D-402A-8F33-C37DAC5856CC}
|
||||
{5ED0DD16-1583-4FC3-B2E9-FE5DBA98BD47} = {CD062AB6-244D-402A-8F33-C37DAC5856CC}
|
||||
{C63F35FD-FE14-4517-9457-9DA43F0DCB9E} = {A2182155-43ED-44C1-BF6F-1B70EBD2DFFE}
|
||||
{1ED371F3-2B28-4B2D-91B8-0C00DA42CB65} = {A2182155-43ED-44C1-BF6F-1B70EBD2DFFE}
|
||||
{0556D9AB-8673-4248-8817-4D99F4DCC568} = {C8E79F4C-8C55-4E13-96B5-3D2BD6A07B74}
|
||||
{FFFD2EB7-AE88-4DAD-A825-528B2CEFB4B5} = {C8E79F4C-8C55-4E13-96B5-3D2BD6A07B74}
|
||||
|
@ -3,7 +3,6 @@
|
||||
"path": "BootstrapBlazor.sln",
|
||||
"projects": [
|
||||
"src\\BootstrapBlazor.Server\\BootstrapBlazor.Server.csproj",
|
||||
"src\\BootstrapBlazor.Shared\\BootstrapBlazor.Shared.csproj",
|
||||
"src\\BootstrapBlazor\\BootstrapBlazor.csproj",
|
||||
"test\\UniTest.Sass\\UniTest.Sass.csproj",
|
||||
"test\\UnitTest\\UnitTest.csproj"
|
||||
|
63
dist/.gitattributes
vendored
63
dist/.gitattributes
vendored
@ -1,63 +0,0 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* binary
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
0
dist/.nojekyll
vendored
0
dist/.nojekyll
vendored
2
dist/.spa
vendored
2
dist/.spa
vendored
@ -1,2 +0,0 @@
|
||||
This file is used to enable gitee pages' spa mode.
|
||||
https://gitee.com/help/articles/4237
|
40
dist/404.html
vendored
40
dist/404.html
vendored
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Single Page Apps for GitHub Pages</title>
|
||||
<script type="text/javascript">
|
||||
// Single Page Apps for GitHub Pages
|
||||
// https://github.com/rafrex/spa-github-pages
|
||||
// Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
|
||||
// ----------------------------------------------------------------------
|
||||
// This script takes the current url and converts the path and query
|
||||
// string into just a query string, and then redirects the browser
|
||||
// to the new url with only a query string and hash fragment,
|
||||
// e.g. http://www.foo.tld/one/two?a=b&c=d#qwe, becomes
|
||||
// http://www.foo.tld/?p=/one/two&q=a=b~and~c=d#qwe
|
||||
// Note: this 404.html file must be at least 512 bytes for it to work
|
||||
// with Internet Explorer (it is currently > 512 bytes)
|
||||
|
||||
// If you're creating a Project Pages site and NOT using a custom domain,
|
||||
// then set segmentCount to 1 (enterprise users may need to set it to > 1).
|
||||
// This way the code will only replace the route part of the path, and not
|
||||
// the real directory in which the app resides, for example:
|
||||
// https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
|
||||
// https://username.github.io/repo-name/?p=/one/two&q=a=b~and~c=d#qwe
|
||||
// Otherwise, leave segmentCount as 0.
|
||||
var segmentCount = 0;
|
||||
|
||||
var l = window.location;
|
||||
l.replace(
|
||||
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
|
||||
l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?p=/' +
|
||||
l.pathname.slice(1).split('/').slice(segmentCount).join('/').replace(/&/g, '~and~') +
|
||||
(l.search ? '&q=' + l.search.slice(1).replace(/&/g, '~and~') : '') +
|
||||
l.hash
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
72
dist/gitee-pages/404.html
vendored
72
dist/gitee-pages/404.html
vendored
@ -1,72 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bootstrap Blazor 演示网站</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<meta content="bootstrap,blazor,wasm,webassembly,UI,netcore,web,assembly" name="Keywords">
|
||||
<base href="/bootstrapblazor/">
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="icon-512.png">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" href="style/loading.css">
|
||||
<link rel="stylesheet" href="_content/BootstrapBlazor/lib/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="_content/BootstrapBlazor/lib/font-awesome/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="_content/BootstrapBlazor/lib/chartjs/Chart.min.css">
|
||||
<link rel="stylesheet" href="_content/BootstrapBlazor/lib/summernote/summernote-bs4.min.css">
|
||||
<link rel="stylesheet" href="_content/BootstrapBlazor/css/bootstrap.blazor.css">
|
||||
<link rel="stylesheet" href="_content/BootstrapBlazor.Shared/lib/highlight/vs.css">
|
||||
<link rel="stylesheet" href="_content/BootstrapBlazor.Shared/css/site.css">
|
||||
</head>
|
||||
|
||||
<body class="overflow-hidden">
|
||||
<app></app>
|
||||
|
||||
<div class="loader" id="loading">
|
||||
<div class="logo">
|
||||
<div class="one common"></div>
|
||||
<div class="two common"></div>
|
||||
<div class="three common"></div>
|
||||
<div class="four common"></div>
|
||||
<div class="five common"></div>
|
||||
<div class="six common"></div>
|
||||
<div class="seven common"></div>
|
||||
<div class="eight common"></div>
|
||||
</div>
|
||||
<div class="intro">
|
||||
<img src="_content/BootstrapBlazor.Shared/images/brand.png" />
|
||||
<span>精彩即将呈现</span>
|
||||
</div>
|
||||
<div class="bar">
|
||||
<div class="progress"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
An error has occurred. This application may no longer respond until reloaded.
|
||||
</environment>
|
||||
<environment include="Development">
|
||||
An unhandled exception has occurred. See browser dev tools for details.
|
||||
</environment>
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss"><i class="fa-solid fa-xmark"></i></a>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script>navigator.serviceWorker.register('service-worker.js');</script>
|
||||
<script src="_content/BootstrapBlazor/lib/jquery/jquery.min.js"></script>
|
||||
<script src="_content/BootstrapBlazor/lib/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="_content/BootstrapBlazor/lib/chartjs/Chart.bundle.min.js"></script>
|
||||
<script src="_content/BootstrapBlazor/lib/summernote/summernote-bs4.min.js"></script>
|
||||
<script src="_content/BootstrapBlazor/lib/summernote/summernote-zh-CN.min.js"></script>
|
||||
<script src="_content/BootstrapBlazor/lib/slimscroll/jquery.slimscroll.min.js"></script>
|
||||
<script src="_content/BootstrapBlazor/js/bootstrap.blazor.js"></script>
|
||||
<script src="_content/BootstrapBlazor.Shared/lib/highlight/highlight.min.js"></script>
|
||||
<script src="_content/BootstrapBlazor.Shared/js/common.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -38,3 +38,8 @@ xmark
|
||||
Func
|
||||
Prev
|
||||
Textarea
|
||||
rendermode
|
||||
motronic
|
||||
webassembly
|
||||
netcore
|
||||
oscs
|
||||
|
@ -1,3 +1,16 @@
|
||||
#user nobody;
|
||||
worker_processes 1;
|
||||
|
||||
#error_log logs/error.log;
|
||||
#error_log logs/error.log notice;
|
||||
#error_log logs/error.log info;
|
||||
|
||||
#pid logs/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
upstream blazor {
|
||||
server localhost:50853;
|
||||
|
@ -2,7 +2,7 @@
|
||||
@using Azure.AI.OpenAI
|
||||
@using BootstrapBlazor.Server.OAuth;
|
||||
@inherits BootstrapModuleComponentBase
|
||||
@attribute [JSModuleAutoLoader("./AIChat/Chats.razor.js")]
|
||||
@attribute [JSModuleAutoLoader("AIChat/Chats.razor.js")]
|
||||
|
||||
<h3>@Localizer["ChatsTitle"]</h3>
|
||||
|
||||
|
@ -5,6 +5,27 @@
|
||||
<UserSecretsId>dd866c36-9a9b-4dda-bce0-44c91d3094cc</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="docs.json" />
|
||||
<Content Remove="Locales\en.json" />
|
||||
<Content Remove="Locales\zh.json" />
|
||||
<Content Remove="menus.json" />
|
||||
<Content Remove="topology.json" />
|
||||
<Content Remove="versionconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="docs.json" />
|
||||
<EmbeddedResource Include="Locales\en.json" />
|
||||
<EmbeddedResource Include="Locales\zh.json" />
|
||||
<EmbeddedResource Include="topology.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="menus.json" />
|
||||
<None Include="versionconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor.Middleware" Version="7.*" />
|
||||
<PackageReference Include="Longbow.Logging" Version="6.0.6" />
|
||||
@ -12,17 +33,48 @@
|
||||
<PackageReference Include="Longbow.GitHubAuth" Version="7.0.1" />
|
||||
<PackageReference Include="Longbow.OAuth" Version="7.0.0" />
|
||||
<PackageReference Include="Longbow.Tasks" Version="5.*" />
|
||||
<PackageReference Include="BootstrapBlazor.AzureOpenAI" Version="7.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.BaiduSpeech" Version="7.1.0" />
|
||||
<PackageReference Include="BootstrapBlazor.BaiduOcr" Version="7.1.1" />
|
||||
<PackageReference Include="BootstrapBlazor.BarCode" Version="7.1.5" />
|
||||
<PackageReference Include="BootstrapBlazor.Bluetooth" Version="7.1.0" />
|
||||
<PackageReference Include="BootstrapBlazor.Chart" Version="7.6.1" />
|
||||
<PackageReference Include="BootstrapBlazor.CherryMarkdown" Version="7.2.1" />
|
||||
<PackageReference Include="BootstrapBlazor.CodeEditor" Version="7.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.Dock" Version="7.0.12" />
|
||||
<PackageReference Include="BootstrapBlazor.FileViewer" Version="7.0.3" />
|
||||
<PackageReference Include="BootstrapBlazor.FontAwesome" Version="7.5.0" />
|
||||
<PackageReference Include="BootstrapBlazor.Gantt" Version="7.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.Html2Pdf" Version="7.2.0" />
|
||||
<PackageReference Include="BootstrapBlazor.Live2DDisplay" Version="7.0.1" />
|
||||
<PackageReference Include="BootstrapBlazor.Markdown" Version="7.2.2" />
|
||||
<PackageReference Include="BootstrapBlazor.MaterialDesign" Version="7.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.MaterialDesign.Extensions" Version="7.4.1" />
|
||||
<PackageReference Include="BootstrapBlazor.OnScreenKeyboard" Version="7.0.1" />
|
||||
<PackageReference Include="BootstrapBlazor.PdfReader" Version="7.2.0" />
|
||||
<PackageReference Include="BootstrapBlazor.SignaturePad" Version="7.0.3" />
|
||||
<PackageReference Include="BootstrapBlazor.Splitting" Version="7.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.SummerNote" Version="7.3.4" />
|
||||
<PackageReference Include="BootstrapBlazor.TableExport" Version="7.6.1" />
|
||||
<PackageReference Include="BootstrapBlazor.Topology" Version="7.4.6" />
|
||||
<PackageReference Include="BootstrapBlazor.VideoPlayer" Version="7.0.4" />
|
||||
<PackageReference Include="BootstrapBlazor.MouseFollower" Version="7.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.WebAPI" Version="7.5.3" />
|
||||
<PackageReference Include="BootstrapBlazor.MindMap" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BootstrapBlazor.Shared\BootstrapBlazor.Shared.csproj" />
|
||||
<ProjectReference Include="..\BootstrapBlazor\BootstrapBlazor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="BootstrapBlazor.Components" />
|
||||
<Using Include="BootstrapBlazor.Shared.Common" />
|
||||
<Using Include="BootstrapBlazor.Shared.Components" />
|
||||
<Using Include="BootstrapBlazor.Shared.Samples" />
|
||||
<Using Include="BootstrapBlazor.Server.Components.Components" />
|
||||
<Using Include="BootstrapBlazor.Server.Components.Layout" />
|
||||
<Using Include="BootstrapBlazor.Server.Data" />
|
||||
<Using Include="BootstrapBlazor.Server.Extensions" />
|
||||
<Using Include="BootstrapBlazor.Server.Services" />
|
||||
<Using Include="Microsoft.AspNetCore.Components" />
|
||||
<Using Include="Microsoft.Extensions.Localization" />
|
||||
<Using Include="System.ComponentModel.DataAnnotations" />
|
||||
</ItemGroup>
|
||||
|
@ -0,0 +1,13 @@
|
||||
<div class="table-attr">
|
||||
<h4>@Title</h4>
|
||||
|
||||
<Table TItem="AttributeItem" Items="Items">
|
||||
<TableColumns>
|
||||
<TableColumn @bind-Field="@context.Name" />
|
||||
<TableColumn @bind-Field="@context.Description" TextWrap="true" />
|
||||
<TableColumn @bind-Field="@context.Type" />
|
||||
<TableColumn @bind-Field="@context.ValueList" TextWrap="true" />
|
||||
<TableColumn @bind-Field="@context.DefaultValue" />
|
||||
</TableColumns>
|
||||
</Table>
|
||||
</div>
|
@ -0,0 +1,37 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class AttributeTable
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<AttributeTable>? Localizer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter] public IEnumerable<AttributeItem>? Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
Title ??= Localizer[nameof(Title)];
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
<img alt="logo" class="bb-icon" src="./images/logo.png" />
|
@ -0,0 +1,8 @@
|
||||
.bb-icon {
|
||||
width: 42px;
|
||||
height: auto;
|
||||
border-radius: var(--bs-border-radius);
|
||||
background-color: var(--bs-info);
|
||||
border: solid 1px #fff;
|
||||
margin-right: 1rem;
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
@inject IOptionsMonitor<WebsiteOptions> WebsiteOption
|
||||
|
||||
<Reconnector>
|
||||
<ReconnectingTemplate>
|
||||
<div class="connection-mask"></div>
|
||||
<div class="connection-body">
|
||||
<div class="row g-3">
|
||||
@RenderBootstrapBlazor
|
||||
<div class="col-12 col-sm-5">
|
||||
<h5>Reconnector 组件</h5>
|
||||
<div class="mb-2"><b>正在尝试重新连接服务器</b></div>
|
||||
<div class="mb-2">服务器正在更新新版本,稍等一会儿即可提供服务,或者 <kbd>F12</kbd> 打开 <b>Developer tools</b> 查看 <b>控制台</b> 是否有错误输出,请扫描左侧二维码加群与管理员联系</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-2">
|
||||
<div class="d-flex align-items-center justify-content-center h-100">
|
||||
<a href="javascript:window.Blazor.reconnect()" class="btn btn-primary">重新连接</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ReconnectingTemplate>
|
||||
<ReconnectFailedTemplate>
|
||||
<div class="connection-mask"></div>
|
||||
<div class="connection-body">
|
||||
<div class="row g-3">
|
||||
@RenderBootstrapBlazor
|
||||
<div class="col-12 col-sm-5">
|
||||
<h5>Reconnector 组件</h5>
|
||||
<div class="mb-2"><b>与服务器连接失败</b></div>
|
||||
<div class="mb-2">请确认网络是否正常,或者 <kbd>F12</kbd> 打开 <b>Developer tools</b> 查看 <b>控制台</b> 是否有错误输出,请扫描左侧二维码加群与管理员联系</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-2">
|
||||
<div class="d-flex flex-column align-items-center justify-content-center h-100">
|
||||
<a href="javascript:window.Blazor.reconnect()" class="btn btn-primary mb-2">重新连接</a>
|
||||
<a href="javascript:location.reload()" class="btn btn-info">重新加载</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ReconnectFailedTemplate>
|
||||
<ReconnectRejectedTemplate>
|
||||
<div class="connection-mask"></div>
|
||||
<div class="connection-body">
|
||||
<div class="row g-3">
|
||||
@RenderBootstrapBlazor
|
||||
<div class="col-12 col-sm-5">
|
||||
<h5>Reconnector 组件</h5>
|
||||
<div class="mb-2"><b>服务器拒绝连接</b></div>
|
||||
<div class="mb-2">所有的连接尝试都被拒绝了,这很有可能是由于网络问题或者服务器问题引起的,请扫描左侧二维码加群与管理员联系</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-2">
|
||||
<div class="d-flex flex-column align-items-center justify-content-center h-100">
|
||||
<a href="javascript:location.reload()" class="btn btn-info">重新加载</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ReconnectRejectedTemplate>
|
||||
</Reconnector>
|
||||
|
||||
@code {
|
||||
private string TemplateUrl => $"{WebsiteOption.CurrentValue.BootstrapBlazorLink}/wikis/%E9%A1%B9%E7%9B%AE%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B";
|
||||
|
||||
RenderFragment RenderBootstrapBlazor =>
|
||||
@<div class="col-12 col-sm-5">
|
||||
<h5>Bootstrap Blazor UI 组件库</h5>
|
||||
<div class="d-flex">
|
||||
<div class="flex-fill">
|
||||
<div class="mb-2">一套基于 <b>Bootstrap</b> 样式的企业级 <b>Blazor UI</b> 组件库,支持 Server 与 WebAssembly</div>
|
||||
<div class="mb-2">适配移动端支持各种主流浏览器以及移动端,适配 <b>ABP</b>,同时支持 <b>NET5/NET6/NET7</b></div>
|
||||
<div class="mb-2"></div>
|
||||
<div>已提供项目模板方便快速上手 <a class="connection-link" href="@TemplateUrl" target="_blank">项目模板</a></div>
|
||||
</div>
|
||||
<img altt="QQ" src="./images/QQGroup@2x.png" alt="QQGroup" />
|
||||
<div class="connection-body-tail d-none d-sm-block"></div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<div>
|
||||
<h4 class="mt-3">CSS Variables</h4>
|
||||
@ChildContent
|
||||
</div>
|
@ -0,0 +1,17 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// CSS 组件
|
||||
/// </summary>
|
||||
public partial class CSS
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 子内容
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<div class="calendar-day" @onclick="OnClickCell">
|
||||
<div>@Value.CellValue.Day</div>
|
||||
@if (Value.CellValue.Month == Value.CalendarValue.Month)
|
||||
{
|
||||
<div class="calendar-body">
|
||||
@foreach (var tag in Crews)
|
||||
{
|
||||
<div class="@tag.Color">@tag.Name @tag.Value</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
@ -0,0 +1,56 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class CalendarCrewCell
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 单元格值
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public CalendarCellValue? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<CalendarCellValue> ValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public List<Crew>? Crews { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private DialogService? DialogService { get; set; }
|
||||
|
||||
private async Task OnClickCell()
|
||||
{
|
||||
await DialogService.Show(new DialogOption()
|
||||
{
|
||||
Title = $"明细查看 - {Value.CellValue:yyyy-MM-dd}",
|
||||
Component = BootstrapDynamicComponent.CreateComponent<CalendarCrewDialogBody>(new Dictionary<string, object?>()
|
||||
{
|
||||
[nameof(Value)] = Value,
|
||||
[nameof(Crews)] = Crews
|
||||
}),
|
||||
OnCloseAsync = async () =>
|
||||
{
|
||||
if (ValueChanged.HasDelegate)
|
||||
{
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
.calendar-day {
|
||||
--bb-calendar-cell-height: 101px;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<div>
|
||||
@foreach (var crew in Crews)
|
||||
{
|
||||
<div class="crew d-flex">
|
||||
<div class="flex-fill @crew.Color">
|
||||
@crew.Name
|
||||
</div>
|
||||
<input type="text" readonly value="@crew.Value" />
|
||||
<div class="actions">
|
||||
<span @onclick="() => OnUpdateValue(crew, 1)">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</span>
|
||||
<span @onclick="() => OnUpdateValue(crew, -1)">
|
||||
<i class="fa-solid fa-minus"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
@ -0,0 +1,32 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class CalendarCrewDialogBody
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 单元格值
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public CalendarCellValue? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
[NotNull]
|
||||
public List<Crew>? Crews { get; set; }
|
||||
|
||||
private static void OnUpdateValue(Crew crew, int interval)
|
||||
{
|
||||
crew.Value += interval;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
.actions {
|
||||
border: 1px solid var(--bs-purple);
|
||||
border-radius: var(--bs-border-radius);
|
||||
padding: 1px 1rem;
|
||||
}
|
||||
|
||||
.actions > span {
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: background-color .3s linear;
|
||||
}
|
||||
|
||||
.actions > span:hover {
|
||||
background-color: var(--bs-purple);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.actions > span:not(:last-child) {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.crew:not(:last-child) {
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
.crew > input {
|
||||
max-width: 2rem;
|
||||
margin-right: 1rem;
|
||||
border: none;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<div class="d-flex fw-bold mb-1">
|
||||
<span class="text-success flex-fill">@Timestamp</span>
|
||||
<span>共 @TotalCount 个提交</span>
|
||||
</div>
|
||||
<div>提交作者: <span class="text-info fw-bold">@Author</span></div>
|
||||
<div>分支名称: <span class="text-info fw-bold">@Branch</span></div>
|
||||
<div>提交信息: <a href="@Url" target="_blank">@Message</a></div>
|
@ -0,0 +1,49 @@
|
||||
// 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/
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class CommitItem
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
[EditorRequired]
|
||||
public GiteePostBody? Item { get; set; }
|
||||
|
||||
private string? Author { get; set; }
|
||||
|
||||
private string? Timestamp { get; set; }
|
||||
|
||||
private string? Message { get; set; }
|
||||
|
||||
private string? Url { get; set; }
|
||||
|
||||
private string? Branch { get; set; }
|
||||
|
||||
private string? TotalCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
var commit = Item.HeadCommit;
|
||||
TotalCount = Item.Commits?.Count.ToString() ?? "1";
|
||||
if (commit != null)
|
||||
{
|
||||
Timestamp = commit.Timestamp.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
Author = commit.Author.Name;
|
||||
Message = commit.Message;
|
||||
Url = commit.Url;
|
||||
Branch = Item.GetBranchName();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="@ClassString">
|
||||
<a href="@Url">
|
||||
<div class="card">
|
||||
<div class="card-header">@Text</div>
|
||||
<div class="card-body"><img alt="url" src="@ImageUrl" /></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
@ -0,0 +1,60 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class ComponentCard
|
||||
{
|
||||
private string ImageUrl => $"./images/{Image}";
|
||||
|
||||
private string? ClassString => CssBuilder.Default("col-12 col-sm-6 col-md-4 col-lg-3")
|
||||
.AddClass("d-none", IsHide)
|
||||
.Build();
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 Header 文字
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Text { get; set; } = "未设置";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件图片
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Image { get; set; } = "Divider.svg";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 链接地址
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Url { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
private List<string>? ComponentNames { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
private ComponentCategory? Parent { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
private string? SearchText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
ComponentNames?.Add(Text);
|
||||
Parent?.Add(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal bool IsHide => !string.IsNullOrEmpty(SearchText) && !Text.Contains(SearchText, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<div class="@ClassString">
|
||||
<h3>
|
||||
<span>@Text</span>
|
||||
<RenderTemplate>
|
||||
<Badge IsPill="true" Color="Color.Success">@CardCount</Badge>
|
||||
</RenderTemplate>
|
||||
</h3>
|
||||
|
||||
@if (!string.IsNullOrEmpty(Desc))
|
||||
{
|
||||
<h4>@Desc</h4>
|
||||
}
|
||||
|
||||
<div class="coms-demo">
|
||||
<div class="row g-3">
|
||||
<CascadingValue Value="this" IsFixed="true">
|
||||
@ChildContent
|
||||
</CascadingValue>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,55 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class ComponentCategory
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Desc { get; set; }
|
||||
|
||||
private List<ComponentCard> Cards { get; } = new List<ComponentCard>();
|
||||
|
||||
internal void Add(ComponentCard card) => Cards.Add(card);
|
||||
|
||||
private int CardCount => Cards.Where(c => !c.IsHide).Count();
|
||||
|
||||
private bool IsRendered { get; set; }
|
||||
|
||||
private string? ClassString => CssBuilder.Default("coms-cate")
|
||||
.AddClass("d-none", IsRendered && CardCount == 0)
|
||||
.Build();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
base.OnAfterRender(firstRender);
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
IsRendered = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
.coms-cate {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.coms-cate:not(:first-child) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.coms-cate ::deep .badge {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
margin-left: 1rem;
|
||||
font-size: .65rem;
|
||||
}
|
||||
|
||||
.coms-demo {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.coms-demo ::deep .card {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: box-shadow .3s linear;
|
||||
}
|
||||
|
||||
.coms-demo ::deep .card img {
|
||||
max-width: calc(100%);
|
||||
}
|
||||
|
||||
.coms-demo ::deep .card .card-header {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.coms-demo ::deep .card .card-body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.coms-demo ::deep a {
|
||||
width: calc(100%);
|
||||
height: calc(100%);
|
||||
color: inherit;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<ul>
|
||||
@foreach (var item in Items)
|
||||
{
|
||||
<ContextMenuTrigger WrapperTag="li" ContextItem="item" >
|
||||
<div>@item</div>
|
||||
</ContextMenuTrigger>
|
||||
}
|
||||
</ul>
|
||||
|
||||
@code {
|
||||
private List<string> Items { get; } = new List<string>() { "Test1", "Test2", "Test3" };
|
||||
|
||||
[CascadingParameter]
|
||||
[NotNull]
|
||||
private ContextMenuZone? Zone { get; set; }
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p>Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
@inherits BootstrapComponentBase
|
||||
|
||||
<div @attributes="@AdditionalAttributes" class="@ClassString">
|
||||
<span>@Label</span>
|
||||
<Select Value="@SelectedCulture" OnSelectedItemChanged="@SetCulture">
|
||||
<Options>
|
||||
@foreach (var kv in BootstrapOptions.CurrentValue.GetSupportedCultures())
|
||||
{
|
||||
<SelectOption Text="@GetDisplayName(kv)" Value="@kv.Name" />
|
||||
}
|
||||
</Options>
|
||||
</Select>
|
||||
</div>
|
@ -0,0 +1,98 @@
|
||||
// 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.Extensions.Options;
|
||||
using System.Globalization;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class CultureChooser
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IOptionsMonitor<BootstrapBlazorOptions>? BootstrapOptions { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IOptionsMonitor<WebsiteOptions>? WebsiteOption { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<CultureChooser>? Localizer { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private NavigationManager? NavigationManager { get; set; }
|
||||
|
||||
private string? ClassString => CssBuilder.Default("culture-selector")
|
||||
.AddClassFromAttributes(AdditionalAttributes)
|
||||
.Build();
|
||||
|
||||
private string SelectedCulture { get; set; } = CultureInfo.CurrentUICulture.Name;
|
||||
|
||||
[NotNull]
|
||||
private string? Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
Label ??= Localizer[nameof(Label)];
|
||||
}
|
||||
|
||||
private async Task SetCulture(SelectedItem item)
|
||||
{
|
||||
if (OperatingSystem.IsBrowser())
|
||||
{
|
||||
var cultureName = item.Value;
|
||||
if (cultureName != CultureInfo.CurrentCulture.Name)
|
||||
{
|
||||
await JSRuntime.SetCulture(cultureName);
|
||||
var culture = new CultureInfo(cultureName);
|
||||
CultureInfo.CurrentCulture = culture;
|
||||
CultureInfo.CurrentUICulture = culture;
|
||||
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用 api 方式 适用于 Server-Side 模式
|
||||
if (SelectedCulture != item.Value)
|
||||
{
|
||||
var culture = item.Value;
|
||||
var uri = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
|
||||
var query = $"?culture={Uri.EscapeDataString(culture)}&redirectUri={Uri.EscapeDataString(uri)}";
|
||||
|
||||
// use a path that matches your culture redirect controller from the previous steps
|
||||
NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetDisplayName(CultureInfo culture)
|
||||
{
|
||||
string? ret;
|
||||
if (OperatingSystem.IsBrowser())
|
||||
{
|
||||
ret = culture.Name switch
|
||||
{
|
||||
"zh-CN" => "中文(中国)",
|
||||
"en-US" => "English (United States)",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = culture.NativeName;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
.culture-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.culture-selector span {
|
||||
margin: 0;
|
||||
color: var(--bs-navbar-color);
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.culture-selector ::deep .select {
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
.culture-selector ::deep .dropdown-menu {
|
||||
--bs-dropdown-link-active-bg: #7532f9;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
@inherits FilterBase
|
||||
|
||||
<Select Items="@Items" @bind-Value="@Value" OnSelectedItemChanged="_ => OnFilterValueChanged()"></Select>
|
||||
|
||||
@code {
|
||||
private int Value = 10;
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
if (TableFilter != null) TableFilter.ShowMoreButton = false;
|
||||
|
||||
Items = new SelectedItem[]
|
||||
{
|
||||
new SelectedItem { Value = "10", Text = "大于 10" },
|
||||
new SelectedItem { Value = "50", Text = "大于 50" },
|
||||
new SelectedItem { Value = "100", Text = "大于 100" }
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置过滤条件方法
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
Value = 10;
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成过滤条件方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override FilterKeyValueAction GetFilterConditions()
|
||||
{
|
||||
var filter = new FilterKeyValueAction() { Filters = new() };
|
||||
filter.Filters.Add(new FilterKeyValueAction()
|
||||
{
|
||||
FieldKey = FieldKey,
|
||||
FieldValue = Value,
|
||||
FilterAction = FilterAction.GreaterThan
|
||||
});
|
||||
return filter;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-sm-6">
|
||||
<Select TValue="string" Items="@Items3" OnSelectedItemChanged="@OnCascadeBindSelectClick" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<Select TValue="string" Items="@Items2" />
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,50 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class CustomerSelectDialog
|
||||
{
|
||||
private IEnumerable<SelectedItem>? Items2;
|
||||
private readonly IEnumerable<SelectedItem> Items3 = new SelectedItem[]
|
||||
{
|
||||
new SelectedItem ("", "请选择 ..."),
|
||||
new SelectedItem ("Beijing", "北京"),
|
||||
new SelectedItem ("Shanghai", "上海")
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 级联绑定菜单
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private async Task OnCascadeBindSelectClick(SelectedItem item)
|
||||
{
|
||||
// 模拟异步通讯获取数据
|
||||
await Task.Delay(100);
|
||||
if (item.Value == "Beijing")
|
||||
{
|
||||
Items2 = new SelectedItem[]
|
||||
{
|
||||
new SelectedItem("1","朝阳区"),
|
||||
new SelectedItem("2","海淀区"),
|
||||
};
|
||||
}
|
||||
else if (item.Value == "Shanghai")
|
||||
{
|
||||
Items2 = new SelectedItem[]
|
||||
{
|
||||
new SelectedItem("1","静安区"),
|
||||
new SelectedItem("2","黄浦区"),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
Items2 = Enumerable.Empty<SelectedItem>();
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
@inject ToastService Toast
|
||||
|
||||
<p>同时通过传递数据主键获取数据后再显示的例子组件</p>
|
||||
|
||||
<p>传递的参数主键为:@DataPrimaryId</p>
|
||||
|
||||
<p>通过传递参数获取的数据为:</p>
|
||||
|
||||
@if (Model != null)
|
||||
{
|
||||
<ValidateForm Model="@Model" OnValidSubmit="@OnValidSubmit">
|
||||
<EditorForm TModel="Foo">
|
||||
<FieldItems>
|
||||
<EditorItem @bind-Field="@context.Id" Editable="false"></EditorItem>
|
||||
<EditorItem @bind-Field="@context.Hobby" Items="@Hobbys"></EditorItem>
|
||||
</FieldItems>
|
||||
</EditorForm>
|
||||
<div class="form-footer mt-3">
|
||||
<DialogCloseButton></DialogCloseButton>
|
||||
<Button Color="Color.Primary" ButtonType="ButtonType.Submit" Icon="fa-solid fa-floppy-disk" Text="保存"></Button>
|
||||
</div>
|
||||
</ValidateForm>
|
||||
}
|
||||
|
||||
@code {
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<Foo>? Localizer { get; set; }
|
||||
|
||||
[CascadingParameter(Name = "BodyContext")]
|
||||
private object? DataPrimaryId { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
[NotNull]
|
||||
private Modal? Dialog { get; set; }
|
||||
|
||||
private Foo? Model { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private List<Foo>? Items { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private IEnumerable<SelectedItem>? Hobbys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
Items = Foo.GenerateFoo(Localizer);
|
||||
Hobbys = Foo.GenerateHobbies(Localizer);
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
if (DataPrimaryId is int primaryId)
|
||||
{
|
||||
Model = Items.FirstOrDefault(i => i.Id == primaryId);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnValidSubmit(EditContext model)
|
||||
{
|
||||
// do someting like save model into db
|
||||
|
||||
// 关闭弹窗
|
||||
// close Dialog
|
||||
await Dialog.Close();
|
||||
|
||||
// 显示 Toast 提示弹窗
|
||||
await Toast.Show(new ToastOption() { Title = "保存数据", Content = "保存成功,4 秒后自动关闭" });
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
@inherits IdComponentBase
|
||||
|
||||
<article class="demo-block">
|
||||
<AnchorLink Text="@Title" Id="@Name" TooltipText="@TooltipText" />
|
||||
|
||||
<p>@(new MarkupString(Introduction))</p>
|
||||
|
||||
<h5>@Localizer["SubTitle"]</h5>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ChildContent
|
||||
</div>
|
||||
@if (ShowCode)
|
||||
{
|
||||
<div class="card-footer">
|
||||
<div class="card-footer-code collapse" id="@Id">
|
||||
<LazyLoad OnLoadConditionCheckAsync="OnLoadConditionCheckAsync">
|
||||
<Pre BlockName="@Name" ShowToolbar="true" CodeFile="@CodeFile"></Pre>
|
||||
</LazyLoad>
|
||||
</div>
|
||||
<a class="card-footer-control collapsed" href="#@Id" data-bs-toggle="collapse" role="button" aria-label="show code" @onclick="ShowPreCode">
|
||||
<i class="fa-solid fa-caret-up"></i>
|
||||
<span class="card-text"></span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</article>
|
@ -0,0 +1,75 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class DemoBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 组件 Title 属性
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件说明信息
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Introduction { get; set; } = "未设置";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件内容
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 是否显示代码块 默认 true 显示
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowCode { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 Tooltip 提示信息文本
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? TooltipText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 友好链接锚点名称
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[CascadingParameter(Name = "RazorFileName")]
|
||||
private string? CodeFile { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<DemoBlock>? Localizer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
Title ??= Localizer[nameof(Title)];
|
||||
TooltipText ??= Localizer[nameof(TooltipText)];
|
||||
}
|
||||
|
||||
private bool _showPreCode;
|
||||
|
||||
private void ShowPreCode()
|
||||
{
|
||||
_showPreCode = true;
|
||||
}
|
||||
|
||||
private Task<bool> OnLoadConditionCheckAsync() => Task.FromResult(_showPreCode);
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
.card {
|
||||
transition: all .3s linear;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
|
||||
}
|
||||
|
||||
.card:hover .card-footer-control i {
|
||||
margin-left: -1.5rem;
|
||||
margin-left: -72px;
|
||||
}
|
||||
|
||||
.card:hover .card-footer-control .card-text {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.card:hover .card-footer-control .card-text:before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
.card-footer {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.card-footer-code {
|
||||
margin: -.5rem -1rem 0 -1rem;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
|
||||
.card-footer-code.show + a {
|
||||
margin-top: .5rem;
|
||||
}
|
||||
|
||||
.card-footer-code .loading {
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
.card-footer-code ::deep code {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card-footer-code ::deep .pre-code {
|
||||
margin: .5rem;
|
||||
}
|
||||
|
||||
.card-footer-control {
|
||||
text-align: center;
|
||||
color: #d3dce6;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-footer-control:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.card-footer-control i {
|
||||
transition: .3s linear;
|
||||
}
|
||||
|
||||
.card-footer-control.collapsed i {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.card-footer-control .card-text {
|
||||
margin-left: 1.5rem;
|
||||
position: absolute;
|
||||
transition: all .3s linear;
|
||||
}
|
||||
|
||||
.card-footer-control .card-text:before {
|
||||
content: "Hide Code";
|
||||
opacity: 0;
|
||||
transition: opacity .3s linear;
|
||||
}
|
||||
|
||||
.card-footer-control.collapsed .card-text:before {
|
||||
content: "Show Code";
|
||||
}
|
||||
|
||||
.demo-block > ::deep .anchor-link {
|
||||
font-weight: var(--bb-font-weight);
|
||||
color: var(--bb-title-color);
|
||||
font-size: var(--bb-sub-font-size);
|
||||
margin-top: 1rem;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
::deep .table-cell .progress {
|
||||
height: 6px;
|
||||
margin-top: 9px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
::deep .chart .btn i + span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::deep .ul-demo {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
::deep .ul-demo li:not(:last-child) {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
::deep .chart {
|
||||
max-width: 740px;
|
||||
}
|
||||
|
||||
::deep .chart .btn i + span {
|
||||
display: inline;
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<div>@Parameter</div>
|
||||
|
||||
@code {
|
||||
[CascadingParameter(Name = "BodyContext")]
|
||||
private object? Parameter { get; set; }
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<p>@((MarkupString)Localizer["Info"].Value)</p>
|
||||
|
||||
<Button OnClick="OnClick" Text="@Localizer["ButtonText"]" />
|
@ -0,0 +1,29 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// DemoTabItem 组件
|
||||
/// </summary>
|
||||
public partial class DemoTabItem
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<DemoTabItem>? Localizer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnSetTitle 回调方法
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<string, Task>? OnSetTitle { get; set; }
|
||||
|
||||
private async Task OnClick()
|
||||
{
|
||||
if (OnSetTitle != null)
|
||||
{
|
||||
await OnSetTitle(DateTime.Now.ToString("mm:ss"));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<p>@((MarkupString)Localizer["Info"].Value)</p>
|
||||
|
||||
<Button OnClick="OnClick" Text="@Localizer["ButtonText"]" />
|
@ -0,0 +1,24 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// DemoTabItem 组件
|
||||
/// </summary>
|
||||
public partial class DemoTabItemSetText
|
||||
{
|
||||
[CascadingParameter]
|
||||
[NotNull]
|
||||
private TabItem? TabItem { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<DemoTabItem>? Localizer { get; set; }
|
||||
|
||||
private void OnClick()
|
||||
{
|
||||
TabItem.SetHeader(DateTime.Now.ToString("mm:ss"));
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
@using BootstrapBlazor.Server.Components.Samples.Table
|
||||
|
||||
<div class="row form-inline g-3">
|
||||
<div class="col-12 col-sm-6">
|
||||
<BootstrapInput @bind-Value="Model.Name" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<BootstrapInput @bind-Value="Model.Address" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<Select @bind-Value="Model.Education" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<Display Value="@EducationDesc" ShowLabel="true" DisplayText="@Localizer["TablesEditTemplateDisplayLabel"]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public Foo? Model { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<TablesEdit>? Localizer { get; set; }
|
||||
|
||||
private string? EducationDesc => Model.Education == EnumEducation.Primary ? Localizer["TablesEditTemplateDisplayDetail1"] : Localizer["TablesEditTemplateDisplayDetail2"];
|
||||
}
|
@ -0,0 +1 @@
|
||||
标题栏下拉框选中值:@Value
|
@ -0,0 +1,29 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class DialogBodyFoo
|
||||
{
|
||||
private string? Value { get; set; }
|
||||
|
||||
private List<SelectedItem> Items { get; } = new(new[]
|
||||
{
|
||||
new SelectedItem("beijing", "北京"),
|
||||
new SelectedItem("shanghai", "上海")
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Task UpdateAsync(string val)
|
||||
{
|
||||
Value = Items.First(i => i.Value == val).Text;
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<h3>无限弹窗示例 @Title</h3>
|
||||
|
||||
<Tab>
|
||||
<TabItem Text="用户管理">
|
||||
<div>我是用户管理</div>
|
||||
<Button Text="弹窗" OnClick="@OnClickButton" />
|
||||
</TabItem>
|
||||
<TabItem Text="菜单管理">
|
||||
<div>我是菜单管理</div>
|
||||
<Button Text="弹窗" OnClick="@OnClickButton" />
|
||||
</TabItem>
|
||||
<TabItem Text="角色管理">
|
||||
<div>我是角色管理</div>
|
||||
<Button Text="弹窗" OnClick="@OnClickButton" />
|
||||
</TabItem>
|
||||
</Tab>
|
@ -0,0 +1,26 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class DialogDemo
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private DialogService? DialogService { get; set; }
|
||||
|
||||
private string Title { get; } = DateTime.Now.ToString();
|
||||
|
||||
private Task OnClickButton() => DialogService.Show(new DialogOption()
|
||||
{
|
||||
Title = "Pop-up",
|
||||
IsDraggable = true,
|
||||
IsKeyboard = true,
|
||||
IsBackdrop = true,
|
||||
Component = BootstrapDynamicComponent.CreateComponent<DialogDemo>()
|
||||
});
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<h5 class="modal-title flex-fill">自定义 Header</h5>
|
||||
<div class="me-2">
|
||||
<Select TValue="string" Items="Items" Value="Value" OnSelectedItemChanged="OnSelectedItemChanged" style="width: 120px;" />
|
||||
</div>
|
@ -0,0 +1,49 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class DialogHeaderFoo
|
||||
{
|
||||
[NotNull]
|
||||
private IEnumerable<SelectedItem>? Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<string, Task>? OnValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
Items = new[]
|
||||
{
|
||||
new SelectedItem("beijing", "北京"),
|
||||
new SelectedItem("shanghai", "上海")
|
||||
};
|
||||
}
|
||||
|
||||
private async Task OnSelectedItemChanged(SelectedItem item)
|
||||
{
|
||||
Value = item.Value;
|
||||
if (OnValueChanged != null)
|
||||
{
|
||||
await OnValueChanged(Value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<div class="row form-inline g-3">
|
||||
<div class="col-12 col-sm-6">
|
||||
<BootstrapInput @bind-Value="Value.Name" ShowLabel="true" DisplayText="姓名" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<BootstrapInput @bind-Value="Value.Count" ShowLabel="true" DisplayText="数量" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public Foo? Value { get; set; }
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p>Current count: @currentCount</p>
|
||||
|
||||
<Button class="btn btn-primary" OnClick="IncrementCount">Click me</Button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
throw new Exception("Custom Exception");
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
@inject IStringLocalizer<EventTable> Localizer
|
||||
|
||||
<div class="table-attr">
|
||||
<h4>@Localizer["Title"]</h4>
|
||||
|
||||
<Table TItem="EventItem" Items="Items">
|
||||
<TableColumns>
|
||||
<TableColumn @bind-Field="@context.Name" />
|
||||
<TableColumn @bind-Field="@context.Description" TextWrap="true" />
|
||||
<TableColumn @bind-Field="@context.Type" />
|
||||
</TableColumns>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public IEnumerable<EventItem>? Items { get; set; }
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
@inject WeatherForecastService ForecastService
|
||||
|
||||
<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 = new WeatherForecast[0];
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<div class="row form-inline g-3">
|
||||
<div class="col-12 col-sm-6">
|
||||
<BootstrapInput @bind-Value="Value.Name" ShowLabel="true" DisplayText="姓名" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<DateTimeRange @bind-Value="Value.SearchDate" ShowLabel="true" DisplayText="时间" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<Select @bind-Value="Value.Education" ShowLabel="true" DisplayText="学历" PlaceHolder="全部" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<Select @bind-Value="Value.Count" ShowLabel="true" DisplayText="数量" Items="CountItems" />
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,35 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class FooSearch
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public FooSearchModel? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<FooSearchModel> ValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<SelectedItem> CountItems { get; } = new List<SelectedItem>()
|
||||
{
|
||||
new SelectedItem("", "全部"),
|
||||
new SelectedItem("1", "小于 30"),
|
||||
new SelectedItem("2", "大于等于 30 小于 70"),
|
||||
new SelectedItem("3", "大于等于 70 小于 100")
|
||||
};
|
||||
}
|
@ -0,0 +1 @@
|
||||
<RadioList IsButton="true" @bind-Value="FormRowType" Items="Items" AdditionalAttributes="AdditionalAttributes" />
|
@ -0,0 +1,61 @@
|
||||
// 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 BootstrapBlazor.Server.Components.Samples;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// 内部组件
|
||||
/// </summary>
|
||||
public partial class FormInlineSwitch
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 用户自定义属性
|
||||
/// </summary>
|
||||
[Parameter(CaptureUnmatchedValues = true)]
|
||||
public IDictionary<string, object>? AdditionalAttributes { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<Rows>? LocalizerRows { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RowType Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<RowType> ValueChanged { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private IEnumerable<SelectedItem>? Items { get; set; }
|
||||
|
||||
private RowType FormRowType
|
||||
{
|
||||
get => Value; set
|
||||
{
|
||||
if (Value != value)
|
||||
{
|
||||
Value = value;
|
||||
if (ValueChanged.HasDelegate)
|
||||
{
|
||||
ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Items = Enum.GetNames<RowType>().Select(i => new SelectedItem(i, LocalizerRows[i]));
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<div class="d-none d-xl-flex flex-xl-fill justify-content-xl-end px-3">
|
||||
<Search PlaceHolder="@Localizer["Search"]" IsSelectAllTextOnEnter="true" IsSelectAllTextOnFocus="true" IsLikeMatch="true" Items="@ComponentItems" SearchButtonText="" OnSearch="OnSearch" OnSelectedItemChanged="OnSelectedItemChanged" SearchButtonColor="Color.None" class="btn-search" />
|
||||
</div>
|
@ -0,0 +1,57 @@
|
||||
// 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.Extensions.Options;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Pre 组件
|
||||
/// </summary>
|
||||
public partial class GlobalSearch
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<GlobalSearch>? Localizer { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IOptionsMonitor<WebsiteOptions>? WebsiteOption { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private NavigationManager? NavigationManager { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private MenuService? MenuService { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private List<string>? ComponentItems { get; set; }
|
||||
|
||||
private IEnumerable<MenuItem> Menus => MenuService.GetMenus().SelectMany(i => i.Items).Where(i => !string.IsNullOrEmpty(i.Url));
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
ComponentItems = Menus.Select(i => i.Text!).ToList();
|
||||
}
|
||||
|
||||
private Task OnSearch(string searchText)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchText))
|
||||
{
|
||||
var item = Menus.FirstOrDefault(i => i.Text!.Contains(searchText, StringComparison.OrdinalIgnoreCase));
|
||||
if (item != null && !string.IsNullOrEmpty(item.Url))
|
||||
{
|
||||
NavigationManager.NavigateTo(item.Url);
|
||||
}
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task OnSelectedItemChanged(string searchText) => OnSearch(searchText);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
@inherits WebSiteModuleComponentBase
|
||||
@attribute [JSModuleAutoLoader("Components/Header.razor.js")]
|
||||
|
||||
<header class="navbar-header navbar navbar-expand navbar-dark flex-column flex-md-row px-3">
|
||||
<div class="header-img navbar-brand">
|
||||
<BBLogo />
|
||||
<span>Bootstrap Blazor</span>
|
||||
</div>
|
||||
<div class="navbar-nav-scroll">
|
||||
<ul class="navbar-nav bd-navbar-nav flex-row">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index">@HomeText</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="introduction">@IntroductionText</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="components">@ComponentsText</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="practice">实战</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<GlobalSearch />
|
||||
<CultureChooser class="flex-md-fill flex-xl-grow-0 justify-content-md-end" />
|
||||
<ul class="navbar-nav ms-3 d-none d-lg-flex">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://github.com/ArgoZhang/BootstrapBlazor" target="_blank">
|
||||
<img alt="git" src="./images/git.svg" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="@WebsiteOption.CurrentValue.BootstrapBlazorLink" target="_blank">
|
||||
<img alt="gitee" src="./images/gitee.svg" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<FullScreenButton class="nav-link p-2" TooltipText="点击切换全屏模式" />
|
||||
</li>
|
||||
</ul>
|
||||
<a class="btn btn-bd-download d-none d-lg-inline-block mb-3 mb-md-0 ms-md-3" target="_blank" href="@DownloadUrl">@DownloadText</a>
|
||||
</header>
|
||||
|
@ -0,0 +1,48 @@
|
||||
// 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.Extensions.Options;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Header 组件
|
||||
/// </summary>
|
||||
public partial class Header
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IOptionsMonitor<WebsiteOptions>? WebsiteOption { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<Header>? Localizer { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private string? HomeText { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private string? IntroductionText { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private string? ComponentsText { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private string? DownloadText { get; set; }
|
||||
|
||||
private string DownloadUrl => $"{WebsiteOption.CurrentValue.BootstrapBlazorLink}/repository/archive/main.zip";
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
DownloadText ??= Localizer[nameof(DownloadText)];
|
||||
HomeText ??= Localizer[nameof(HomeText)];
|
||||
IntroductionText ??= Localizer[nameof(IntroductionText)];
|
||||
ComponentsText ??= Localizer[nameof(ComponentsText)];
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
header {
|
||||
--bb-violet-rgb: 112.520718,44.062154,249.437846;
|
||||
background-color: transparent;
|
||||
background-image: linear-gradient(to bottom, rgba(var(--bb-violet-rgb), 1), rgba(var(--bb-violet-rgb), 0.95));
|
||||
box-shadow: 0 0.5rem 1rem rgba(0,0,0,.05), inset 0 -1px 0 rgba(0,0,0,.1);
|
||||
font-size: 1rem;
|
||||
transition: transform .3s ease;
|
||||
}
|
||||
|
||||
.header-img {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
::deep .btn-search .btn {
|
||||
--bs-btn-bg: #8759ff;
|
||||
--bs-btn-color: #fff;
|
||||
--bs-btn-hover-bg: #7d53eb;
|
||||
--bs-btn-hover-color: var(--bs-btn-color);
|
||||
--bs-btn-hover-border-color: var(--bs-btn-hover-bg);
|
||||
--bs-btn-active-bg: var(--bs-btn-hover-bg);
|
||||
--bs-btn-active-color: var(--bs-btn-hover-color);
|
||||
--bs-btn-active-border-color: var(--bs-btn-hover-border-color);
|
||||
}
|
||||
|
||||
::deep .btn-search .form-control {
|
||||
--bs-border-color: #fff;
|
||||
--bb-border-focus-color: var(--bs-border-color);
|
||||
--bb-border-hover-color: var(--bs-border-color);
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
::deep .btn-fs {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.btn-bd-download {
|
||||
font-weight: 600;
|
||||
color: #ffe484;
|
||||
border-color: #ffe484;
|
||||
}
|
||||
|
||||
.btn-bd-download:active,
|
||||
.btn-bd-download:hover {
|
||||
color: #2a2730;
|
||||
background-color: #ffe484;
|
||||
border-color: #ffe484;
|
||||
}
|
||||
|
||||
.nav-link img {
|
||||
height: 24px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.navbar-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1050;
|
||||
height: var(--bs-header-height);
|
||||
}
|
||||
|
||||
.modal-open .navbar-header {
|
||||
z-index: 1040;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import EventHandler from "../../_content/BootstrapBlazor/modules/event-handler.js?v=$version"
|
||||
|
||||
export function init() {
|
||||
const scrollTop = () => (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop
|
||||
let prevScrollTop = 0;
|
||||
EventHandler.on(document, 'scroll', () => {
|
||||
const items = document.querySelectorAll('.navbar-header, .coms-search')
|
||||
const currentScrollTop = scrollTop()
|
||||
if (currentScrollTop > prevScrollTop) {
|
||||
items.forEach(item => item.classList.add('hide'))
|
||||
} else {
|
||||
items.forEach(item => item.classList.remove('hide'))
|
||||
}
|
||||
prevScrollTop = currentScrollTop
|
||||
})
|
||||
}
|
||||
|
||||
export function dispose() {
|
||||
EventHandler.off(document, 'scroll')
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
@using Microsoft.Extensions.DependencyInjection
|
||||
@inject PackageVersionService VersionManager
|
||||
@inject IStringLocalizer<InstallContent> Localizer
|
||||
|
||||
<h3>@Title</h3>
|
||||
|
||||
<h4>@Localizer["Heading"]</h4>
|
||||
|
||||
<p class="mt-3">@Localizer["P1"]</p>
|
||||
<ul>
|
||||
<li><code>visual studio 2019</code> @Localizer["P2"] <code>visual studio 2022</code></li>
|
||||
<li><code>net5</code> @Localizer["P3"] <code>net6</code></li>
|
||||
</ul>
|
||||
<div><code>BootstrapBlazor</code> @Localizer["P4"] <code>net5/net6</code></div>
|
||||
|
||||
<h4>@Localizer["P5"]</h4>
|
||||
|
||||
<p>@Localizer["P6"] <a href="template">[@Localizer["P7"]]</a> @Localizer["P8"]</p>
|
||||
|
||||
<h4>@Localizer["P9"]</h4>
|
||||
|
||||
<h5 class="mb-3">@Localizer["P10"]</h5>
|
||||
<div class="code-label mb-2">1. @Localizer["P11"]</div>
|
||||
<div class="code-label mb-2">2. @Localizer["P12"]</div>
|
||||
<div class="code-label mb-2">3. @Localizer["P13"] <b>Blazor App</b> @Localizer["P14"] <b>@Localizer["P15"]</b>, @Localizer["P16"] <b>Create</b></div>
|
||||
<img alt="install" src="./images/create-new-application.png" style="border-radius: 6px;" class="d-none d-sm-block mb-2" />
|
||||
@ChooseTemplate
|
||||
<h5 class="mb-3">@Localizer["P17"]</h5>
|
||||
<div class="code-label mb-2">1. @Localizer["P18"] <b>nuget.org</b> @Localizer["P19"] <code>BootstrapBlazor</code></div>
|
||||
<div class="mb-2">@Localizer["P20"] <b>Manage Nuget Packages</b></div>
|
||||
<Pre @key="@Version" class="no-highlight mb-2">dotnet add package BootstrapBlazor --version @Version</Pre>
|
||||
<img alt="install" src="./images/manage-nuget-packages-for-server-app.png" style="border-radius: 6px;" class="d-none d-sm-block mb-2" />
|
||||
<div class="code-label mt-3 mb-2">2. @Localizer["P21"]</div>
|
||||
<img alt="install" src="./images/nuget_install.png" style="width: 1000px; border-radius: 6px;" class="d-none d-sm-block mb-2" />
|
||||
<div class="code-label mt-3 mb-2">3. @Localizer["P22"]</div>
|
||||
<div class="mb-2">@Localizer["P23"]</div>
|
||||
@SheetTemplate
|
||||
<Tips>
|
||||
<div>@((MarkupString)Localizer["Tips2"].Value)</div>
|
||||
</Tips>
|
||||
<Pre class="mb-2"><head>
|
||||
...
|
||||
<b>
|
||||
<!-- @Localizer["P24"] !-->
|
||||
<link href="_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css" rel="stylesheet">
|
||||
</b>
|
||||
...
|
||||
<link href="css/site.css" rel="stylesheet">
|
||||
<link href="BlazorApp1.styles.css" rel="stylesheet">
|
||||
</head></Pre>
|
||||
<div class="code-label my-2">4. @Localizer["P25"]</div>
|
||||
@ScriptsTemplate
|
||||
<Pre class="mb-2"><body>
|
||||
...
|
||||
<!-- @Localizer["P26"] !-->
|
||||
<b><script src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js"></script></b>
|
||||
...
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
</body></Pre>
|
||||
<div class="code-label mb-2">5. @Localizer["P27"]</div>
|
||||
@ServicesTemplate
|
||||
|
||||
<div class="code-label mb-2">6. @Localizer["P28"]</div>
|
||||
<div class="mb-2">@Localizer["P29"] <code>~/_Imports.razor</code> @Localizer["P30"] <code>Razor</code> @Localizer["P31"]</div>
|
||||
<Pre class="mb-2"><b>@@using BootstrapBlazor.Components</b></Pre>
|
||||
|
||||
<div class="code-label mb-2">7. @Localizer["P32"] <code>BootstrapBlazorRoot</code> @Localizer["P33"] <code>~/App.razor</code> @Localizer["P34"]</div>
|
||||
<Pre class="mb-2"><BootstrapBlazorRoot>
|
||||
<Router AppAssembly="@@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<PageTitle>Title</PageTitle>
|
||||
<RouteView RouteData="@@routeData" DefaultLayout="@@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@@routeData" Selector="h1" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@@typeof(MainLayout)">
|
||||
<p> @Localizer["P35"] ...</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
</BootstrapBlazorRoot></Pre>
|
||||
|
||||
<h5 class="mb-3">@Localizer["P36"]</h5>
|
||||
<div class="mb-2">@Localizer["P37"] <code>BootstrapBlazor</code> @Localizer["P38"]:</div>
|
||||
<div class="code-label mb-2">1. @Localizer["P39"] <code>Button</code> @Localizer["P40"]</div>
|
||||
<Pre class="mb-2"><Button Color="Color.Primary" Icon="fa-solid fa-font-awesome" Text="@Localizer["P41"]" /></Pre>
|
||||
<div class="code-label mb-2">2. @Localizer["P42"] <b>Visual studio 2022</b> @Localizer["P43"] <kbd>F5</kbd> @Localizer["P44"]</div>
|
||||
<img alt="install" src="./images/preview.png" style="border-radius: 6px;" class="d-none d-sm-block" />
|
@ -0,0 +1,67 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class InstallContent
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 版本号字符串
|
||||
/// </summary>
|
||||
private string Version { get; set; } = "latest";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Title { get; set; } = "服务器端 Blazor 安装教程";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string HostFile { get; set; } = "Pages/_Host.cshtml";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChooseTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? SheetTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ScriptsTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ServicesTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitializedAsync 方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Version = await VersionManager.GetVersionAsync();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<div class="table-attr">
|
||||
<h4>@Title</h4>
|
||||
|
||||
<Table TItem="MethodItem" Items="Items">
|
||||
<TableColumns>
|
||||
<TableColumn @bind-Field="@context.Name" />
|
||||
<TableColumn @bind-Field="@context.Description" TextWrap="true" />
|
||||
<TableColumn @bind-Field="@context.Parameters" />
|
||||
<TableColumn @bind-Field="@context.ReturnValue" />
|
||||
</TableColumns>
|
||||
</Table>
|
||||
</div>
|
||||
|
@ -0,0 +1,38 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class MethodTable
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<MethodTable>? Localizer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter] public IEnumerable<MethodItem>? Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
Title ??= Localizer[nameof(Title)];
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
@inject IStringLocalizer<PackageTips> Localizer
|
||||
|
||||
<div class="info mb-2">@((MarkupString)Localizer["Tips", Name].Value)</div>
|
||||
|
||||
<div class="code-label mb-2">.NET CLI</div>
|
||||
<Pre class="no-highlight mb-2">dotnet add package @Name</Pre>
|
||||
|
||||
<div class="code-label mb-2">PackageReference</div>
|
||||
<Pre @key="@Version" class="no-highlight mb-2"><PackageReference Include="@Name" Version="@Version" /></Pre>
|
||||
|
||||
<div class="code-label mb-2">Package Manager</div>
|
||||
<Pre class="no-highlight">Install-Package @Name</Pre>
|
||||
|
||||
@code {
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private PackageVersionService? VersionManager { get; set; }
|
||||
|
||||
private string Version { get; set; } = "fetching";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 Package 名称
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
[EditorRequired]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Version = await VersionManager.GetVersionAsync(Name.ToLower());
|
||||
}
|
||||
}
|
21
src/BootstrapBlazor.Server/Components/Components/Pre.razor
Normal file
21
src/BootstrapBlazor.Server/Components/Components/Pre.razor
Normal file
@ -0,0 +1,21 @@
|
||||
@inherits WebSiteModuleComponentBase
|
||||
@attribute [JSModuleAutoLoader("Components/Pre.razor.js")]
|
||||
|
||||
<div @attributes="@AdditionalAttributes" class="@ClassString" id="@Id" data-bb-title="@CopiedText">
|
||||
<p class="loading">@LoadingText</p>
|
||||
@if (Loaded)
|
||||
{
|
||||
<pre><code>@ChildContent</code></pre>
|
||||
@if (CanCopy)
|
||||
{
|
||||
@if (ShowToolbar)
|
||||
{
|
||||
<div class="btn-group">
|
||||
<Button TooltipPlacement="Placement.Top" TooltipText="@PlusTooltipTitle" TooltipTrigger="hover" Icon="fa-solid fa-plus" class="btn-plus"></Button>
|
||||
<Button TooltipPlacement="Placement.Top" TooltipText="@MinusTooltipTitle" TooltipTrigger="hover" Icon="fa-solid fa-minus" class="btn-minus"></Button>
|
||||
</div>
|
||||
}
|
||||
<Button TooltipPlacement="Placement.Top" TooltipText="@TooltipTitle" TooltipTrigger="hover" class="btn-copy">Copy</Button>
|
||||
}
|
||||
}
|
||||
</div>
|
191
src/BootstrapBlazor.Server/Components/Components/Pre.razor.cs
Normal file
191
src/BootstrapBlazor.Server/Components/Components/Pre.razor.cs
Normal file
@ -0,0 +1,191 @@
|
||||
// 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 System.Text.RegularExpressions;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Pre 组件
|
||||
/// </summary>
|
||||
public partial class Pre
|
||||
{
|
||||
private bool Loaded { get; set; }
|
||||
|
||||
private bool CanCopy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得 样式集合
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string? ClassString => CssBuilder.Default("pre-code")
|
||||
.AddClass("loaded", Loaded)
|
||||
.AddClassFromAttributes(AdditionalAttributes)
|
||||
.Build();
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private CodeSnippetService? CodeSnippetService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 子组件 CodeFile 为空时生效
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 代码段的标题
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? BlockName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 示例代码片段 默认 null 未设置
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? CodeFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 是否显示工具按钮组
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowToolbar { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<Pre>? Localizer { get; set; }
|
||||
|
||||
private string? LoadingText { get; set; }
|
||||
|
||||
private string? TooltipTitle { get; set; }
|
||||
|
||||
private string? PlusTooltipTitle { get; set; }
|
||||
|
||||
private string? MinusTooltipTitle { get; set; }
|
||||
|
||||
private string? CopiedText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
LoadingText ??= Localizer[nameof(LoadingText)];
|
||||
TooltipTitle ??= Localizer[nameof(TooltipTitle)];
|
||||
PlusTooltipTitle ??= Localizer[nameof(PlusTooltipTitle)];
|
||||
MinusTooltipTitle ??= Localizer[nameof(MinusTooltipTitle)];
|
||||
CopiedText ??= Localizer[nameof(CopiedText)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (ChildContent == null)
|
||||
{
|
||||
await GetCodeAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Loaded = true;
|
||||
CanCopy = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnAfterRender 方法
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
if (Loaded)
|
||||
{
|
||||
await InvokeVoidAsync("highlight", Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, CopiedText);
|
||||
|
||||
private async Task GetCodeAsync()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(CodeFile))
|
||||
{
|
||||
var code = await CodeSnippetService.GetCodeAsync(CodeFile);
|
||||
if (!string.IsNullOrEmpty(code))
|
||||
{
|
||||
code = FindCodeSnippetByName(code);
|
||||
ChildContent = builder =>
|
||||
{
|
||||
builder.AddContent(0, code);
|
||||
};
|
||||
}
|
||||
CanCopy = !string.IsNullOrEmpty(code) && !code.StartsWith("Error: ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ChildContent = builder =>
|
||||
{
|
||||
builder.AddContent(0, "网站改版中 ... Refactoring website. Coming soon ...");
|
||||
};
|
||||
CanCopy = false;
|
||||
}
|
||||
Loaded = true;
|
||||
}
|
||||
|
||||
private string FindCodeSnippetByName(string code)
|
||||
{
|
||||
var content = code;
|
||||
if (!string.IsNullOrEmpty(BlockName))
|
||||
{
|
||||
var regex = new Regex($"<DemoBlock [\\s\\S]*? Name=\"{BlockName}\">([\\s\\S]*?)</DemoBlock>");
|
||||
var match = regex.Match(content);
|
||||
if (match.Success && match.Groups.Count == 2)
|
||||
{
|
||||
content = match.Groups[1].Value.Replace("\r\n", "\n").Replace("\n ", "\n").TrimStart('\n');
|
||||
}
|
||||
|
||||
// 移除 ignore 节点
|
||||
regex = IgnoreRegex();
|
||||
var matchCollection = regex.Matches(content);
|
||||
matchCollection.ToList().ForEach(m =>
|
||||
{
|
||||
content = content.Replace(m.Value, "").TrimStart('\n');
|
||||
});
|
||||
|
||||
// 移除 ConsoleLogger
|
||||
regex = ConsoleLoggerRegex();
|
||||
match = regex.Match(content);
|
||||
if (match.Success)
|
||||
{
|
||||
content = content.Replace(match.Value, "").TrimStart('\n');
|
||||
}
|
||||
|
||||
// 移除 Tips
|
||||
regex = TipsRegex();
|
||||
match = regex.Match(content);
|
||||
if (match.Success)
|
||||
{
|
||||
content = content.Replace(match.Value, "").TrimStart('\n');
|
||||
}
|
||||
}
|
||||
return content.TrimEnd('\n');
|
||||
}
|
||||
|
||||
[GeneratedRegex("<section ignore[ \\s\\S]*?>[\\s\\S]*?</section>")]
|
||||
private static partial Regex IgnoreRegex();
|
||||
|
||||
[GeneratedRegex("<ConsoleLogger [\\s\\S]* />")]
|
||||
private static partial Regex ConsoleLoggerRegex();
|
||||
|
||||
[GeneratedRegex("<Tips[\\s\\S]*>[\\s\\S]*?</Tips>")]
|
||||
private static partial Regex TipsRegex();
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
.pre-code {
|
||||
position: relative;
|
||||
border: 1px solid var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pre-code .loading {
|
||||
padding: .5rem 1rem;
|
||||
}
|
||||
|
||||
.pre-code.loaded > pre > code {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::deep .btn-primary {
|
||||
position: absolute;
|
||||
top: .65rem;
|
||||
right: 1.5rem;
|
||||
font-size: 65%;
|
||||
--bs-btn-color: var(--bs-primary);
|
||||
--bs-btn-bg: #fff;
|
||||
--bs-btn-padding-y: .25rem;
|
||||
--bs-btn-padding-x: .5rem;
|
||||
}
|
||||
|
||||
::deep .btn-group {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 3rem;
|
||||
}
|
||||
|
||||
::deep .btn-group .btn-primary {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
code {
|
||||
line-height: 1.8;
|
||||
font-size: 0.75rem;
|
||||
padding: 10px 65px 10px 16px;
|
||||
display: block;
|
||||
white-space: pre-wrap;
|
||||
-webkit-font-smoothing: auto;
|
||||
}
|
||||
|
||||
.no-highlight code {
|
||||
color: var(--bs-code-color);
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
import { copy, getDescribedElement, addLink, addScript, getHeight } from "../../_content/BootstrapBlazor/modules/utility.js?v=$version"
|
||||
import EventHandler from "../../_content/BootstrapBlazor/modules/event-handler.js?v=$version"
|
||||
|
||||
export async function init(id, title) {
|
||||
const el = document.getElementById(id);
|
||||
if (el === null) {
|
||||
return
|
||||
}
|
||||
|
||||
await addScript('./lib/highlight/highlight.min.js')
|
||||
await addScript('./lib/highlight/cshtml-razor.min.js')
|
||||
await addLink('./lib/highlight/vs.min.css')
|
||||
|
||||
const preElement = el.querySelector('pre')
|
||||
const code = el.querySelector('pre > code')
|
||||
|
||||
if (preElement) {
|
||||
EventHandler.on(el, 'click', '.btn-copy', e => {
|
||||
const text = code.textContent;
|
||||
copy(text)
|
||||
|
||||
const tooltip = getDescribedElement(e.delegateTarget)
|
||||
if (tooltip) {
|
||||
tooltip.querySelector('.tooltip-inner').innerHTML = title
|
||||
}
|
||||
})
|
||||
|
||||
EventHandler.on(el, 'click', '.btn-plus', e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation();
|
||||
|
||||
let preHeight = getHeight(preElement)
|
||||
const codeHeight = getHeight(code)
|
||||
if (preHeight < codeHeight) {
|
||||
preHeight = Math.min(codeHeight, preHeight + 100)
|
||||
}
|
||||
preElement.style.maxHeight = `${preHeight}px`
|
||||
})
|
||||
|
||||
EventHandler.on(el, 'click', '.btn-minus', e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation();
|
||||
|
||||
let preHeight = getHeight(preElement)
|
||||
if (preHeight > 260) {
|
||||
preHeight = Math.max(260, preHeight - 100)
|
||||
}
|
||||
preElement.style.maxHeight = `${preHeight}px`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export async function highlight(id) {
|
||||
const el = document.getElementById(id);
|
||||
|
||||
if (el) {
|
||||
const invoke = () => {
|
||||
hljs.highlightElement(el.querySelector('code'))
|
||||
el.querySelector('.loading').classList.add('d-none')
|
||||
el.classList.remove('loaded')
|
||||
}
|
||||
|
||||
const check = () => new Promise((resolve, reject) => {
|
||||
const handler = setInterval(() => {
|
||||
const done = window.hljs !== void 0;
|
||||
if (done) {
|
||||
clearInterval(handler)
|
||||
resolve()
|
||||
}
|
||||
}, 20)
|
||||
})
|
||||
|
||||
await check();
|
||||
invoke();
|
||||
}
|
||||
}
|
||||
|
||||
export function dispose(id) {
|
||||
const el = document.getElementById(id);
|
||||
|
||||
if (el === null) {
|
||||
return
|
||||
}
|
||||
|
||||
EventHandler.off(el, 'click', '.btn-copy')
|
||||
EventHandler.off(el, 'click', '.btn-plus')
|
||||
EventHandler.off(el, 'click', '.btn-minus')
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
@inject IOptionsMonitor<WebsiteOptions> WebsiteOption
|
||||
@inject IStringLocalizer<QQGroup> Localzier
|
||||
|
||||
<div>
|
||||
@Localzier["Group"]:BootstrapAdmin & Blazor
|
||||
<a class="mx-1" target="_blank" href="@WebsiteOption.CurrentValue.QQGroup1Link">
|
||||
<span class="text-success fa-brands fa-qq">
|
||||
<span class="ms-1"><b>795206915</b></span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="mx-1" target="_blank" href="@WebsiteOption.CurrentValue.QQGroup2Link">
|
||||
<span class="text-success fa-brands fa-qq">
|
||||
<span class="ms-1"><b>675147445</b></span>
|
||||
</span>
|
||||
</a>
|
||||
@Localzier["Welcome"]
|
||||
</div>
|
@ -0,0 +1,8 @@
|
||||
<ul class="ul-demo mb-3">
|
||||
<li>更改数值后,点击 <code>确认</code> 返回主页面并 <b>更新</b> 数值</li>
|
||||
<li>点击其余按钮时关闭弹窗 <b>不更新</b> 数值</li>
|
||||
</ul>
|
||||
|
||||
<div style="width: 220px;">
|
||||
<BootstrapInputNumber ShowButton="true" Step="1" Min="1" Max="10" @bind-Value="@Value"></BootstrapInputNumber>
|
||||
</div>
|
@ -0,0 +1,37 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class ResultDialogDemo : ComponentBase, IResultDialog
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Value { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<int> ValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public async Task OnClose(DialogResult result)
|
||||
{
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
if (ValueChanged.HasDelegate)
|
||||
{
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<Table TItem="Foo" ClickToSelect="true" IsMultipleSelect="true" @bind-SelectedRows="@SelectedRows" OnQueryAsync="@OnQueryAsync">
|
||||
<TableColumns>
|
||||
<TableColumn @bind-Field="@context.Id" />
|
||||
<TableColumn @bind-Field="@context.Name" />
|
||||
<TableColumn @bind-Field="@context.Email" />
|
||||
</TableColumns>
|
||||
</Table>
|
@ -0,0 +1,138 @@
|
||||
// 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 System.ComponentModel;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class ResultDialogDemo2 : ComponentBase, IResultDialog
|
||||
{
|
||||
private List<Foo> SelectedRows { get; set; } = new List<Foo>();
|
||||
|
||||
[NotNull]
|
||||
private List<Foo>? Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
|
||||
public IEnumerable<string>? Emails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<IEnumerable<string>> EmailsChanged { get; set; }
|
||||
|
||||
[CascadingParameter(Name = "BodyContext")]
|
||||
private object? BodyContext { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private MessageService? MessageService { get; set; }
|
||||
|
||||
private Task<QueryData<Foo>> OnQueryAsync(QueryPageOptions option)
|
||||
{
|
||||
// 模拟查询数据
|
||||
var context = BodyContext as FooContext;
|
||||
Items = GenerateItems(context?.Count ?? 10);
|
||||
var data = new QueryData<Foo>()
|
||||
{
|
||||
TotalCount = Items.Count,
|
||||
Items = Items
|
||||
};
|
||||
|
||||
// 处理选中行
|
||||
Emails = context?.Emails?.Split(";") ?? Array.Empty<string>();
|
||||
SelectedRows.AddRange(Items.Where(i => Emails.Any(mail => mail == i.Email)));
|
||||
return Task.FromResult(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> OnClosing(DialogResult result)
|
||||
{
|
||||
var ret = true;
|
||||
if (result == DialogResult.Yes && !SelectedRows.Any())
|
||||
{
|
||||
await MessageService.Show(new MessageOption()
|
||||
{
|
||||
Content = "请至少选择一位用户!"
|
||||
});
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public async Task OnClose(DialogResult result)
|
||||
{
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
if (EmailsChanged.HasDelegate)
|
||||
{
|
||||
Emails = SelectedRows.Where(r => !string.IsNullOrEmpty(r.Email)).Select(r => r.Email!).ToList();
|
||||
await EmailsChanged.InvokeAsync(Emails);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static List<Foo> GenerateItems(int startId) => new(Enumerable.Range(startId, 10).Select(i => new Foo()
|
||||
{
|
||||
Id = i,
|
||||
Name = $"张三 {i:d4}",
|
||||
Email = $"zhangsan{i:d4}@163.com"
|
||||
}));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class FooContext
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? Emails { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private class Foo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[DisplayName("员工ID")]
|
||||
public int? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[DisplayName("员工姓名")]
|
||||
public string? Name { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[DisplayName("员工邮箱")]
|
||||
public string? Email { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<h3>窗口加载后回调示例</h3>
|
||||
|
||||
<p>在实战应用中,有些脚本比如画图类,必须窗体显示后,由具体高度或者宽度后才能正确工作,此时需要先显示此窗体,然后再调用其方法,本示例中下面数字是通过窗体加载并且显示后,由回调方法触发后,延时 2秒 后显示当前时间</p>
|
||||
|
||||
<p>@_text</p>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public Action<Func<Task>>? ShownTodo { get; set; }
|
||||
|
||||
private string? _text;
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
base.OnAfterRender(firstRender);
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
// 首次加载时回调 ShowTodo 方法
|
||||
if (ShownTodo != null)
|
||||
{
|
||||
ShownTodo(DoJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DoJob()
|
||||
{
|
||||
_text = "回调成功,开始延时 2 秒";
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await Task.Delay(2000);
|
||||
_text = $"当前时间: {DateTime.Now}";
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
18
src/BootstrapBlazor.Server/Components/Components/State.razor
Normal file
18
src/BootstrapBlazor.Server/Components/Components/State.razor
Normal file
@ -0,0 +1,18 @@
|
||||
@if (IsNew)
|
||||
{
|
||||
<Badge Color="Color.Danger" IsPill="true">
|
||||
NEW
|
||||
</Badge>
|
||||
}
|
||||
@if (IsUpdate)
|
||||
{
|
||||
<Badge Color="Color.Success" IsPill="true">
|
||||
Upd
|
||||
</Badge>
|
||||
}
|
||||
@if (Count > 0)
|
||||
{
|
||||
<Badge Color="Color.Info" IsPill="true">
|
||||
@Count
|
||||
</Badge>
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed partial class State
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 是否为新组件 默认为 false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsNew { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 是否为更新功能 默认为 false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件数量
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Count { get; set; }
|
||||
}
|
@ -0,0 +1 @@
|
||||
<div>Why do I have this issue?</div>
|
@ -0,0 +1,18 @@
|
||||
@inherits WebSiteModuleComponentBase
|
||||
@attribute [JSModuleAutoLoader("Components/ThemeChooser.razor.js")]
|
||||
|
||||
<div id="@Id" class="theme">
|
||||
<PulseButton class="btn-fade btn-theme" Color="Color.None" ImageUrl="./images/m.svg" TooltipText="@Title" TooltipPlacement="Placement.Left" />
|
||||
<div class="theme-list">
|
||||
<div class="theme-header">
|
||||
<div class="flex-fill">@HeaderText</div>
|
||||
<button class="btn-close btn-close-white" type="button" aria-label="Close"></button>
|
||||
</div>
|
||||
@foreach (var item in Themes)
|
||||
{
|
||||
<div class="@GetThemeItemClass(item)" @onclick="@(e => OnClickTheme(item))">
|
||||
@item.Text
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,74 @@
|
||||
// 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.Extensions.Options;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class ThemeChooser
|
||||
{
|
||||
[NotNull]
|
||||
private IEnumerable<SelectedItem>? Themes { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private string? Title { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private string? HeaderText { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<ThemeChooser>? Localizer { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IOptionsMonitor<BootstrapBlazorOptions>? BootstrapOptions { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IOptionsMonitor<WebsiteOptions>? SiteOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
Title ??= Localizer[nameof(Title)];
|
||||
HeaderText ??= Localizer[nameof(HeaderText)];
|
||||
Themes = BootstrapOptions.CurrentValue.Themes.Select(kv => new SelectedItem(kv.Value, kv.Key));
|
||||
SiteOptions.CurrentValue.CurrentTheme = Themes.FirstOrDefault(i => i.Text == "Motronic")?.Value ?? "";
|
||||
}
|
||||
|
||||
private async Task OnClickTheme(SelectedItem item)
|
||||
{
|
||||
SiteOptions.CurrentValue.CurrentTheme = item.Value;
|
||||
|
||||
await InvokeVoidAsync("addScript", LinksCache[item.Value]);
|
||||
}
|
||||
|
||||
private string? GetThemeItemClass(SelectedItem item) => CssBuilder.Default("theme-item")
|
||||
.AddClass("active", SiteOptions.CurrentValue.CurrentTheme == item.Value)
|
||||
.Build();
|
||||
|
||||
private Dictionary<string, ICollection<string>> LinksCache { get; } = new(new KeyValuePair<string, ICollection<string>>[]
|
||||
{
|
||||
new("bootstrap.blazor.bundle.min.css", new List<string>()),
|
||||
new("motronic.min.css", new string[]
|
||||
{
|
||||
"./_content/BootstrapBlazor/css/motronic.min.css",
|
||||
"./css/motronic.css"
|
||||
}),
|
||||
new("ant", new List<string>()),
|
||||
new("layui", new List<string>()),
|
||||
new("devui", new string[]
|
||||
{
|
||||
"./css/devui.css"
|
||||
})
|
||||
});
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
.theme-list {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
bottom: 12rem;
|
||||
right: 1rem;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0 5px 24px 0 rgba(0, 0, 0, 0.2);
|
||||
border-radius: var(--bs-border-radius);
|
||||
width: 260px;
|
||||
box-shadow: 0 0 12px #211b50;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
transition: height .3s ease-in-out;
|
||||
}
|
||||
|
||||
.theme-list.is-open {
|
||||
height: 306px;
|
||||
}
|
||||
|
||||
.theme-header {
|
||||
padding: 0.75rem 1rem;
|
||||
background-color: #8759ff;
|
||||
color: #fff;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
display: flex;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
transition: opacity .3s linear;
|
||||
}
|
||||
|
||||
.btn-close:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.theme-item {
|
||||
cursor: pointer;
|
||||
border-radius: 100px;
|
||||
padding: 6px 15px;
|
||||
background-color: #f6f6f6;
|
||||
color: #005980;
|
||||
transition: background-color .3s linear;
|
||||
margin: 0 1rem 1rem 1rem;
|
||||
}
|
||||
|
||||
.theme-item:hover,
|
||||
.theme-item.active {
|
||||
background-color: #ab8aff;
|
||||
}
|
||||
|
||||
::deep .btn-theme {
|
||||
--bs-btn-bg: #034995;
|
||||
--bs-btn-hover-bg: #034995;
|
||||
--bs-btn-active-bg: #034995;
|
||||
right: 1rem;
|
||||
bottom: 9rem;
|
||||
}
|
||||
|
||||
::deep .btn-theme img {
|
||||
width: 20px;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
import { insertAfter } from "../../_content/BootstrapBlazor/modules/utility.js?v=$version"
|
||||
import Data from "../../_content/BootstrapBlazor/modules/data.js?v=$version"
|
||||
import EventHandler from "../../_content/BootstrapBlazor/modules/event-handler.js?v=$version"
|
||||
|
||||
export function init(id) {
|
||||
const el = document.getElementById(id)
|
||||
if (el === null) {
|
||||
return
|
||||
}
|
||||
const themeList = el.querySelector('.theme-list')
|
||||
|
||||
const chooser = { el, themeList }
|
||||
Data.set(id, chooser);
|
||||
|
||||
EventHandler.on(el, 'click', () => {
|
||||
themeList.classList.toggle('is-open')
|
||||
})
|
||||
}
|
||||
|
||||
export function addScript(args) {
|
||||
const links = document.querySelectorAll('link')
|
||||
if (links) {
|
||||
const link = [].slice.call(links).filter(function (item) {
|
||||
const href = item.getAttribute('href')
|
||||
return href.indexOf('/css/site.css') > -1
|
||||
});
|
||||
const original = link[0]
|
||||
while (original.nextElementSibling && original.nextElementSibling.nodeName === 'LINK') {
|
||||
original.nextElementSibling.remove()
|
||||
}
|
||||
|
||||
args.forEach(function (c) {
|
||||
const link = document.createElement('link')
|
||||
link.setAttribute('rel', 'stylesheet')
|
||||
link.setAttribute('href', c)
|
||||
|
||||
insertAfter(original, link)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function dispose(id) {
|
||||
const chooser = Data.get(id)
|
||||
Data.remove(id)
|
||||
|
||||
if (chooser) {
|
||||
EventHandler.off(chooser.el, 'click')
|
||||
}
|
||||
}
|
28
src/BootstrapBlazor.Server/Components/Components/Tips.razor
Normal file
28
src/BootstrapBlazor.Server/Components/Components/Tips.razor
Normal file
@ -0,0 +1,28 @@
|
||||
@inherits BootstrapComponentBase
|
||||
@inject IStringLocalizer<Tips> Localizer
|
||||
|
||||
<Alert AdditionalAttributes="@AdditionalAttributes" ShowBar="true" ShowBorder="true" Color="@Color">
|
||||
<h4><i class="alert-icon @Icon"></i>@Localizer["Title"]</h4>
|
||||
@ChildContent
|
||||
</Alert>
|
||||
|
||||
@code {
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图标
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Icon { get; set; } = "fa-regular fa-lightbulb";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 颜色 默认为 Info
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Color Color { get; set; } = Color.Info;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 子组件内容
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
@inherits WebSiteModuleComponentBase
|
||||
@inject IStringLocalizer<UpdateIntro> Localizer
|
||||
@attribute [JSModuleAutoLoader("Components/UpdateIntro.razor.js")]
|
||||
|
||||
<div class="blazor-intro" id="@Id" data-bb-button=".blazor-intro-button" data-bb-version="@PackageVersionService.Version">
|
||||
<h5><b>Bootstrap Blazor</b> @Localizer["H1"] <span class="version">@PackageVersionService.Version</span></h5>
|
||||
<div class="d-flex">
|
||||
<div class="blazor-intro-body">
|
||||
<p>@Localizer["B1"] <b>Bootstrap</b> <b>Blazor</b> @Localizer["B2"] <a href="@WebsiteOption.CurrentValue.AdminUrl" target="_blank"><b>@Localizer["B3"]</b></a> @Localizer["B4"]。<b>Bootstrap Blazor</b> @((MarkupString)Localizer["B5"].Value)</p>
|
||||
<p>
|
||||
@Localizer["P1"] <span class="version">@PackageVersionService.Version</span> @Localizer["P2"] <a target="_blank" href="@UpdateLogUrl"><b>[@Localizer["P3"]]</b></a> @Localizer["P4"] <b>Star</b>
|
||||
<a class="px-2" href="https://github.com/ArgoZhang/BootstrapBlazor" target="_blank">
|
||||
<img src="./images/git.svg" alt="github" />
|
||||
</a>
|
||||
<a href="@WebsiteOption.CurrentValue.BootstrapBlazorLink" target="_blank">
|
||||
<img src="./images/gitee.svg" alt="gitee" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="blazor-intro-barcode">
|
||||
<img src="./images/QQGroup@2x.png" alt="QQGroup" />
|
||||
<div>QQ 795206915</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="blazor-intro-button">
|
||||
<svg viewBox="0 0 24 24"><path d="M19.707 5.707l-1.414-1.414L12 10.586 5.707 4.293 4.293 5.707 10.586 12l-6.293 6.293 1.414 1.414L12 13.414l6.293 6.293 1.414-1.414L13.414 12l6.293-6.293z"></path></svg>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,35 @@
|
||||
// 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.Extensions.Options;
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// 更新日志介绍组件
|
||||
/// </summary>
|
||||
public partial class UpdateIntro
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IOptionsMonitor<WebsiteOptions>? WebsiteOption { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private PackageVersionService? PackageVersionService { get; set; }
|
||||
|
||||
private string UpdateLogUrl => $"{WebsiteOption.CurrentValue.BootstrapBlazorLink}/wikis/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97?sort_id=4062034";
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
protected override async Task InvokeInitAsync()
|
||||
{
|
||||
#if DEBUG
|
||||
await InvokeVoidAsync("init", "");
|
||||
#else
|
||||
await InvokeVoidAsync("init", Id, PackageVersionService.Version);
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
.blazor-intro {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1900;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(54.4deg,#771f89 -28.5%,#834cef 30.36%,#636cea 99.19%);
|
||||
padding: 1rem;
|
||||
height: 224px;
|
||||
transform: translateY(100%);
|
||||
transition: transform .3s ease-in-out;
|
||||
}
|
||||
|
||||
.blazor-intro.show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.blazor-intro .blazor-intro-body {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.blazor-intro .blazor-intro-body a {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.blazor-intro .blazor-intro-body img {
|
||||
width: 44px;
|
||||
}
|
||||
|
||||
.blazor-intro .blazor-intro-barcode {
|
||||
text-align: center;
|
||||
margin: 1rem 1rem 0 2rem;
|
||||
}
|
||||
|
||||
.blazor-intro .blazor-intro-barcode img {
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.blazor-intro-button {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
color: #fff;
|
||||
background-color: #4b4df6;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
padding: 6px;
|
||||
transition: background-color .3s linear;
|
||||
}
|
||||
|
||||
.blazor-intro-button:hover {
|
||||
background-color: #3c3de2;
|
||||
}
|
||||
|
||||
.blazor-intro-button svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.blazor-intro {
|
||||
display: none;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
import Data from "../../_content/BootstrapBlazor/modules/data.js?v=$version"
|
||||
import EventHandler from "../../_content/BootstrapBlazor/modules/event-handler.js?v=$version"
|
||||
|
||||
export function init(id, version) {
|
||||
const el = document.getElementById(id)
|
||||
if (el === null) {
|
||||
return
|
||||
}
|
||||
|
||||
const update = {
|
||||
el,
|
||||
key: `bb_intro_popup:${version}`,
|
||||
}
|
||||
Data.set(id, update)
|
||||
|
||||
check(update.key, update.el);
|
||||
EventHandler.on(el, 'click', '.blazor-intro-button', () => {
|
||||
close(update.key, el)
|
||||
})
|
||||
}
|
||||
|
||||
export function dispose(id) {
|
||||
Data.remove(id)
|
||||
|
||||
const data = Data.get(id)
|
||||
if (data) {
|
||||
EventHandler.off(data.el, 'click', '.blazor-intro-button');
|
||||
}
|
||||
}
|
||||
|
||||
const check = (key, el) => {
|
||||
const width = window.innerWidth
|
||||
if (width >= 768) {
|
||||
const isShown = localStorage.getItem(key)
|
||||
if (!isShown) {
|
||||
slideToggle(el)
|
||||
|
||||
// clean
|
||||
for (let index = localStorage.length; index > 0; index--) {
|
||||
const k = localStorage.key(index - 1);
|
||||
if (k.indexOf('bb_intro_popup:') > -1) {
|
||||
localStorage.removeItem(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const slideToggle = el => {
|
||||
el.classList.toggle('show')
|
||||
}
|
||||
|
||||
const close = (key, el) => {
|
||||
localStorage.setItem(key, 'false')
|
||||
slideToggle(el)
|
||||
}
|
42
src/BootstrapBlazor.Server/Components/Components/Video.razor
Normal file
42
src/BootstrapBlazor.Server/Components/Components/Video.razor
Normal file
@ -0,0 +1,42 @@
|
||||
@inject IOptionsMonitor<WebsiteOptions> Options
|
||||
@inject IStringLocalizer<Video> Localizer
|
||||
|
||||
<p><b>@Localizer["H1"]</b></p>
|
||||
|
||||
@if (VideoUrl.Any())
|
||||
{
|
||||
foreach (var url in VideoUrl)
|
||||
{
|
||||
<div class="mb-3">
|
||||
<a class="fa-solid fa-video" href="@url" target="_blank"><span class="ms-2">@Localizer["L1"]</span></a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="mb-3">@Localizer["L2"]</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
[NotNull]
|
||||
private List<string> VideoUrl { get; } = new List<string>();
|
||||
|
||||
[Parameter]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
if (!string.IsNullOrEmpty(Name) && Options.CurrentValue.Videos.TryGetValue(Name, out var url))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
VideoUrl.AddRange(url.Split(';').Select(a => $"{Options.CurrentValue.VideoUrl}{a}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// 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/
|
||||
|
||||
namespace BootstrapBlazor.Server.Components.Components;
|
||||
|
||||
/// <summary>
|
||||
/// WebSiteModuleComponentBase 组件
|
||||
/// </summary>
|
||||
public abstract class WebSiteModuleComponentBase : BootstrapModuleComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
protected override void OnLoadJSModule()
|
||||
{
|
||||
base.OnLoadJSModule();
|
||||
|
||||
ModulePath = $"./Components/{ModulePath}";
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
<DropdownWidget class="text-end flex-fill px-3">
|
||||
<DropdownWidgetItem Icon="fa-regular fa-envelope" BadgeNumber="4">
|
||||
<HeaderTemplate>
|
||||
<span>您有 4 个未读消息</span>
|
||||
</HeaderTemplate>
|
||||
<BodyTemplate>
|
||||
@for (var index = 0; index < 4; index++)
|
||||
{
|
||||
<a class="dropdown-item d-flex align-items-center" href="#" @onclick:preventDefault>
|
||||
<div style="width: 40px; height: 40px;">
|
||||
<Avatar Url="./images/Argo-C.png" IsCircle="true" Size="Size.Small" />
|
||||
</div>
|
||||
<div class="ms-2">
|
||||
<div class="d-flex position-relative">
|
||||
<h4>Argo Zhang</h4>
|
||||
<small><i class="fa-regular fa-clock"></i> @(4 + index) mins</small>
|
||||
</div>
|
||||
<div class="text-truncate">Why not buy a new awesome theme?</div>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
</BodyTemplate>
|
||||
<FooterTemplate>
|
||||
<a href="#" @onclick:preventDefault>查看所有消息</a>
|
||||
</FooterTemplate>
|
||||
</DropdownWidgetItem>
|
||||
<DropdownWidgetItem Icon="fa-regular fa-bell" BadgeNumber="10" HeaderColor="Color.Success" BadgeColor="Color.Warning">
|
||||
<HeaderTemplate>
|
||||
<span>您有 10 个未读通知</span>
|
||||
</HeaderTemplate>
|
||||
<BodyTemplate>
|
||||
@for (var index = 0; index < 10; index++)
|
||||
{
|
||||
<a class="dropdown-item d-flex align-items-center" href="#" @onclick:preventDefault>
|
||||
<i class="fa-solid fa-users text-primary"></i>
|
||||
<div class="ms-2">5 new members joined</div>
|
||||
</a>
|
||||
}
|
||||
</BodyTemplate>
|
||||
<FooterTemplate>
|
||||
<a href="#" @onclick:preventDefault>查看所有通知</a>
|
||||
</FooterTemplate>
|
||||
</DropdownWidgetItem>
|
||||
<DropdownWidgetItem Icon="fa-solid fa-flag" BadgeNumber="9" HeaderColor="Color.Danger" BadgeColor="Color.Danger">
|
||||
<HeaderTemplate>
|
||||
<span>您有 3 个任务</span>
|
||||
</HeaderTemplate>
|
||||
<BodyTemplate>
|
||||
<a href="#" class="dropdown-item" @onclick:preventDefault>
|
||||
<h3 class="position-relative">
|
||||
Design some buttons
|
||||
<small class="pull-right">20%</small>
|
||||
</h3>
|
||||
<BootstrapBlazor.Components.Progress IsAnimated="true" IsStriped="true" Value="20" Color="Color.Primary"></BootstrapBlazor.Components.Progress>
|
||||
</a>
|
||||
<a href="#" class="dropdown-item" @onclick:preventDefault>
|
||||
<h3 class="position-relative">
|
||||
Create a nice theme
|
||||
<small class="pull-right">40%</small>
|
||||
</h3>
|
||||
<BootstrapBlazor.Components.Progress Value="40" Color="Color.Success"></BootstrapBlazor.Components.Progress>
|
||||
</a>
|
||||
<a href="#" class="dropdown-item" @onclick:preventDefault>
|
||||
<h3 class="position-relative">
|
||||
Some task I need to do
|
||||
<small class="pull-right">60%</small>
|
||||
</h3>
|
||||
<BootstrapBlazor.Components.Progress Value="60" Color="Color.Danger"></BootstrapBlazor.Components.Progress>
|
||||
</a>
|
||||
</BodyTemplate>
|
||||
<FooterTemplate>
|
||||
<a href="#" @onclick:preventDefault>查看所有任务</a>
|
||||
</FooterTemplate>
|
||||
</DropdownWidgetItem>
|
||||
</DropdownWidget>
|
@ -0,0 +1,9 @@
|
||||
<Button Text="@Text" OnClick="@(e => OnClick(Text))" />
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string Text { get; set; } = "Test";
|
||||
|
||||
[Parameter]
|
||||
public Func<string, Task> OnClick { get; set; } = _ => Task.CompletedTask;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user