uAdvancedButton 1.0.2
See the version list below for details.
dotnet add package uAdvancedButton --version 1.0.2
NuGet\Install-Package uAdvancedButton -Version 1.0.2
<PackageReference Include="uAdvancedButton" Version="1.0.2" />
<PackageVersion Include="uAdvancedButton" Version="1.0.2" />
<PackageReference Include="uAdvancedButton" />
paket add uAdvancedButton --version 1.0.2
#r "nuget: uAdvancedButton, 1.0.2"
#:package uAdvancedButton@1.0.2
#addin nuget:?package=uAdvancedButton&version=1.0.2
#tool nuget:?package=uAdvancedButton&version=1.0.2
uAdvancedButton - Advanced Button & CTA System for Umbraco 17+
Enterprise-level CTA system with advanced buttons, button groups, dropdown menus, analytics hooks, and full accessibility.
Features
- AdvancedButton element type with 30+ configurable properties
- ButtonGroup element type with layout, gap, alignment, and responsive stacking
- Dropdown mode with keyboard navigation and ARIA compliance
- 5 size variants (XS–XL), 6 style variants, 4 rendering modes (Solid, Outline, Ghost, Gradient)
- 6 hover animations (scale, lift, glow, pulse, slide, none)
- Confirmation dialog, loading state, disabled state
- Smooth scroll-to-anchor, modal trigger (custom event)
- Full keyboard accessibility and screen reader support
- Scoped CSS (
uab-prefix), no global pollution - Works in Block Grid, Block List, and as standalone ViewComponent
Installation
dotnet add package uAdvancedButton
On first startup, the package automatically provisions:
- 15+ data types (prefixed
uAB) - 3 element types:
uabAdvancedButton,uabButtonGroup,uabDropdownItem
Setup Guide
Step 1: Add CSS & JS to your layout
In your main layout file (e.g. _Layout.cshtml or Master.cshtml), add the CSS in <head> and the JS before </body>:
<head>
...
<link rel="stylesheet" href="/css/advanced-button.css" />
</head>
<body>
...
<script src="/js/advanced-button.js"></script>
</body>
Step 2: Add Block List to your Document Type
- Open the Umbraco backoffice
- Go to Settings > Document Types and select your document type (e.g.
HomePage) - Add a new property of type Block List
- In the Block List configuration, add the element types:
- UAB Advanced Button — for standalone buttons
- UAB Button Group — for grouped buttons (contains a nested Block List of buttons)
- Save the document type
Step 3: Add buttons in the Content section
- Go to Content and edit a page that uses your document type
- Click Add on your Block List property
- Select UAB Advanced Button or UAB Button Group
- Fill in the button properties:
- Content tab: Label, sub-label, icon, links, ARIA label, analytics
- Behavior tab: Loading state, disabled, confirmation dialog, scroll-to-anchor, modal trigger
- Layout Controls tab: Full width, alignment, spacing
- Style Controls tab: Size, style variant, mode, border radius, shadow, hover animation, custom CSS class
- Dropdown tab: Enable dropdown toggle, add dropdown items
Step 4: Render in your Razor template
You have two options for rendering buttons in your template.
Option A: Use the built-in partial (recommended)
The simplest approach — one line renders everything (buttons, groups, dropdowns):
@using Umbraco.Cms.Core.Models.Blocks
@using Umbraco.Cms.Core.Models.PublishedContent
@using Umbraco.Extensions
@{
IPublishedContent page = Model.Content;
@* Replace "socialMediaButton" with your Block List property alias *@
var buttons = page.Value<BlockListModel>("socialMediaButton");
}
@if (buttons != null)
{
@await Html.PartialAsync("uabRenderButtons", buttons)
}
The uabRenderButtons partial handles both uabAdvancedButton and uabButtonGroup blocks automatically, including nested dropdown items.
Option B: Manual inline rendering (full control)
If you need full control over the HTML, you can render each block manually. Below is a complete working Master.cshtml example:
@using Umbraco.Cms.Core.Models.Blocks
@using Umbraco.Cms.Core.Models.PublishedContent
@using Umbraco.Extensions
@{
IPublishedContent page = Model.Content;
var buttonBlocks = page.Value<IEnumerable<BlockListItem>>("socialMediaButton");
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link href="~/css/advanced-button.css" rel="stylesheet" />
</head>
<body>
@if (buttonBlocks != null && buttonBlocks.Any())
{
<div class="uab-group uab-group-horizontal uab-group-gap-md uab-group-responsive">
@foreach (var block in buttonBlocks)
{
var c = block.Content;
// ── Content ──
var label = c.Value<string>("buttonLabel") ?? "";
var subLabel = c.Value<string>("subLabel") ?? "";
var extLink = c.Value<string>("externalLink") ?? "";
var intLink = c.Value<IPublishedContent>("internalLink");
var intUrl = intLink?.Url() ?? "";
var mediaFile = c.Value<IPublishedContent>("mediaLink");
var mediaUrl = mediaFile?.Url() ?? "";
var anchorId = c.Value<string>("anchorTarget") ?? "";
var iconImg = c.Value<IPublishedContent>("iconMedia");
var iconUrl = iconImg?.Url() ?? "";
var iconPos = c.Value<string>("iconPosition") ?? "left";
var openNewTab = c.Value<bool>("openInNewTab");
var ariaLabel = c.Value<string>("ariaLabel") ?? "";
// ── Analytics ──
var eventName = c.Value<string>("analyticsEventName") ?? "";
var eventPayload = c.Value<string>("analyticsPayload") ?? "";
// ── Behavior ──
var isLoading = c.Value<bool>("loadingState");
var isDisabled = c.Value<bool>("disabledState");
var hasConfirm = c.Value<bool>("confirmationDialog");
var confirmText = c.Value<string>("confirmationText") ?? "Are you sure?";
var scrollTo = c.Value<bool>("scrollToAnchor");
var isModal = c.Value<bool>("modalTrigger");
var modalId = c.Value<string>("modalTargetId") ?? "";
// ── Dropdown ──
var isDropdown = c.Value<bool>("isDropdown");
var dropdownBlocks = c.Value<IEnumerable<BlockListItem>>("dropdownItems");
// ── Style ──
var size = c.Value<string>("sizeVariant") ?? "md";
var style = c.Value<string>("styleVariant") ?? "primary";
var mode = c.Value<string>("modeSelector") ?? "solid";
var radius = c.Value<string>("borderRadius") ?? "md";
var shadow = c.Value<bool>("shadowEnabled");
var hover = c.Value<string>("hoverAnimation") ?? "none";
var customClass = c.Value<string>("customCssClass") ?? "";
var fullWidth = c.Value<bool>("fullWidth");
var alignment = c.Value<string>("alignment") ?? "left";
var spacing = c.Value<string>("spacingPreset") ?? "md";
// ── Resolve URL ──
var url = !string.IsNullOrEmpty(intUrl) ? intUrl
: !string.IsNullOrEmpty(extLink) ? extLink
: !string.IsNullOrEmpty(mediaUrl) ? mediaUrl
: scrollTo && !string.IsNullOrEmpty(anchorId) ? $"#{anchorId}"
: "";
var hasLink = !string.IsNullOrEmpty(url);
// ── Tag: dropdown always renders as <button> ──
var useAnchor = hasLink && !isDisabled && !isDropdown;
// ── Sanitize custom class ──
var safeClass = System.Text.RegularExpressions.Regex.Replace(
customClass, @"[^a-zA-Z0-9\s\-_]", "");
// ── Build CSS classes ──
var cls = $"uab-btn uab-size-{size} uab-style-{style} uab-mode-{mode} uab-radius-{radius}";
if (shadow) { cls += " uab-shadow"; }
if (fullWidth) { cls += " uab-full-width"; }
if (isLoading) { cls += " uab-loading"; }
if (isDisabled){ cls += " uab-disabled"; }
if (hover != "none") { cls += $" uab-hover-{hover}"; }
if (isDropdown){ cls += " uab-dropdown-trigger"; }
if (!string.IsNullOrEmpty(safeClass)) { cls += $" {safeClass}"; }
var wrapperCls = $"uab-wrapper uab-align-{alignment} uab-spacing-{spacing}";
var isIconOnly = iconPos == "icon-only";
<div class="@wrapperCls">
@if (useAnchor)
{
<a href="@url"
class="@cls"
@Html.Raw(openNewTab ? "target=\"_blank\" rel=\"noopener noreferrer\"" : "")
@Html.Raw(!string.IsNullOrEmpty(ariaLabel) ? $"aria-label=\"{Html.Encode(ariaLabel)}\"" : "")
@Html.Raw(!string.IsNullOrEmpty(eventName) ? $"data-event=\"{Html.Encode(eventName)}\"" : "")
@Html.Raw(!string.IsNullOrEmpty(eventPayload) ? $"data-payload='{Html.Encode(eventPayload)}'" : "")
@Html.Raw(hasConfirm ? $"data-confirm=\"{Html.Encode(confirmText)}\"" : "")
@Html.Raw(scrollTo && !string.IsNullOrEmpty(anchorId) ? $"data-scroll-to=\"{Html.Encode(anchorId)}\"" : "")
@Html.Raw(isModal && !string.IsNullOrEmpty(modalId) ? $"data-modal-target=\"{Html.Encode(modalId)}\"" : "")>
@if (isLoading)
{
<span class="uab-spinner" aria-hidden="true"></span>
<span class="uab-sr-only">Loading...</span>
}
else
{
@if (!string.IsNullOrEmpty(iconUrl) && (iconPos == "left" || isIconOnly))
{
<img src="@iconUrl" alt="" class="uab-icon uab-icon-left" loading="lazy" aria-hidden="true" />
}
@if (!isIconOnly)
{
<span class="uab-label">@label</span>
@if (!string.IsNullOrEmpty(subLabel))
{
<span class="uab-sub-label">@subLabel</span>
}
}
@if (!string.IsNullOrEmpty(iconUrl) && iconPos == "right")
{
<img src="@iconUrl" alt="" class="uab-icon uab-icon-right" loading="lazy" aria-hidden="true" />
}
}
</a>
}
else
{
<button type="button"
class="@cls"
@Html.Raw(isDisabled ? "disabled aria-disabled=\"true\"" : "")
@Html.Raw(!string.IsNullOrEmpty(ariaLabel) ? $"aria-label=\"{Html.Encode(ariaLabel)}\"" : "")
@Html.Raw(!string.IsNullOrEmpty(eventName) ? $"data-event=\"{Html.Encode(eventName)}\"" : "")
@Html.Raw(!string.IsNullOrEmpty(eventPayload) ? $"data-payload='{Html.Encode(eventPayload)}'" : "")
@Html.Raw(hasConfirm ? $"data-confirm=\"{Html.Encode(confirmText)}\"" : "")
@Html.Raw(scrollTo && !string.IsNullOrEmpty(anchorId) ? $"data-scroll-to=\"{Html.Encode(anchorId)}\"" : "")
@Html.Raw(isModal && !string.IsNullOrEmpty(modalId) ? $"data-modal-target=\"{Html.Encode(modalId)}\"" : "")
@Html.Raw(isDropdown ? "aria-haspopup=\"true\" aria-expanded=\"false\"" : "")>
@if (isLoading)
{
<span class="uab-spinner" aria-hidden="true"></span>
<span class="uab-sr-only">Loading...</span>
}
else
{
@if (!string.IsNullOrEmpty(iconUrl) && (iconPos == "left" || isIconOnly))
{
<img src="@iconUrl" alt="" class="uab-icon uab-icon-left" loading="lazy" aria-hidden="true" />
}
@if (!isIconOnly)
{
<span class="uab-label">@label</span>
@if (!string.IsNullOrEmpty(subLabel))
{
<span class="uab-sub-label">@subLabel</span>
}
}
@if (!string.IsNullOrEmpty(iconUrl) && iconPos == "right")
{
<img src="@iconUrl" alt="" class="uab-icon uab-icon-right" loading="lazy" aria-hidden="true" />
}
@if (isDropdown)
{
<span class="uab-caret" aria-hidden="true"></span>
}
}
</button>
}
@* ── Dropdown Menu ── *@
@if (isDropdown && dropdownBlocks != null && dropdownBlocks.Any())
{
<ul class="uab-dropdown-menu" role="menu" aria-hidden="true">
@foreach (var ddBlock in dropdownBlocks)
{
var dd = ddBlock.Content;
var ddLabel = dd.Value<string>("label") ?? "";
var ddExtLink = dd.Value<string>("externalLink") ?? "";
var ddIntLink = dd.Value<IPublishedContent>("internalLink");
var ddUrl = ddIntLink?.Url() ?? ddExtLink;
var ddIcon = dd.Value<IPublishedContent>("iconMedia");
var ddIconUrl = ddIcon?.Url() ?? "";
<li role="none">
<a href="@(string.IsNullOrEmpty(ddUrl) ? "#" : ddUrl)"
class="uab-dropdown-item" role="menuitem" tabindex="-1">
@if (!string.IsNullOrEmpty(ddIconUrl))
{
<img src="@ddIconUrl" alt="" class="uab-dropdown-icon" loading="lazy" />
}
<span>@Html.Encode(ddLabel)</span>
</a>
</li>
}
</ul>
}
</div>
}
</div>
}
<script src="~/js/advanced-button.js"></script>
</body>
</html>
Key rules for manual rendering:
- Dropdown buttons must render as
<button>, never<a>— usehasLink && !isDisabled && !isDropdownto decide the tag- Always include
<span class="uab-caret">inside dropdown buttons for the visual arrow indicator- Use
uab-icon-left/uab-icon-rightCSS classes on icon<img>elements for proper spacing- Include
data-scroll-toon<button>elements too (not just<a>) so scroll-to-anchor works without a link- Always use
Html.Encode()for user-provided attribute values andHtml.Raw()for the conditional attribute wrappers
Step 5: Dropdown Setup
- Edit your UAB Advanced Button in the backoffice
- Go to the Dropdown tab
- Toggle Enable Dropdown to ON
- Under Dropdown Items, click Add and select UAB Dropdown Item
- Fill in the label, link (internal or external), and optional icon
- Save and publish
The dropdown renders a <button> with aria-haspopup, aria-expanded, and a <ul> menu with full keyboard navigation (Arrow keys, Home, End, Escape, Tab).
Element Types & Property Aliases
uabAdvancedButton
| Group | Alias | Type | Description |
|---|---|---|---|
| Content | buttonLabel |
Text | Main button text (required) |
| Content | subLabel |
Text | Secondary text below label |
| Content | iconMedia |
Media Picker | SVG or image icon |
| Content | iconPosition |
Dropdown | left, right, icon-only |
| Content | internalLink |
Content Picker | Link to Umbraco page |
| Content | externalLink |
Text | External URL |
| Content | mediaLink |
Media Picker | Link to media file |
| Content | anchorTarget |
Text | Anchor ID (without #) |
| Content | openInNewTab |
Toggle | Open in new tab |
| Content | ariaLabel |
Text | Screen reader label |
| Content | analyticsEventName |
Text | Analytics event name |
| Content | analyticsPayload |
TextArea | Analytics JSON payload |
| Behavior | loadingState |
Toggle | Show spinner |
| Behavior | disabledState |
Toggle | Disable button |
| Behavior | confirmationDialog |
Toggle | Confirm before action |
| Behavior | confirmationText |
Text | Confirmation message |
| Behavior | scrollToAnchor |
Toggle | Smooth scroll on click |
| Behavior | modalTrigger |
Toggle | Trigger modal on click |
| Behavior | modalTargetId |
Text | Target modal element ID |
| Layout | fullWidth |
Toggle | 100% width |
| Layout | alignment |
Dropdown | left, center, right |
| Layout | spacingPreset |
Dropdown | none, xs, sm, md, lg, xl |
| Style | sizeVariant |
Dropdown | xs, sm, md, lg, xl |
| Style | styleVariant |
Dropdown | primary, secondary, success, danger, neutral, custom |
| Style | modeSelector |
Dropdown | solid, outline, ghost, gradient |
| Style | borderRadius |
Dropdown | none, sm, md, lg, xl, full |
| Style | shadowEnabled |
Toggle | Drop shadow |
| Style | hoverAnimation |
Dropdown | none, scale, lift, glow, pulse, slide |
| Style | customCssClass |
Text | Extra CSS class |
| Dropdown | isDropdown |
Toggle | Enable dropdown mode |
| Dropdown | dropdownItems |
Block List | Dropdown menu items |
uabDropdownItem
| Alias | Type | Description |
|---|---|---|
label |
Text | Item label |
internalLink |
Content Picker | Internal page link |
externalLink |
Text | External URL |
iconMedia |
Media Picker | Optional icon |
uabButtonGroup
| Group | Alias | Type | Description |
|---|---|---|---|
| Buttons | buttons |
Block List | Nested Advanced Buttons |
| Layout | groupLayout |
Dropdown | horizontal, vertical |
| Layout | wrapEnabled |
Toggle | Allow wrapping |
| Layout | equalWidth |
Toggle | Equal-width buttons |
| Layout | gapSize |
Dropdown | none, xs, sm, md, lg, xl |
| Layout | groupAlignment |
Dropdown | left, center, right |
| Layout | responsiveStacking |
Toggle | Stack on mobile |
Shipped Files
On build, the .targets file copies package assets into two locations in the consumer project:
| File | Copied to (project root) | Also copied to (App_Plugins mirror) |
|---|---|---|
AdvancedButton.cshtml |
Views/Partials/ |
App_Plugins/uAdvancedButton/content/Views/Partials/ |
_ButtonInner.cshtml |
Views/Partials/ |
App_Plugins/uAdvancedButton/content/Views/Partials/ |
ButtonGroup.cshtml |
Views/Partials/ |
App_Plugins/uAdvancedButton/content/Views/Partials/ |
uabRenderButtons.cshtml |
Views/Partials/ |
App_Plugins/uAdvancedButton/content/Views/Partials/ |
Error.cshtml |
Views/Partials/ |
App_Plugins/uAdvancedButton/content/Views/Partials/ |
NoContent.cshtml |
Views/Partials/ |
App_Plugins/uAdvancedButton/content/Views/Partials/ |
advanced-button.css |
wwwroot/css/ |
App_Plugins/uAdvancedButton/content/wwwroot/css/ |
advanced-button.js |
wwwroot/js/ |
App_Plugins/uAdvancedButton/content/wwwroot/js/ |
On dotnet clean, the App_Plugins directory and wwwroot/css/advanced-button.css + wwwroot/js/advanced-button.js are removed.
Analytics Integration
The package outputs data-event and data-payload attributes on buttons. No tracking library is bundled — attach your own listener:
document.addEventListener("uab:analytics", function (e) {
// e.detail.event — the event name from "analyticsEventName"
// e.detail.payload — parsed JSON from "analyticsPayload"
gtag("event", e.detail.event, e.detail.payload);
});
Requirements
- Umbraco 17.1.0+
- .NET 10.0
License
MIT — © 2026 Atharva IT Services Pvt. Ltd.
Links
🤝 Support
For support, feature requests, or bug reports:
- Website: https://www.atharvaits.com
- Email: contact@atharvaits.com
- Company: Atharva IT Services Pvt. Ltd.
📄 License
Copyright © Atharva IT Services Pvt. Ltd.
This package is free to use for the Umbraco community.
🏢 About Atharva IT Services
Atharva IT Services Pvt. Ltd. a global software development company in Ahmedabad, excels in e-commerce solutions, web development, and software testing.
Made with ❤️ by Atharva IT Services
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Umbraco.Cms.Infrastructure (>= 17.1.0)
- Umbraco.Cms.Web.Common (>= 17.1.0)
- Umbraco.Cms.Web.Website (>= 17.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.