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.
- ✅ 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
Install via NuGet Package Manager:
dotnet add package AnbthOr via Package Manager Console:
Install-Package AnbthAdd 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>Add to your _ViewImports.cshtml:
@addTagHelper *, Anbth<!-- 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>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 buttonfade/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
<!-- 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 helperbs-variant- Button colorbs-size- Size (Small, Default, Large)bs-outline- Outline stylebs-disabled- Disabled statebs-active- Active statebs-block- Full width
Anbth provides two ways to work with Bootstrap's grid system:
<!-- 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 sizesoffset- Column offsetorder- Column orderid- Column ID
<!-- 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 rowbs-gutter- Gutter sizebs-col- Activates column with sizebs-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.)
<!-- 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 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><!-- 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><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><input bs-range min="0" max="100" value="50" />Anbth provides two ways to use modals:
<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
<!-- 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 centerscrollable/bs-scrollable- Make body scrollablefullscreen/bs-fullscreen- Fullscreen modalbackdrop/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 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
<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 scrollbackdrop/bs-backdrop- Show backdropkeyboard/bs-keyboard- Close on ESC
<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- Containerbs-dropdown-toggle- Toggle buttonbs-direction- Direction (down, up, start, end)bs-auto-close- Auto close behavior
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 textbs-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-initializationbs-popover-title- Popover title (popover only)
<!-- 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><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><!-- 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><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><!-- 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><!-- 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 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 stylingid- Custom ID
Supported Elements:
- Custom tag:
<badge>(renders as<span>) - Attributes:
span,a
<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>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><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><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><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>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
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>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">dotnet build src/Anbth/Anbth.csprojNote: The build process automatically runs CSharpier to format all C# files before compilation. This ensures consistent code formatting across the project.
dotnet pack src/Anbth/Anbth.csproj -c ReleaseThe package will be created in src/Anbth/bin/Release/.
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-commitSetup for Windows (Command Prompt):
git config core.hooksPath .githooks
copy .githooks\pre-commit.bat .githooks\pre-commitSetup for Windows (PowerShell):
git config core.hooksPath .githooks
Copy-Item .githooks/pre-commit.ps1 .githooks/pre-commit -ForceThe hook will:
- Check if any C# files need formatting
- Run CSharpier if needed
- Re-stage formatted files
- 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.
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.
- .NET 10 or later
- Bootstrap 5.3.8 CSS and JavaScript
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>orbs-alerton div/section/article/aside) - Badge (
<badge>orbs-badgeon span/a) - Input Group (
<input-group>orbs-input-group) - Button Group (
<button-group>orbs-btn-group) - Card (
<card>orbs-card) - Dropdown (
<dropdown>orbs-dropdown) - Collapse (
<collapse>orbs-collapse) - List Group (
<list-group>orbs-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>orbs-container*attributes) - Row (
<row>orbs-row) - Column (
<col>orbs-colwith 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-initoption)
✅ 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
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:
-alphaor-previewbased on PR labels - Runs tests with coverage collection
- Only packages if:
- Main branch (always)
- Non-main branch with
alphaorpreviewlabel
- Version extracted from PR title
-
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
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
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
schivei
Made with ❤️ for the ASP.NET Core community