uAdvancedButton 1.0.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package uAdvancedButton --version 1.0.2
                    
NuGet\Install-Package uAdvancedButton -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="uAdvancedButton" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="uAdvancedButton" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="uAdvancedButton" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add uAdvancedButton --version 1.0.2
                    
#r "nuget: uAdvancedButton, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package uAdvancedButton@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=uAdvancedButton&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=uAdvancedButton&version=1.0.2
                    
Install as a Cake Tool

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

  1. Open the Umbraco backoffice
  2. Go to Settings > Document Types and select your document type (e.g. HomePage)
  3. Add a new property of type Block List
  4. 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)
  5. Save the document type

Step 3: Add buttons in the Content section

  1. Go to Content and edit a page that uses your document type
  2. Click Add on your Block List property
  3. Select UAB Advanced Button or UAB Button Group
  4. 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.

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> — use hasLink && !isDisabled && !isDropdown to decide the tag
  • Always include <span class="uab-caret"> inside dropdown buttons for the visual arrow indicator
  • Use uab-icon-left / uab-icon-right CSS classes on icon <img> elements for proper spacing
  • Include data-scroll-to on <button> elements too (not just <a>) so scroll-to-anchor works without a link
  • Always use Html.Encode() for user-provided attribute values and Html.Raw() for the conditional attribute wrappers

Step 5: Dropdown Setup

  1. Edit your UAB Advanced Button in the backoffice
  2. Go to the Dropdown tab
  3. Toggle Enable Dropdown to ON
  4. Under Dropdown Items, click Add and select UAB Dropdown Item
  5. Fill in the label, link (internal or external), and optional icon
  6. 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.


🤝 Support

For support, feature requests, or bug reports:

📄 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 97 5/29/2026
1.0.3 94 5/26/2026
1.0.2 97 5/5/2026
1.0.1 124 2/23/2026
1.0.0 127 2/13/2026