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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>10.0.1-beta06</Version>
<Version>10.0.1-beta07</Version>
</PropertyGroup>

<PropertyGroup>
Expand All @@ -17,11 +17,7 @@
</ItemGroup>

<ItemGroup>
<!--<PackageReference Include="BootstrapBlazor" Version="$(BBVersion)" />-->
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\BootstrapBlazor\src\BootstrapBlazor\BootstrapBlazor.csproj" />
<PackageReference Include="BootstrapBlazor" Version="$(BBVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
56 changes: 38 additions & 18 deletions src/components/BootstrapBlazor.PdfReader/PdfReader.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,57 @@
<div class="bb-view-toolbar init">
<div class="bb-view-title">
<div class="bb-view-icon bb-view-bar"><i class="fa-solid fa-bars"></i></div>
<span class="bb-view-subject d-none d-sm-block">@_docTitle</span>
<span class="bb-view-subject">@_docTitle</span>
</div>
<div class="@ViewBodyString">
<input type="text" class="bb-view-num" @bind="CurrentPageString" /><span class="bb-view-slash">/</span><div class="bb-view-pagesCount"></div>
<input type="text" class="bb-view-num" @bind="CurrentPageString" /><span class="bb-view-slash">/</span>
<div class="bb-view-pagesCount"></div>
<div class="bb-view-divider"></div>
<div class="bb-view-icon bb-page-minus"><i class="fa-solid fa-minus"></i></div>
<input type="text" class="bb-view-scale" @bind="CurrentScaleString" />
<div class="bb-view-icon bb-page-plus"><i class="fa-solid fa-plus"></i></div>
<div class="bb-view-divider"></div>
<div class="bb-view-icon bb-view-fit-page" @onclick="FitToPage"><i class="fa-solid fa-arrows-left-right-to-line fa-rotate-90"></i></div>
<div class="bb-view-icon bb-view-fit-width" @onclick="FitToWidth"><i class="fa-solid fa-arrows-left-right-to-line"></i></div>
<div class="bb-view-icon bb-view-fit-rotate" @onclick="RotateLeft"><i class="fa-solid fa-rotate-left"></i></div>
<div class="bb-view-icon bb-view-fit-rotate" @onclick="RotateRight"><i class="fa-solid fa-rotate-right"></i></div>
<div class="bb-view-icon bb-page-minus"><i class="fa-solid fa-fw fa-minus"></i></div>
<input type="text" class="bb-view-scale-input" @bind="CurrentScaleString" />
<div class="bb-view-icon bb-page-plus"><i class="fa-solid fa-fw fa-plus"></i></div>
<div class="bb-view-scale">
<div class="bb-view-divider"></div>
<div class="bb-view-icon btn-group">
<button type="button" class="btn bb-view-fit-height" @onclick="() => SetFitMode(PdfReaderFitMode.PageHeight)"><i class="fa-solid fa-fw fa-arrows-left-right-to-line fa-rotate-90"></i></button>
<button type="button" class="btn bb-view-fit-width" @onclick="() => SetFitMode(PdfReaderFitMode.PageWidth)"><i class="fa-solid fa-fw fa-arrows-left-right-to-line"></i></button>
<button type="button" class="btn dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<div class="dropdown-menu dropdown-menu-end">
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageActual)">page-actual</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageWidth)">page-width</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageHeight)">page-height</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageFit)">page-fit</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.Auto)">auto</div>
Comment on lines +29 to +33
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dropdown items display raw technical values (e.g., "page-actual", "page-width") which are not user-friendly. Consider using localized or human-readable labels instead, similar to how the enum descriptions are used in Chinese comments (e.g., "实际大小" for PageActual, "页面宽度" for PageWidth).

Suggested change
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageActual)">page-actual</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageWidth)">page-width</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageHeight)">page-height</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageFit)">page-fit</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.Auto)">auto</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageActual)">实际大小</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageWidth)">页面宽度</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageHeight)">页面高度</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageFit)">适合页面</div>
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.Auto)">自动</div>

Copilot uses AI. Check for mistakes.
</div>
</div>
<div class="bb-view-icon bb-view-fit-rotate" @onclick="RotateLeft"><i class="fa-solid fa-fw fa-rotate-left"></i></div>
<div class="bb-view-icon bb-view-fit-rotate" @onclick="RotateRight"><i class="fa-solid fa-fw fa-rotate-right"></i></div>
</div>
</div>
<div class="bb-view-controls">
@if (ShowDownload)
{
<div class="bb-view-icon bb-view-download" @onclick="OnDownload"><i class="fa-solid fa-arrow-right-to-bracket fa-rotate-90"></i></div>
<div class="bb-view-icon bb-view-download" @onclick="OnDownload"><i class="fa-solid fa-fw fa-arrow-right-to-bracket fa-rotate-90"></i></div>
}
@if (ShowPrint)
{
<div class="bb-view-icon bb-view-print"><i class="fa-solid fa-fw fa-print"></i></div>
}
<div class="bb-view-icon bb-view-print"><i class="fa-solid fa-print"></i></div>
<Dropdown TValue="string" Color="Color.None" SkipValidate="true" ShowLabel="false"
IsPopover="false" MenuAlignment="Alignment.Right" Icon="@MoreButtonIcon">
<ItemsTemplate>
@if (ShowTwoPagesOneViewButton)
<div class="dropdown">
<button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown">
<i class="@MoreButtonIcon"></i>
</button>
<div class="dropdown-menu shadow dropdown-menu-end">
@if (ShowTwoPagesOneView)
{
<div class="dropdown-item dropdown-item-pages" @onclick="OnToggleTwoPagesOneView"><i class="@_twoPagesOneViewIcon"></i><span>Two pages on view</span></div>
<Divider></Divider>
}
<div class="dropdown-item"><i class="fa-solid fa-fw"></i><span>Document properties</span></div>
</ItemsTemplate>
</Dropdown>
</div>
</div>
</div>
</div>
}
Expand Down
48 changes: 21 additions & 27 deletions src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public partial class PdfReader
[Parameter]
public bool ShowDownload { get; set; } = true;

/// <summary>
/// 获得/设置 是否显示打印按钮 默认 true 显示
/// </summary>
[Parameter]
public bool ShowPrint { get; set; } = true;

/// <summary>
/// 获得/设置 是否显示缩略图 默认 true 显示
/// </summary>
Expand Down Expand Up @@ -59,13 +65,13 @@ public partial class PdfReader
/// 获得/设置 是否适配当前页面宽度 默认 false
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation comment "获得/设置 是否适配当前页面宽度 默认 false" (Get/Set whether to fit current page width, default false) is outdated. The parameter type changed from bool IsFitToPage to PdfReaderFitMode FitMode, which accepts multiple fit modes. The comment should be updated to reflect this, e.g., "获得/设置 文档适配模式 默认 Auto" (Get/Set document fit mode, default Auto).

Suggested change
/// 获得/设置 是否适配当前页面宽度 默认 false
/// 获得/设置 文档适配模式 默认 Auto

Copilot uses AI. Check for mistakes.
/// </summary>
[Parameter]
public bool IsFitToPage { get; set; }
public PdfReaderFitMode FitMode { get; set; }

/// <summary>
/// 获得/设置 是否显示双页单视图按钮 默认 true 显示
/// </summary>
[Parameter]
public bool ShowTwoPagesOneViewButton { get; set; } = true;
public bool ShowTwoPagesOneView { get; set; } = true;

/// <summary>
/// 获得/设置 是否启用双页单视图模式 默认 false
Expand All @@ -86,7 +92,7 @@ public partial class PdfReader
public Func<int, Task>? OnPagesLoadedAsync { get; set; }

/// <summary>
/// 页面初始化回调方法
/// 页码变化时回调方法
/// </summary>
[Parameter]
public Func<uint, Task>? OnPageChangedAsync { get; set; }
Expand All @@ -109,9 +115,6 @@ public partial class PdfReader
[Parameter]
public Func<Task>? OnDownloadAsync { get; set; }

[Inject, NotNull]
private DownloadService? DownloadService { get; set; }

private string? ClassString => CssBuilder.Default("bb-pdf-reader")
.AddClassFromAttributes(AdditionalAttributes)
.Build();
Expand All @@ -122,20 +125,18 @@ public partial class PdfReader
.Build();

private string? ViewBodyString => CssBuilder.Default("bb-view-body")
.AddClass("fit-page", IsFitToPage)
.AddClass("fit-width", FitMode == PdfReaderFitMode.PageHeight)
.Build();

private string? _docTitle;
private bool _isFitToPage;
private PdfReaderFitMode _fitMode;
private uint _currentPage;
private string? _url;
private string? _currentScale;
private bool _enableTwoPagesOneView;
private bool _showTwoPagesOneViewButton;
private string? _twoPagesOneViewIcon;

private readonly HashSet<string> AllowedScaleValues = ["page-actual", "page-width", "page-height", "page-fit", "auto"];

private string CurrentPageString
{
get => CurrentPage.ToString(CultureInfo.InvariantCulture);
Expand Down Expand Up @@ -190,7 +191,7 @@ protected override void OnParametersSet()
{
base.OnParametersSet();

MoreButtonIcon ??= "fa-solid fa-ellipsis-vertical";
MoreButtonIcon ??= "fa-solid fa-fw fa-ellipsis-vertical";
_twoPagesOneViewIcon ??= "fa-solid fa-fw";

if (CurrentPage == 0)
Expand All @@ -211,12 +212,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender)

if (firstRender)
{
_isFitToPage = IsFitToPage;
_fitMode = FitMode;
_currentPage = CurrentPage;
_url = Url;
_currentScale = CurrentScale;
_enableTwoPagesOneView = EnableTwoPagesOneView;
_showTwoPagesOneViewButton = ShowTwoPagesOneViewButton;
_showTwoPagesOneViewButton = ShowTwoPagesOneView;
}

if (_url != Url)
Expand All @@ -225,10 +226,10 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
await InvokeInitAsync();
}

if (_isFitToPage != IsFitToPage)
if (_fitMode != FitMode)
{
_isFitToPage = IsFitToPage;
await TriggerFit(_isFitToPage ? "fitToPage" : "fitToWidth");
_fitMode = FitMode;
await InvokeVoidAsync("setScaleValue", Id, _fitMode.ToDescriptionString());
}
if (_currentPage != CurrentPage)
{
Expand All @@ -245,9 +246,9 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
_enableTwoPagesOneView = EnableTwoPagesOneView;
await InvokeVoidAsync("setPages", Id, _enableTwoPagesOneView);
}
if (_showTwoPagesOneViewButton != ShowTwoPagesOneViewButton)
if (_showTwoPagesOneViewButton != ShowTwoPagesOneView)
{
_showTwoPagesOneViewButton = ShowTwoPagesOneViewButton;
_showTwoPagesOneViewButton = ShowTwoPagesOneView;
await InvokeVoidAsync("setPages", Id, _enableTwoPagesOneView);
}
}
Expand All @@ -259,7 +260,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, new
{
Url,
IsFitToPage,
FitMode,
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FitMode enum value is being passed directly to JavaScript, but it needs to be converted to its description string value (e.g., "page-width", "page-height"). It should be FitMode.ToDescriptionString() or a similar conversion, similar to what's done on line 232.

Suggested change
FitMode,
FitMode = FitMode.ToDescriptionString(),

Copilot uses AI. Check for mistakes.
EnableThumbnails,
TriggerPagesInit = OnPagesInitAsync != null,
TriggerPagesLoaded = OnPagesLoadedAsync != null,
Expand All @@ -277,12 +278,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
/// <summary>
/// 适应页面宽度
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation comment "适应页面宽度" (Fit to page width) is misleading. This method now sets any fit mode via parameter, not just page width. The comment should be updated to reflect the actual functionality, e.g., "设置文档适配模式" (Set document fit mode).

Suggested change
/// 适应页面宽度
/// 设置文档适配模式

Copilot uses AI. Check for mistakes.
/// </summary>
public void FitToPage() => IsFitToPage = true;

/// <summary>
/// 适应文档宽度
/// </summary>
public void FitToWidth() => IsFitToPage = false;
public void SetFitMode(PdfReaderFitMode mode) => FitMode = mode;

/// <summary>
/// 旋转页面方法
Expand Down Expand Up @@ -310,8 +306,6 @@ private async Task OnDownload()
}
}

private Task TriggerFit(string methodName) => InvokeVoidAsync(methodName, Id);

/// <summary>
/// 页面开始初始化时回调方法
/// </summary>
Expand Down
48 changes: 39 additions & 9 deletions src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
visibility: hidden;
}

.bb-view-toolbar ::deep .btn {
.bb-view-toolbar .btn {
--bs-btn-color: #fff;
}

.bb-view-toolbar ::deep .dropdown-toggle::after {
.bb-view-toolbar .bb-view-controls .dropdown-toggle::after {
content: none;
}

Expand All @@ -34,7 +34,6 @@
}

.bb-view-icon {
margin: 0 .5rem;
padding: .5rem;
cursor: pointer;
}
Expand All @@ -43,6 +42,20 @@
color: #6c757d;
}

.bb-view-icon .dropdown-toggle-split {
padding-left: 0.25rem;
padding-right: 0.25rem;
}

.bb-view-icon.btn-group .btn {
--bs-btn-padding-x: 0.5rem;
}

.bb-view-icon.btn-group .dropdown-toggle-split {
padding-left: 0;
padding-right: 0;
}

.bb-view-subject {
white-space: nowrap;
display: block;
Expand All @@ -51,6 +64,10 @@
max-width: 300px;
}

.bb-view-pagesCount {
padding-inline-end: .5rem;
}

.bb-view-body {
flex: 1;
min-width: 0;
Expand All @@ -59,30 +76,35 @@
flex-wrap: nowrap;
align-items: center;
justify-content: center;
overflow: hidden;
background-color: var(--bb-toolbar-background-color);
}

.bb-view-body.fit-page .bb-view-fit-page {
.bb-view-body.fit-width .bb-view-fit-height {
display: none;
}

.bb-view-body.fit-page .bb-view-fit-width {
.bb-view-body.fit-width .bb-view-fit-width {
display: block;
}

.bb-view-body .bb-view-fit-width {
display: none;
}

.bb-view-num, .bb-view-scale {
.bb-view-scale {
display: flex;
align-items: center;
}

.bb-view-num, .bb-view-scale-input {
width: 36px;
text-align: center;
background-color: #000;
border: none;
color: #fff;
}

.bb-view-scale {
.bb-view-scale-input {
width: 40px;
}

Expand All @@ -94,16 +116,24 @@
width: .6px;
height: calc(var(--bb-pdf-toolbar-height) / 3);
background-color: #777;
margin: 0 1rem;
margin: 0 0.5rem;
}

.bb-view-divider + .bb-view-icon {
padding-inline-start: 0;
}

.bb-view-controls {
display: flex;
align-items: center;
justify-content: center;
padding: 0 1rem;
}

.bb-view-controls .dropdown-toggle {
padding: 7px;
}

.bb-view-main {
display: flex;
width: 100%;
Expand Down
Loading