Skip to content

schivei/anbth

Repository files navigation

Anbth - ASP.NET Bootstrap 5.3.8 Tag Helpers

Build and Test CodeQL Package Release NuGet Version NuGet Downloads GitHub Release GitHub Package License

Anbth is a comprehensive library of ASP.NET Core Tag Helpers that brings Bootstrap 5.3.8 components and utilities to your Razor views through an intuitive attribute-driven approach. Supports both native HTML tag enhancement via bs-* attributes and custom tags for complex components.

Features

  • Bootstrap 5.3.8 Complete Coverage - All components, forms, and utilities
  • Dual Syntax Support - Both native tag enhancement (bs-* attributes) and custom tags (<modal>, <offcanvas>, etc.)
  • Attribute-Driven API - Intuitive attributes with strongly-typed enums
  • Auto-ID Generation - Automatic unique IDs for components that need them
  • Accessibility First - Proper ARIA attributes and roles automatically added
  • .NET 10 - Built for the latest .NET platform
  • IntelliSense Support - Full XML documentation for all tag helpers and properties
  • CI/CD Pipelines - Automated build, test, package, and release workflows

Installation

Install via NuGet Package Manager:

dotnet add package Anbth

Or via Package Manager Console:

Install-Package Anbth

Quick Start

1. Add Bootstrap 5.3.8 to Your Layout

Add Bootstrap CSS and JavaScript to your _Layout.cshtml or page:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My App</title>
    
    <!-- Bootstrap 5.3.8 CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" 
          rel="stylesheet" 
          integrity="sha384-..." 
          crossorigin="anonymous">
    
    <!-- Optional: Bootstrap Icons -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
</head>
<body>
    @RenderBody()
    
    <!-- Bootstrap 5.3.8 JS Bundle (includes Popper) -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" 
            integrity="sha384-..." 
            crossorigin="anonymous"></script>
    
    @RenderSection("Scripts", required: false)
</body>
</html>

2. Register Tag Helpers

Add to your _ViewImports.cshtml:

@addTagHelper *, Anbth

3. Start Using Bootstrap Components

<!-- Alert -->
<div bs-alert bs-variant="Success" bs-dismissible="true">
    <strong>Success!</strong> Your action was completed.
</div>

<!-- Button -->
<button bs-button bs-variant="Primary" bs-size="Large">
    Click Me
</button>

<!-- Card -->
<div bs-card bs-variant="Light">
    <div class="card-body">
        <h5 class="card-title">Card Title</h5>
        <p class="card-text">Some quick example text.</p>
    </div>
</div>

Component Examples

Alerts (Hybrid)

Alerts support both custom tags and attributes for maximum flexibility.

Custom Tag Syntax (for divs):

<!-- Basic Alert -->
<alert variant="Success">
    Operation completed successfully!
</alert>

<!-- Dismissible Alert with Fade -->
<alert variant="Warning" dismissible="true" fade="true" id="my-alert">
    <strong>Warning!</strong> Something needs your attention.
</alert>

Attribute Syntax (for semantic HTML):

<!-- On div -->
<div bs-alert bs-variant="Info">
    This is an info alert.
</div>

<!-- On section -->
<section bs-alert bs-variant="Danger" bs-dismissible="true">
    <strong>Error!</strong> Something went wrong.
</section>

<!-- On article or aside -->
<article bs-alert bs-variant="Success">
    Article content with alert styling.
</article>

Properties:

  • variant / bs-variant - Color scheme (Primary, Secondary, Success, Danger, Warning, Info, Light, Dark)
  • dismissible / bs-dismissible - Makes alert dismissible with close button
  • fade / bs-fade - Enables fade animation (default: true)
  • id - Custom ID (auto-generated if not provided)

Supported Elements:

  • Custom tag: <alert>
  • Attributes: div, section, article, aside

Buttons

<!-- Solid Button -->
<button bs-button bs-variant="Primary">Primary Button</button>

<!-- Outline Button -->
<button bs-button bs-variant="Success" bs-outline="true">Success Outline</button>

<!-- Sized Button -->
<button bs-button bs-variant="Danger" bs-size="Large">Large Button</button>
<button bs-button bs-variant="Secondary" bs-size="Small">Small Button</button>

<!-- Block Button -->
<button bs-button bs-variant="Info" bs-block="true">Full Width Button</button>

<!-- Disabled Button -->
<button bs-button bs-variant="Primary" bs-disabled="true">Disabled</button>

<!-- Link as Button -->
<a bs-button bs-variant="Link" href="/somewhere">Link Button</a>

Attributes:

  • bs-button - Activates the button tag helper
  • bs-variant - Button color
  • bs-size - Size (Small, Default, Large)
  • bs-outline - Outline style
  • bs-disabled - Disabled state
  • bs-active - Active state
  • bs-block - Full width

Grid System (Hybrid Approach)

Anbth provides two ways to work with Bootstrap's grid system:

Option 1: Custom Tags (Recommended for divs)

<!-- Simple Grid -->
<container>
    <row>
        <col md="6">Column 1</col>
        <col md="6">Column 2</col>
    </row>
</container>

<!-- Fluid Container -->
<container-fluid>
    <row gutter="3">
        <col size="12" md="8">Main Content</col>
        <col size="12" md="4">Sidebar</col>
    </row>
</container-fluid>

<!-- Responsive Breakpoint Containers -->
<container-md><!-- Responsive at md and above -->
    <row gutter-x="2" gutter-y="3">
        <col sm="6" md="4" lg="3">Card 1</col>
        <col sm="6" md="4" lg="3">Card 2</col>
        <col sm="6" md="4" lg="3">Card 3</col>
        <col sm="6" md="4" lg="3">Card 4</col>
    </row>
</container-md>

<!-- Available container tags: -->
<!-- <container> - Fixed width container -->
<!-- <container-fluid> - Full width container -->
<!-- <container-sm>, <container-md>, <container-lg>, <container-xl>, <container-xxl> - Responsive containers -->

<!-- Column with Offset and Order -->
<container>
    <row>
        <col md="4" offset="4">Centered Column</col>
    </row>
    <row>
        <col order="2">First (but ordered 2nd)</col>
        <col order="1">Second (but ordered 1st)</col>
    </row>
</container>

Custom Tag Options:

  • Container Tags: <container>, <container-fluid>, <container-sm>, <container-md>, <container-lg>, <container-xl>, <container-xxl>
    • id - Container ID
  • <row>:
    • gutter - Overall gutter size (0-5)
    • gutter-x - Horizontal gutter (0-5)
    • gutter-y - Vertical gutter (0-5)
    • id - Row ID
  • <col>:
    • size - Base column size (1-12 or "auto")
    • sm, md, lg, xl, xxl - Responsive sizes
    • offset - Column offset
    • order - Column order
    • id - Column ID

Option 2: Attributes on Native Elements (For non-div elements)

<!-- Works on any element, not just divs -->
<div bs-container>
    <div bs-row bs-gutter="3">
        <div bs-col="12" bs-col-md="6">Column 1</div>
        <div bs-col="12" bs-col-md="6">Column 2</div>
    </div>
</div>

<!-- Can be used on section, article, etc. -->
<section bs-container-fluid>
    <article bs-row>
        <aside bs-col="12" bs-col-lg="3">Sidebar</aside>
        <main bs-col="12" bs-col-lg="9">Main Content</main>
    </article>
</section>

<!-- Responsive container attributes -->
<section bs-container-md><!-- Responsive at md and above -->
    <div bs-row bs-gutter="2">
        <div bs-col="12" bs-col-sm="6">Item 1</div>
        <div bs-col="12" bs-col-sm="6">Item 2</div>
    </div>
</section>

Attribute Syntax:

  • Container Attributes: bs-container, bs-container-fluid, bs-container-sm, bs-container-md, bs-container-lg, bs-container-xl, bs-container-xxl
  • bs-row - Activates row
  • bs-gutter - Gutter size
  • bs-col - Activates column with size
  • bs-col-sm, bs-col-md, bs-col-lg, bs-col-xl, bs-col-xxl - Responsive column sizes

When to use each approach:

  • Use custom tags (<container>, <row>, <col>) when working with divs for cleaner markup
  • Use attributes (bs-container, bs-row, bs-col) when working with semantic HTML elements (section, article, aside, main, etc.)

Forms

Form Controls

<!-- Text Input -->
<input bs-form-control type="text" placeholder="Enter text" />

<!-- Large Input -->
<input bs-form-control bs-size="Large" type="text" />

<!-- Textarea -->
<textarea bs-form-control rows="3"></textarea>

<!-- Validated Input -->
<input bs-form-control bs-valid="true" type="email" />
<input bs-form-control bs-valid="false" type="email" />

<!-- Readonly -->
<input bs-form-control bs-readonly="true" value="Read-only value" />

<!-- Disabled -->
<input bs-form-control bs-disabled="true" type="text" />

Select

<select bs-select>
    <option>Choose...</option>
    <option>Option 1</option>
    <option>Option 2</option>
</select>

<!-- Large Select -->
<select bs-select bs-size="Large">
    <option>Large Select</option>
</select>

Checkboxes and Radios

<!-- Checkbox -->
<div bs-check>
    <input bs-check type="checkbox" id="check1" />
    <label class="form-check-label" for="check1">Check me out</label>
</div>

<!-- Switch -->
<div bs-check bs-switch="true">
    <input bs-check type="checkbox" id="switch1" />
    <label class="form-check-label" for="switch1">Toggle switch</label>
</div>

<!-- Inline Checkboxes -->
<div bs-check bs-inline="true">
    <input bs-check type="checkbox" id="inline1" />
    <label class="form-check-label" for="inline1">Option 1</label>
</div>
<div bs-check bs-inline="true">
    <input bs-check type="checkbox" id="inline2" />
    <label class="form-check-label" for="inline2">Option 2</label>
</div>

Input Groups

<div bs-input-group>
    <span class="input-group-text">@</span>
    <input bs-form-control type="text" placeholder="Username" />
</div>

<!-- Large Input Group -->
<div bs-input-group bs-size="Large">
    <span class="input-group-text">$</span>
    <input bs-form-control type="text" />
    <span class="input-group-text">.00</span>
</div>

Range

<input bs-range min="0" max="100" value="50" />

Modals

Anbth provides two ways to use modals:

Option 1: Custom Modal Tag with Sub-Tags (Recommended)

<modal size="Large" centered="true" id="myModal">
    <modal-header>
        <modal-title id="myModalLabel">Modal Title</modal-title>
        <button bs-close bs-dismiss="modal"></button>
    </modal-header>
    <modal-body>
        <p>Modal body text goes here.</p>
    </modal-body>
    <modal-footer>
        <button bs-button bs-variant="Secondary" data-bs-dismiss="modal">Close</button>
        <button bs-button bs-variant="Primary">Save changes</button>
    </modal-footer>
</modal>

<!-- Trigger Button -->
<button bs-button bs-variant="Primary" data-bs-toggle="modal" data-bs-target="#myModal">
    Launch Modal
</button>

Available Sub-Tags:

  • <modal-header> - Modal header section
  • <modal-title> - Modal title (renders as h5)
  • <modal-body> - Modal body content
  • <modal-footer> - Modal footer with actions

Option 2: Native Div with bs-modal Attribute

<!-- Modal -->
<div bs-modal bs-size="Large" bs-centered="true" id="myModal">
    <div class="modal-header">
        <h5 class="modal-title" id="myModalLabel">Modal Title</h5>
        <button bs-close bs-dismiss="modal"></button>
    </div>
    <div class="modal-body">
        <p>Modal body text goes here.</p>
    </div>
    <div class="modal-footer">
        <button bs-button bs-variant="Secondary" data-bs-dismiss="modal">Close</button>
        <button bs-button bs-variant="Primary">Save changes</button>
    </div>
</div>

<!-- Trigger Button -->
<button bs-button bs-variant="Primary" data-bs-toggle="modal" data-bs-target="#myModal">
    Launch Modal
</button>

Attributes:

  • size / bs-size - Modal size (Small, Default, Large)
  • centered / bs-centered - Vertically center
  • scrollable / bs-scrollable - Make body scrollable
  • fullscreen / bs-fullscreen - Fullscreen modal
  • backdrop / bs-backdrop - Show backdrop (default: true)
  • backdrop-static / bs-backdrop-static - Static backdrop (no dismiss on click)
  • keyboard / bs-keyboard - Close on ESC key (default: true)
  • fade / bs-fade - Fade animation (default: true)

Offcanvas

Option 1: Custom Offcanvas Tag with Sub-Tags (Recommended)

<offcanvas placement="start" id="offcanvasExample">
    <offcanvas-header>
        <offcanvas-title id="offcanvasExampleLabel">Offcanvas</offcanvas-title>
        <button bs-close bs-dismiss="offcanvas"></button>
    </offcanvas-header>
    <offcanvas-body>
        Content goes here.
    </offcanvas-body>
</offcanvas>

<!-- Trigger -->
<button bs-button bs-variant="Primary" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample">
    Open Offcanvas
</button>

Available Sub-Tags:

  • <offcanvas-header> - Offcanvas header section
  • <offcanvas-title> - Offcanvas title (renders as h5)
  • <offcanvas-body> - Offcanvas body content

Option 2: Native Div with bs-offcanvas Attribute

<div bs-offcanvas bs-placement="start" id="offcanvasExample">
    <div class="offcanvas-header">
        <h5 class="offcanvas-title" id="offcanvasExampleLabel">Offcanvas</h5>
        <button bs-close bs-dismiss="offcanvas"></button>
    </div>
    <div class="offcanvas-body">
        Content goes here.
    </div>
</div>

<!-- Trigger -->
<button bs-button bs-variant="Primary" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample">
    Open Offcanvas
</button>

Attributes:

  • placement / bs-placement - Position (start, end, top, bottom)
  • scroll / bs-scroll - Allow body scroll
  • backdrop / bs-backdrop - Show backdrop
  • keyboard / bs-keyboard - Close on ESC

Dropdowns

<div bs-dropdown>
    <button bs-button bs-dropdown-toggle bs-variant="Primary">
        Dropdown button
    </button>
    <ul class="dropdown-menu">
        <li><a class="dropdown-item" href="#">Action</a></li>
        <li><a class="dropdown-item" href="#">Another action</a></li>
        <li><hr class="dropdown-divider"></li>
        <li><a class="dropdown-item" href="#">Something else</a></li>
    </ul>
</div>

Attributes:

  • bs-dropdown - Container
  • bs-dropdown-toggle - Toggle button
  • bs-direction - Direction (down, up, start, end)
  • bs-auto-close - Auto close behavior

Tooltips and Popovers

Auto-Initialization: Tooltips and popovers are automatically initialized by default! The tag helpers inject the necessary JavaScript after each element.

<!-- Tooltip - Auto-initialized -->
<button bs-button bs-variant="Secondary" bs-tooltip="Tooltip text" bs-tooltip-placement="Top">
    Hover me
</button>

<!-- Popover - Auto-initialized -->
<button bs-button bs-variant="Primary" 
        bs-popover="Popover content text" 
        bs-popover-title="Popover Title"
        bs-popover-placement="Right">
    Click me
</button>

<!-- Custom trigger -->
<button bs-button bs-variant="Info" 
        bs-tooltip="Click to see tooltip" 
        bs-tooltip-trigger="click">
    Click me for tooltip
</button>

<!-- Disable auto-initialization (if you want manual control) -->
<button bs-button bs-variant="Warning" 
        bs-tooltip="Manual tooltip" 
        bs-tooltip-no-init="true"
        id="manual-tooltip">
    Manual initialization
</button>

<script>
// Only needed if you use bs-tooltip-no-init or bs-popover-no-init
new bootstrap.Tooltip(document.getElementById('manual-tooltip'));
</script>

Available Attributes:

  • bs-tooltip / bs-popover - Content text
  • bs-tooltip-placement / bs-popover-placement - Position (Top, Bottom, Left, Right, Auto, etc.)
  • bs-tooltip-trigger / bs-popover-trigger - Trigger event (hover, click, focus, etc.)
  • bs-tooltip-no-init / bs-popover-no-init - Disable auto-initialization
  • bs-popover-title - Popover title (popover only)

Navigation

Navs and Tabs

<!-- Tabs -->
<ul bs-nav bs-style="tabs">
    <li class="nav-item">
        <a class="nav-link active" href="#">Active</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
    </li>
</ul>

<!-- Pills -->
<ul bs-nav bs-style="pills" bs-vertical="true">
    <li class="nav-item">
        <a class="nav-link active" href="#">Active</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
    </li>
</ul>

Navbar

<nav bs-navbar bs-expand="lg" bs-variant="Dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="#">Navbar</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link active" href="#">Home</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Features</a>
                </li>
            </ul>
        </div>
    </div>
</nav>

Grid System

<!-- Container -->
<div bs-container>
    <!-- Row -->
    <div bs-row bs-gutter="3">
        <!-- Columns -->
        <div bs-col="12" bs-col-md="6" bs-col-lg="4">Column 1</div>
        <div bs-col="12" bs-col-md="6" bs-col-lg="4">Column 2</div>
        <div bs-col="12" bs-col-lg="4">Column 3</div>
    </div>
</div>

<!-- Fluid Container -->
<div bs-container bs-fluid="true">
    <div bs-row>
        <div bs-col="auto">Auto width</div>
        <div bs-col>Flexible width</div>
    </div>
</div>

Cards

<div bs-card bs-variant="Primary" bs-text-variant="White">
    <div class="card-header">Featured</div>
    <div class="card-body">
        <h5 class="card-title">Special title treatment</h5>
        <p class="card-text">With supporting text below.</p>
        <button bs-button bs-variant="Light">Go somewhere</button>
    </div>
</div>

Progress Bars

<!-- Simple Progress -->
<div bs-progress>
    <div bs-progress-bar bs-value="75"></div>
</div>

<!-- Colored Progress -->
<div bs-progress>
    <div bs-progress-bar bs-value="60" bs-variant="Success"></div>
</div>

<!-- Striped and Animated -->
<div bs-progress>
    <div bs-progress-bar bs-value="50" bs-striped="true" bs-animated="true" bs-variant="Info"></div>
</div>

Spinners

<!-- Border Spinner -->
<div bs-spinner></div>

<!-- Growing Spinner -->
<div bs-spinner bs-type="grow" bs-variant="Primary"></div>

<!-- Small Spinner -->
<span bs-spinner bs-size="Small" bs-variant="Secondary"></span>

Badges (Hybrid)

Badges support both custom tags and attributes, and can be used on <span> and <a> elements.

Custom Tag Syntax:

<!-- Basic Badge -->
<badge variant="Primary">New</badge>

<!-- Pill Badge -->
<badge variant="Success" pill="true">5</badge>

<!-- Badge with ID -->
<badge variant="Danger" id="notification-badge">99+</badge>

Attribute Syntax:

<!-- On span -->
<span bs-badge bs-variant="Primary">Primary</span>

<!-- On anchor (link badge) -->
<a href="/notifications" bs-badge bs-variant="Danger" bs-pill="true">
    99+
</a>

<!-- Pill badge on span -->
<span bs-badge bs-variant="Success" bs-pill="true">Success</span>

Properties:

  • variant / bs-variant - Color scheme (Primary, Secondary, Success, Danger, Warning, Info, Light, Dark)
  • pill / bs-pill - Rounded pill styling
  • id - Custom ID

Supported Elements:

  • Custom tag: <badge> (renders as <span>)
  • Attributes: span, a

List Groups

<ul bs-list-group>
    <li bs-list-group-item>An item</li>
    <li bs-list-group-item bs-active="true">Active item</li>
    <li bs-list-group-item bs-disabled="true">Disabled item</li>
</ul>

<!-- Colored Items -->
<div bs-list-group>
    <a bs-list-group-item bs-variant="Primary" href="#">Primary item</a>
    <a bs-list-group-item bs-variant="Success" href="#">Success item</a>
</div>

Utility Classes

Anbth provides tag helper attributes for common Bootstrap utilities:

<!-- Spacing -->
<div bs-m="3" bs-p="2">Margin 3, Padding 2</div>
<div bs-mt="5" bs-mb="3">Margin Top 5, Bottom 3</div>
<div bs-px="4" bs-py="2">Padding X 4, Y 2</div>

<!-- Display -->
<div bs-display="flex">Flex container</div>
<span bs-display="none">Hidden</span>

<!-- Flex -->
<div bs-display="flex" bs-flex="row align-items-center justify-content-between">
    Flex utilities
</div>

<!-- Text -->
<p bs-text="center primary">Centered primary text</p>
<p bs-text="end muted">Right-aligned muted text</p>

<!-- Background -->
<div bs-bg="primary" bs-text="white">Primary background</div>

<!-- Border -->
<div bs-border="true" bs-rounded="true">Bordered and rounded</div>
<div bs-border="primary" bs-rounded="pill">Primary border, pill shape</div>

<!-- Shadow -->
<div bs-shadow="lg">Large shadow</div>

Toasts

<div bs-toast bs-autohide="true" bs-delay="3000">
    <div class="toast-header">
        <strong class="me-auto">Bootstrap</strong>
        <small>11 mins ago</small>
        <button bs-close bs-dismiss="toast"></button>
    </div>
    <div class="toast-body">
        Hello, world! This is a toast message.
    </div>
</div>

Accordion

<div bs-accordion id="accordionExample">
    <div class="accordion-item">
        <h2 class="accordion-header">
            <button class="accordion-button" type="button" data-bs-toggle="collapse" 
                    data-bs-target="#collapseOne">
                Accordion Item #1
            </button>
        </h2>
        <div bs-collapse bs-show="true" id="collapseOne" bs-parent="#accordionExample">
            <div class="accordion-body">
                Content for item 1
            </div>
        </div>
    </div>
</div>

Carousel

<div bs-carousel bs-fade="false" bs-ride="carousel" id="carouselExample">
    <div class="carousel-inner">
        <div class="carousel-item active">
            <img src="..." class="d-block w-100" alt="...">
        </div>
        <div class="carousel-item">
            <img src="..." class="d-block w-100" alt="...">
        </div>
    </div>
    <button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" 
            data-bs-slide="prev">
        <span class="carousel-control-prev-icon"></span>
    </button>
    <button class="carousel-control-next" type="button" data-bs-target="#carouselExample" 
            data-bs-slide="next">
        <span class="carousel-control-next-icon"></span>
    </button>
</div>

Enums and Types

Anbth uses strongly-typed enums for better IntelliSense and type safety:

  • BootstrapVariant: None, Primary, Secondary, Success, Danger, Warning, Info, Light, Dark, Link, Body, Muted, White, Black50
  • BootstrapSize: Default, Small, Large, ExtraSmall
  • Placement: Auto, Top, Bottom, Left, Right, TopStart, TopEnd, BottomStart, BottomEnd, LeftStart, LeftEnd, RightStart, RightEnd
  • BootstrapTheme: Auto, Light, Dark
  • Display: None, Inline, InlineBlock, Block, Grid, InlineGrid, Table, TableCell, TableRow, Flex, InlineFlex, Hidden
  • TextAlignment: None, Start, Center, End

Auto-ID Generation

Components that require IDs (modals, offcanvas, collapse, etc.) will automatically generate unique IDs in the format anbth-{guid} if no ID is provided.

<!-- ID will be auto-generated -->
<div bs-modal>
    <!-- ... -->
</div>

<!-- Custom ID -->
<div bs-modal id="myCustomModal">
    <!-- ... -->
</div>

Theming

To use Bootstrap's theme system, add the data-bs-theme attribute to your HTML or body tag:

<html lang="en" data-bs-theme="dark">
<!-- or -->
<html lang="en" data-bs-theme="light">

Building and Packing

Build the Project

dotnet build src/Anbth/Anbth.csproj

Note: The build process automatically runs CSharpier to format all C# files before compilation. This ensures consistent code formatting across the project.

Create NuGet Package

dotnet pack src/Anbth/Anbth.csproj -c Release

The package will be created in src/Anbth/bin/Release/.

Code Formatting

The project uses CSharpier for automatic code formatting.

Automatic Formatting on Build: CSharpier runs automatically on every build via an MSBuild task defined in the project file.

Pre-Commit Hook: A Git pre-commit hook automatically formats code before committing.

Setup for Linux/macOS/Git Bash:

git config core.hooksPath .githooks
chmod +x .githooks/pre-commit

Setup for Windows (Command Prompt):

git config core.hooksPath .githooks
copy .githooks\pre-commit.bat .githooks\pre-commit

Setup for Windows (PowerShell):

git config core.hooksPath .githooks
Copy-Item .githooks/pre-commit.ps1 .githooks/pre-commit -Force

The hook will:

  1. Check if any C# files need formatting
  2. Run CSharpier if needed
  3. Re-stage formatted files
  4. Continue with the commit

See .githooks/README.md for detailed setup instructions for your platform.

Manual Formatting:

dotnet tool restore
dotnet csharpier format .

Format Check (Validation Only):

dotnet csharpier check .

Configuration is in .csharpierrc.json at the repository root.

Note: The csharpier check command validates formatting without making changes, while csharpier format applies formatting changes to files.

EditorConfig

The project includes a comprehensive .editorconfig file with:

  • C# Coding Conventions: var preferences, expression-bodied members, pattern matching, null-checking
  • Code Style Rules: File-scoped namespaces, primary constructors, using directives placement
  • Formatting Rules: Indentation, spacing, new lines, wrapping
  • Naming Conventions: PascalCase for types, camelCase with underscore for private fields, interfaces with 'I' prefix
  • Analyzer Rules: All configured for warnings/suggestions

IDE support ensures consistent code style across the team.

Requirements

  • .NET 10 or later
  • Bootstrap 5.3.8 CSS and JavaScript

Component Coverage

Anbth provides tag helpers for all Bootstrap 5.3.8 components with hybrid/dual syntax support:

Hybrid Components with Custom Tags (support both <component> tags AND bs-* attributes):

  • Alert (<alert> or bs-alert on div/section/article/aside)
  • Badge (<badge> or bs-badge on span/a)
  • Input Group (<input-group> or bs-input-group)
  • Button Group (<button-group> or bs-btn-group)
  • Card (<card> or bs-card)
  • Dropdown (<dropdown> or bs-dropdown)
  • Collapse (<collapse> or bs-collapse)
  • List Group (<list-group> or bs-list-group)

Components with Custom Tags and Sub-Tags:

  • Modal (<modal> with <modal-header>, <modal-body>, <modal-footer>, <modal-title>)
  • Offcanvas (<offcanvas> with <offcanvas-header>, <offcanvas-body>, <offcanvas-title>)
  • Accordion (<accordion> with <accordion-item>)
  • Carousel (<carousel> with <carousel-item>)
  • Toast (<toast> with <toast-header>, <toast-body>)

Grid System (Hybrid approach - custom tags for divs, attributes for semantic HTML):

  • Container (<container>, <container-fluid>, <container-sm/md/lg/xl/xxl> or bs-container* attributes)
  • Row (<row> or bs-row)
  • Column (<col> or bs-col with responsive breakpoints)

Attribute-Based Components:

  • Buttons, Breadcrumbs, Close Button, Navs & Tabs, Navbar, Pagination, Placeholders, Progress, Spinners
  • Auto-Initializing: Tooltips, Popovers (with JavaScript injection and no-init option)

Forms: Form Controls, Select, Checkboxes, Radios, Switches, Floating Labels, Input Groups, Validation, Range, File Input

Utilities: Spacing (Margin/Padding), Display, Flex, Text, Background, Border, Rounding, Shadows

CI/CD Pipelines

Anbth includes automated GitHub Actions workflows with comprehensive testing, security scanning, and dependency management:

  • Build and Test - Runs on every push and PR to validate code

    • Executes all unit tests (223 tests covering major components)
    • Collects code coverage metrics using Coverlet
    • Generates coverage reports with ReportGenerator
    • Publishes coverage summary as PR comment
    • Uploads detailed HTML coverage reports as artifacts
  • CodeQL Security Analysis - Automated security vulnerability scanning

    • Runs on push to main/develop branches
    • Runs on all pull requests to main
    • Weekly scheduled scans (every Monday at 9:00 AM UTC)
    • Uses security-extended and security-and-quality query suites
    • Uploads results to GitHub Security tab
  • Dependabot - Automated dependency updates

    • Checks for NuGet package updates monthly
    • Checks for GitHub Actions updates monthly
    • Automatically creates pull requests for updates
    • Configured with reviewers and labels
  • Package - Creates NuGet packages on PR with version detection

    • Version extracted from PR title [vX.Y.Z] or auto-incremented
    • Label-based suffix: -alpha or -preview based on PR labels
    • Runs tests with coverage collection
    • Only packages if:
      • Main branch (always)
      • Non-main branch with alpha or preview label
  • Release - Creates GitHub release and publishes package on merge

    • Creates git tags
    • Generates release notes
    • Publishes to GitHub Packages
    • Marks as pre-release for preview/alpha versions

Code Coverage

The project maintains comprehensive test coverage:

  • 91+ Unit Tests covering all major tag helpers
  • Coverage Reports automatically generated on each PR
  • Detailed Metrics for line, branch, and complexity coverage
  • Historical Tracking of coverage trends

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Links

Author

schivei


Made with ❤️ for the ASP.NET Core community

About

ASP.NET Bootstrap Tag Helpers

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 2

  •  
  •  

Languages