P11Button Component
P11Button is a versatile and accessible button component built with Bootstrap 5. It provides extensive customization options for appearance, size, icons, and behavior, ensuring a consistent and user-friendly experience.Standard Buttons (Various Variants and Sizes)
Basic buttons in different Bootstrap color schemes and sizes.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Primary Button" ButtonVariant="ButtonVariant.Primary" />
<P11Button Text="Secondary Button" ButtonVariant="ButtonVariant.Secondary" />
<P11Button Text="Success Button" ButtonVariant="ButtonVariant.Success" />
<P11Button Text="Danger Button" ButtonVariant="ButtonVariant.Danger" />
<P11Button Text="Warning Button" ButtonVariant="ButtonVariant.Warning" />
<P11Button Text="Info Button" ButtonVariant="ButtonVariant.Info" />
<P11Button Text="Light Button" ButtonVariant="ButtonVariant.Light" />
<P11Button Text="Dark Button" ButtonVariant="ButtonVariant.Dark" />
<P11Button Text="Link Button" ButtonVariant="ButtonVariant.Link" />
</div>
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Small Button" ButtonVariant="ButtonVariant.Primary" Size="Size.Small" />
<P11Button Text="Medium Button" ButtonVariant="ButtonVariant.Success" Size="Size.Medium" />
<P11Button Text="Large Button" ButtonVariant="ButtonVariant.Danger" Size="Size.Large" />
</div>
// P11Button is primarily designed for declarative use in Razor markup.
// No specific C# code is typically required for standard button variants and sizes.
Outline Buttons
Buttons with borders and transparent backgrounds.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Outline Primary" ButtonVariant="ButtonVariant.OutlinePrimary" />
<P11Button Text="Outline Success" ButtonVariant="ButtonVariant.OutlineSuccess" />
<P11Button Text="Outline Dark" ButtonVariant="ButtonVariant.OutlineDark" />
</div>
// Outline buttons are configured directly in Razor markup using the ButtonVariant parameter.
Buttons with Icons
Displaying icons before or after the text.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Save" IconClass="bi bi-save" ButtonVariant="ButtonVariant.Primary" />
<P11Button Text="Delete" IconClass="bi bi-trash" IconPosition="IconPosition.End" ButtonVariant="ButtonVariant.Danger" />
<P11Button Text="Search" IconClass="bi bi-search" ButtonVariant="ButtonVariant.Info" IconPosition="IconPosition.Start" />
<P11Button Text="Add" IconClass="bi bi-plus-circle" ButtonVariant="ButtonVariant.Success" IconPosition="IconPosition.End" />
<P11Button Text="Export" IconClass="bi bi-download" ButtonVariant="ButtonVariant.Secondary" />
</div>
// Icons are specified using the IconClass parameter (e.g., Bootstrap Icons).
// IconPosition determines if the icon appears at the start or end of the button text.
Icon-Only Buttons (with and without AriaLabel for Validation)
Buttons that only display an icon. Tests internal validation regarding AriaLabel.
P11Button Configuration Error:
P11Button Configuration Warning: This is an icon-only button without visible text. The 'AriaLabel' parameter is strongly recommended for accessibility to provide a descriptive label for screen readers.
This is only visible during development. Please correct the parameters or set SkipValidation to true to suppress this warning.
P11Button Configuration Error:
P11Button Configuration Warning: This is an icon-only button without visible text. The 'AriaLabel' parameter is strongly recommended for accessibility to provide a descriptive label for screen readers.
This is only visible during development. Please correct the parameters or set SkipValidation to true to suppress this warning.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button IconClass="bi bi-star-fill" AriaLabel="Star Button" Title="Give a star" ButtonVariant="ButtonVariant.Warning" />
<P11Button IconClass="bi bi-gear-fill" AriaLabel="Open Settings" ButtonVariant="ButtonVariant.Dark" />
<!-- This button should display a developer error message (configuration error),
as it only has an icon but no AriaLabel or Title. -->
<P11Button IconClass="bi bi-exclamation-triangle-fill" ButtonVariant="ButtonVariant.Info" />
<!-- This button should suppress the developer error message -->
<P11Button IconClass="bi bi-info-circle-fill" SkipValidation="true" ButtonVariant="ButtonVariant.Light" />
</div>
// For icon-only buttons, it's crucial to provide an AriaLabel or Title for accessibility.
// The component includes internal validation for this.
// SkipValidation can be used to suppress these warnings if the context implies accessibility.
Buttons with Loading State (IsLoading) and ARIA Announcements
Tests the loading state, spinner display, and screen reader announcements.
Implementation
<P11Button ButtonVariant="ButtonVariant.Primary"
IsLoading="@isLoading1"
OnClick="ToggleLoading1"
LoadingStartAnnouncement="Data is loading. Please wait."
LoadingEndAnnouncement="Data successfully loaded.">
@if (!isLoading1)
{
< span > Start Loading</ span >
}
else
{
< span > Loading...</ span >
}
</P11Button>
<P11Button ButtonVariant="ButtonVariant.Success"
IsLoading="False"
OnClick="ToggleLoading2"
LoadingStartAnnouncement="Save operation started."
LoadingEndAnnouncement="Save completed.">
@if (!isLoading2)
{
< i class= " bi bi-upload" > </ i >
}
</P11Button>
<P11Button ButtonVariant="ButtonVariant.Warning"
IsLoading="@isLoading3"
OnClick="ToggleLoading3"
LoadingStartAnnouncement="Process is starting."
LoadingEndAnnouncement="Process finished.">
@if (!isLoading3)
{
< i class= " bi bi-play-fill" > </ i >
}
else
{
< span > < i class= " bi bi-hourglass-split" > </ i > </ span >
}
</P11Button>
private bool isLoading1 = false;
private bool isLoading2 = false;
private bool isLoading3 = false;
private async Task ToggleLoading1()
{
isLoading1 = !isLoading1;
LogEvent($"Button 1: IsLoading set to {isLoading1}");
if (isLoading1)
{
await Task.Delay(3000); // Simulate network request
isLoading1 = false;
LogEvent("Button 1: Loading finished.");
}
}
private async Task ToggleLoading2()
{
isLoading2 = !isLoading2;
LogEvent($"Button 2: IsLoading set to {isLoading2}");
if (isLoading2)
{
await Task.Delay(2000); // Simulate network request
isLoading2 = false;
LogEvent("Button 2: Loading finished.");
}
}
private async Task ToggleLoading3()
{
isLoading3 = !isLoading3;
LogEvent($"Button 3: IsLoading set to {isLoading3}");
if (isLoading3)
{
await Task.Delay(2500); // Simulate network request
isLoading3 = false;
LogEvent("Button 3: Loading finished.");
}
}
Disabled Buttons (IsDisabled)
Buttons that are not clickable.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Disabled Primary" ButtonVariant="ButtonVariant.Primary" IsDisabled="true" />
<P11Button Text="Disabled Outline" ButtonVariant="ButtonVariant.OutlineSecondary" IsDisabled="true" />
<P11Button Text="Not Available" IconClass="bi bi-x-circle" ButtonVariant="ButtonVariant.Danger" IsDisabled="true" />
</div>
// Buttons are disabled using the IsDisabled parameter.
Buttons with Different HTML Types
Buttons with type=\"button\", type=\"submit\" and type=\"reset\".
P11Button Configuration Error:
P11Button Configuration Error: 'HtmlType' is set to 'Submit', but no 'OnClick' handler was provided. Ensure the button either has click logic or is disabled.
This is only visible during development. Please correct the parameters or set SkipValidation to true to suppress this warning.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Standard Button" HtmlType="HtmlType.Button" OnClick="@(() = > LogEvent(" Standard Button clicked"))" />
<P11Button Text="Submit Button" HtmlType="HtmlType.Submit" OnClick="@(() = > LogEvent(" Submit Button clicked (Form will submit if in form)"))" ButtonVariant="ButtonVariant.Success" />
<P11Button Text="Reset Button" HtmlType="HtmlType.Reset" OnClick="@(() = > LogEvent(" Reset Button clicked (Form will reset if in form)"))" ButtonVariant="ButtonVariant.Warning" />
<!-- This button should display a developer error message, as HtmlType="Submit" but no OnClick handler is present. -->
<P11Button Text="Submit (No OnClick)" HtmlType="HtmlType.Submit" ButtonVariant="ButtonVariant.Danger" />
</div>
// HtmlType specifies the button's behavior within a form.
// For HtmlType.Submit, it's generally recommended to have an OnClick handler
// or ensure it's part of a Blazor EditForm.
Buttons with ChildContent (Prioritized over Text Parameter)
Shows how ChildContent overrides the Text parameter.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Ignored Text" ButtonVariant="ButtonVariant.Primary">
<span class="text-white"><b>Perform Action</b> <i class="bi bi-arrow-right-circle"></i></span>
</P11Button>
<P11Button ButtonVariant="ButtonVariant.Secondary">
<span>ChildContent only here</span>
</P11Button>
</div>
// When both 'Text' and 'ChildContent' are provided, 'ChildContent' takes precedence.
// This allows for rich, custom HTML content within the button.
Buttons with Bootstrap Toggle/Dismiss Attributes (Modal, Offcanvas)
Simulates Bootstrap interactions (only works if Bootstrap JS is loaded).
Offcanvas Title
This is the content of the offcanvas menu.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<!-- Example for a Modal (You need an actual modal on the page for this to work) -->
<P11Button Text="Open Modal" ButtonVariant="ButtonVariant.Info" ToggleDataBsToggle="modal" ToggleDataBsTarget="#exampleModal" />
<!-- Example for an Offcanvas (You need an actual offcanvas on the page for this to work) -->
<P11Button Text="Toggle Offcanvas" ButtonVariant="ButtonVariant.Warning" ToggleDataBsToggle="offcanvas" ToggleDataBsTarget="#exampleOffcanvas" />
<!-- Example for a Dismiss button inside a Modal/Offcanvas -->
<P11Button Text="Close" ButtonVariant="ButtonVariant.Light" DismissDataBsDismiss="modal" />
</div>
<!-- Dummy Bootstrap Modal for test purposes (needs to be present on the page) -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal Title</h5>
<button type="button" class="btn-close</button>
</div>
<div class="modal-body">
This is the content of the modal dialog.
</div>
<div class="modal-footer">
<P11Button Text="Close" ButtonVariant="ButtonVariant.Secondary" DismissDataBsDismiss="modal" />
<P11Button Text="Save" ButtonVariant="ButtonVariant.Primary" />
</div>
</div>
</div>
</div>
<!-- Dummy Bootstrap Offcanvas for test purposes (needs to be present on the page) -->
<div class="offcanvas offcanvas-start" tabindex="-1" id="exampleOffcanvas" aria-labelledby="offcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasLabel">Offcanvas Title</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<p>This is the content of the offcanvas menu.</p>
</div>
</div>
// The ToggleDataBsToggle, ToggleDataBsTarget, and DismissDataBsDismiss parameters
// are used for direct integration with Bootstrap's JavaScript features.
// Ensure the corresponding Bootstrap components (e.g., modals, offcanvas) are present on the page.
Additional Attributes and Inline Styles
Application of additional HTML attributes and inline styles.
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Custom Style" style="background-color: #8A2BE2; color: white; border-radius: 8px;" ButtonVariant="ButtonVariant.None" />
<P11Button Text="Custom ID" id="myCustomButton" ButtonVariant="ButtonVariant.Primary" />
<P11Button Text="Data Attribute" data-custom-id="12345" data-category="example" ButtonVariant="ButtonVariant.Secondary" />
</div>
// Additional attributes and inline styles are passed directly to the component
// and are applied to the underlying HTML button element via Blazor's attribute splatting.
Event Handling (Check Console)
Check the browser console for messages on clicks, focus, and double-clicks.
Event Log:
Implementation
<div class="d-flex flex-wrap gap-2 mb-4">
<P11Button Text="Click me!" OnClick="@(() = > LogEvent(" Button clicked!"))" ButtonVariant="ButtonVariant.Primary" />
<P11Button Text="Focus me!" OnFocus="@(() = > LogEvent(" Button focused!"))" OnBlur="@(() = > LogEvent(" Button blurred!"))" ButtonVariant="ButtonVariant.Info" />
<P11Button Text="Double-click me!" OnDoubleClick="@(() = > LogEvent(" Button double-clicked!"))" ButtonVariant="ButtonVariant.Warning" />
<P11Button Text="Right-click me!" OnContextMenu="@(() = > LogEvent(" Button right-clicked!"))" ButtonVariant="ButtonVariant.Danger" />
</div>
<h4 class="mt-4">Event Log:</h4>
<div class="border p-2" style="height: 150px; overflow-y: scroll; background-color: #f8f9fa;">
@foreach (var logEntry in eventLog)
{
< div >
@logEntry
</ div >
}
</div>
private List<string> eventLog = new List<string>();
private void LogEvent(string message)
{
eventLog.Add($"{DateTime.Now:HH:mm:ss} - {message}");
// Keep only the last 10 entries
if (eventLog.Count > 10)
{
eventLog.RemoveAt(0);
}
StateHasChanged(); // Force UI update for the log
}
Component API
| Parameter | Type | Default | Description |
|---|---|---|---|
Text |
string? |
null |
The main text content of the button. This will be prioritized over ChildContent if both are provided. |
ChildContent |
RenderFragment? |
null |
The HTML content (e.g., other components, HTML tags) to be rendered inside the button. This will be used if the Text parameter is null or empty. |
ButtonVariant |
ButtonVariant? |
null (uses Bootstrap default) |
Specifies the button's variant (e.g., Primary, Secondary, OutlinePrimary) affecting its styling. |
Size |
Size |
Size.Medium |
Specifies the button's size (e.g., Small, Medium, Large) affecting its padding and font size. |
HtmlType |
HtmlType |
HtmlType.Button |
Specifies the HTML 'type' attribute for the button (e.g., button, submit, reset). |
IconClass |
string? |
null |
The CSS class for an icon to be displayed within the button (e.g., 'bi bi-search', 'fa fa-plus'). |
IconPosition |
IconPosition |
IconPosition.Start |
Specifies the position of the icon relative to the text within the button (Start or End). |
IsDisabled |
bool |
false |
Specifies whether the button should be disabled. A disabled button is not interactive. |
AriaLabel |
string? |
null |
An ARIA label for accessibility, providing a descriptive name for screen readers when the button's visible content is not sufficient. |
Title |
string? |
null |
A tooltip text that appears when the user hovers over the button. |
AdditionalAttributes |
Dictionary<string, object>? |
new() |
Additional HTML attributes to be splatted onto the button element. |
ToggleDataBsToggle |
string? |
null |
Specifies the data-bs-toggle attribute for Bootstrap integration (e.g., 'dropdown', 'modal'). |
ToggleDataBsTarget |
string? |
null |
Specifies the data-bs-target attribute for Bootstrap integration (e.g., '#myModalId'). |
DismissDataBsDismiss |
string? |
null |
Specifies the data-bs-dismiss attribute for Bootstrap integration (e.g., 'modal'). |
Style |
string? |
null |
Custom inline CSS style for the button element. |
SkipValidation |
bool |
false |
If set to true, developer-facing configuration validation warnings/errors will be suppressed. Use with caution. |
| Events | |||
OnClick |
EventCallback<MouseEventArgs> |
- | Event callback triggered when the button is clicked. |
OnFocus |
EventCallback<FocusEventArgs> |
- | Event callback triggered when the button receives keyboard focus. |
OnBlur |
EventCallback<FocusEventArgs> |
- | Event callback triggered when the button loses keyboard focus. |
OnDoubleClick |
EventCallback<MouseEventArgs> |
- | Event callback triggered when the button is double-clicked. |
OnContextMenu |
EventCallback<MouseEventArgs> |
- | Event callback triggered when the context menu is requested (e.g., right-click). |