check_circle v1.0.0-mvp Last Updated: June 2026

bzr-dial.ui Docs

A physics-based radial dial menu web component. Zero dependencies. 60 FPS. Shadow DOM encapsulated. Built by Web Works Systems.

rocket_launch Quick Start

Step 1 Include the component script
<script src="/demo/bzr-dial-menu.js"></script>
Step 2 Add the component to your HTML
<bzr-dial-menu>
    <bzr-item label="Home" icon="/icons/home.svg" href="#home"></bzr-item>
    <bzr-item label="Settings" icon="/icons/settings.svg" href="#settings"></bzr-item>
    <bzr-item label="Profile" icon="/icons/profile.svg" href="#profile"></bzr-item>
</bzr-dial-menu>
Step 3 That's it. The dial auto-mounts to the viewport edge.

No build step. No npm install. No framework dependency. The component registers two custom elements: <bzr-dial-menu> and <bzr-item>.

download Installation

CDN (Demo / Unlicensed)

<script src="https://czarui.game4real.us/demo/bzr-dial-menu.js"></script>

Includes a visible "UNLICENSED" watermark badge. For evaluation only.

Licensed Download

<script src="/component/bzr-dial-menu.js"></script>

Requires a valid license key. Purchase at bzzrr.link.

Self-Hosted

# Download and serve from your own domain
<script src="/your-path/bzr-dial-menu.js"></script>

# Or use as an ES module (future — see Coming Soon section)

tune <bzr-dial-menu> Attributes

Attribute Type Default Status Description
radius Number 120 Active Radius of the dial circle in pixels
justify String right Active FAB position: left or right
top String 50% Active Vertical position of FAB (e.g. 200px)
bottom String Active Bottom position override (mutually exclusive with top)
anchor String auto Active Active slot anchor: left, right, top, bottom. Auto-derives from justify.
license String Active License key (format: BZRD-XXXX-XXXX-XXXX-XXXX). Removes watermark.
demo Flag Active Marks component as demo (used on landing page)
snap String auto Planned Observed but not yet handled. Currently auto-calculated as 2π/item count.
sensitivity String Planned Drag sensitivity control. Reserved for future use.

widgets <bzr-item> Attributes

Attribute Type Required Status Description
label String Yes Active Display name shown when item is active
icon URL No Active Path or URL to icon image (SVG, PNG). Shows placeholder if absent.
href URL No Active Navigation URL — triggered when active item is clicked
active Flag No Active Set automatically by the dial when an item reaches the active slot

perm_media Inline Content Attributes

Display rich media and interactive content in a modal overlay instead of navigating away. Content attributes take priority over href.

music_note data-audio
Active

Audio player with WebAudio visualizer (80 radial bars, FFT 256) and custom media controls.

<bzr-item label="Podcast" icon="music.svg"
    data-audio="episode.mp3"
    data-autoplay>
</bzr-item>
videocam data-video
Active

Video player with canvas frame-copy render loop and aspect-ratio-aware fitting.

<bzr-item label="Tutorial" icon="video.svg"
    data-video="tutorial.mp4">
</bzr-item>
image data-image
Active

Image viewer with contain-fit and max-height 70vh.

<bzr-item label="Gallery" icon="gallery.svg"
    data-image="photo.png">
</bzr-item>
mail data-email
Active

Contact form (to/subject/message) that opens a mailto: link on submit.

<bzr-item label="Contact" icon="email.svg"
    data-email="hello@example.com">
</bzr-item>
call data-phone
Active

Phone card with large number display and tel: call button.

<bzr-item label="Call Us" icon="phone.svg"
    data-phone="+1-555-123-4567">
</bzr-item>
map data-map
Active

OpenStreetMap embed via Leaflet + Nominatim geocoding. Lazily loads Leaflet CSS/JS.

<bzr-item label="Location" icon="map.svg"
    data-map="Eiffel Tower, Paris">
</bzr-item>
web data-iframe
Active

Embed any external website in an iframe overlay.

<bzr-item label="Docs" icon="web.svg"
    data-iframe="https://docs.example.com">
</bzr-item>
play_circle data-autoplay
Active

Optional flag — auto-plays audio/video when the content modal opens. Works with data-audio and data-video only.

palette CSS Custom Properties

Override these CSS variables on the bzr-dial-menu host element to customize the theme.

bzr-dial-menu {
    --primary: #2bee8c;          /* Primary color: active items, glow, FAB */
    --bg: #111;                   /* Background color */
    --text: #fff;                 /* Text color */
    --trigger-size: 80px;         /* FAB button diameter */
    --trigger-inset: 20px;        /* FAB inset from viewport edge */
}

Custom Theme Example

<style>
    #custom-dial {
        --primary: #ff6b6b;   /* Red theme */
        --bg: #2c3e50;
        --text: #ecf0f1;
        --trigger-size: 60px;  /* Smaller FAB */
    }
</style>

<bzr-dial-menu id="custom-dial" radius="150" justify="right">
    <div slot="trigger-content" style="font-size:28px; font-weight:bold;">⚡</div>
    <bzr-item label="Dashboard" icon="dashboard.svg" href="/dashboard"></bzr-item>
    <bzr-item label="Analytics" icon="chart.svg" href="/analytics"></bzr-item>
</bzr-dial-menu>

bolt Events

bzr-change Active

Fired when the active item changes (an item rotates into the active slot).

Event Detail
{
    index: Number,      // Index of the active item (0-based)
    item: HTMLElement    // The bzr-item element
}
const dial = document.querySelector('bzr-dial-menu');

dial.addEventListener('bzr-change', (event) => {
    const { index, item } = event.detail;
    const label = item.getAttribute('label');
    console.log(`Active item: ${label} (index: ${index})`);

    // Track analytics
    analytics.track('dial_item_selected', { item: label });
});

code JavaScript API

Properties

Property Type Description
dial.isOpenBooleanIs the dial currently open?
dial.rotationNumberCurrent rotation in radians
dial.activeIndexNumberIndex of active item (0-based)
dial.itemsArrayArray of all slotted bzr-item elements
dial.radiusNumberDial radius in pixels

Methods

const dial = document.querySelector('bzr-dial-menu');

// Toggle open/close
dial.toggle();

// Programmatically open/close
dial.isOpen = true;   // Open
dial.isOpen = false;  // Close

Dynamic Item Management

// Add items dynamically
const newItem = document.createElement('bzr-item');
newItem.setAttribute('label', 'New Item');
newItem.setAttribute('icon', 'new-icon.svg');
newItem.setAttribute('href', '#new');
dial.appendChild(newItem);

// Remove items
const items = dial.querySelectorAll('bzr-item');
items[2].remove(); // Remove third item

// Update item attributes
const item = dial.querySelector('bzr-item[label="Home"]');
item.setAttribute('label', 'Dashboard');
item.setAttribute('icon', 'dashboard.svg');

The slotchange event auto-triggers updateItems() when children change.

Custom Trigger Content

Use the trigger-content slot to customize the FAB button:

<bzr-dial-menu>
    <!-- Custom trigger -->
    <div slot="trigger-content" style="font-size:24px;">☰</div>

    <!-- Items -->
    <bzr-item label="Home" icon="home.svg"></bzr-item>
</bzr-dial-menu>

touch_app Interaction Guide

click Open / Close

Single click the FAB button to toggle the dial open/closed.

rotate_right Rotate Dial

Drag anywhere on the overlay — outer ring, icons, or inner ring area. Rotation pivots around the FAB center.

swap_vert Quick Navigate

Swipe up/down on any icon to snap to the next/previous item. 10px threshold locks the direction.

touch_app Select Item

Click the active (highlighted) item to trigger its action — navigate to href or open inline content.

drag_indicator Slide Mode

Double-click the FAB to enable slide mode. Drag vertically to reposition the FAB along the viewport edge. Click backdrop to exit.

vibration Haptic Feedback

Vibration API feedback on snap, slide-mode toggle, and item activation (mobile only).

Physics Model

Friction
0.985
Spring
0.1
Snap
2π / N
Target Lerp
0.15

Inertial scrolling with velocity decay, spring-snapping to slot positions, and a target-rotation lerp for programmatic navigation. The rAF loop runs continuously at 60 FPS.

collections Examples

Navigation Menu

<bzr-dial-menu justify="right">
    <div slot="trigger-content">☰</div>
    <bzr-item label="Home" icon="home.svg" href="/"></bzr-item>
    <bzr-item label="About" icon="info.svg" href="/about"></bzr-item>
    <bzr-item label="Services" icon="services.svg" href="/services"></bzr-item>
    <bzr-item label="Contact" icon="contact.svg" href="/contact"></bzr-item>
</bzr-dial-menu>

App Actions with Event Handling

<bzr-dial-menu radius="150" justify="left">
    <div slot="trigger-content">+</div>
    <bzr-item label="New Post" icon="edit.svg"></bzr-item>
    <bzr-item label="Upload Photo" icon="camera.svg"></bzr-item>
    <bzr-item label="Create Event" icon="calendar.svg"></bzr-item>
    <bzr-item label="Start Chat" icon="message.svg"></bzr-item>
</bzr-dial-menu>

<script>
    const dial = document.querySelector('bzr-dial-menu');
    dial.addEventListener('bzr-change', (e) => {
        const label = e.detail.item.getAttribute('label');
        switch(label) {
            case 'New Post': openPostEditor(); break;
            case 'Upload Photo': openPhotoUploader(); break;
        }
    });
</script>

Media Showcase

<bzr-dial-menu justify="right" radius="140">
    <bzr-item label="Music" icon="music.svg"
        data-audio="track.mp3" data-autoplay></bzr-item>
    <bzr-item label="Video" icon="video.svg"
        data-video="demo.mp4"></bzr-item>
    <bzr-item label="Gallery" icon="image.svg"
        data-image="photo.jpg"></bzr-item>
    <bzr-item label="Map" icon="map.svg"
        data-map="350 Fifth Avenue, New York"></bzr-item>
</bzr-dial-menu>

Using Iconify Icons

<bzr-dial-menu>
    <bzr-item label="Home"
        icon="https://api.iconify.design/mdi:home.svg?color=%23ffffff"></bzr-item>
    <bzr-item label="Search"
        icon="https://api.iconify.design/mdi:magnify.svg?color=%23ffffff"></bzr-item>
    <bzr-item label="Settings"
        icon="https://api.iconify.design/mdi:cog.svg?color=%23ffffff"></bzr-item>
</bzr-dial-menu>
schedule

Coming Soon

The following features are planned for future releases. Attributes may be observed but not yet functional, or methods are stubbed with TODOs. These will be activated in upcoming versions.

straighten snap
Planned

Custom snap angle control. Currently auto-calculated as 2π/item count. Will allow manual override (e.g. 30deg) for half-dial and custom layouts.

tune sensitivity
Planned

Adjustable drag sensitivity multiplier. Will control how much physical drag translates to rotational movement. Currently fixed at 1:1 with a 5px movement threshold.

vibration Snap Feedback Audio
Stub

Sophisticated tick/haptic feedback on snap. The checkSnapFeedback() method exists as a TODO stub — will produce audio ticks and refined vibration patterns when crossing slot boundaries.

dialpad Inner Jog Dial
Reserved

Secondary inner-ring jog dial for fine-grained navigation. The drawInnerControls() method is reserved — currently empty to keep the icon path clean.

accessibility Keyboard & A11y
Planned

Focus management, keyboard navigation (arrow keys for rotation, Enter to select), ARIA roles, and focus trapping within the dial overlay. Not yet implemented.

verified_user Server License Check
Planned

Server-side license validation. Currently format-only regex check (BZRD-XXXX-XXXX-XXXX-XXXX). Will validate against the Web Works Systems license server.

label Active Label Overlay
In Progress

The #active-label element exists in the template and CSS but the label text is not yet populated at runtime. Will display the active item's label prominently at the bottom of the viewport.

fullscreen Fullscreen Media Mode
Planned

CSS class fullscreen-mode is defined for the content container but not yet applied by JS. Will allow video/image content to expand to full viewport.

picture_as_pdf data-pdf
Roadmap

Inline PDF viewer attribute. Will render PDFs in the content overlay modal with page navigation controls.

photo_library Image Gallery
Roadmap

Lightbox-style image gallery mode. Will support multiple images with swipe navigation, zoom, and captions.

calendar_month Calendar / Date Picker
Roadmap

Inline calendar/date picker interface accessible from a dial item. Will integrate with form workflows.

dynamic_form Form Builder
Roadmap

Declarative form configuration via data attributes. Will render custom forms in the content overlay with field types, validation, and submission.

public Browser Support

Chrome / Edge
Latest
Firefox
Latest
Safari
Latest
Mobile Browsers
iOS Safari, Chrome Mobile

Requirements

  • check Custom Elements v1 (Web Components)
  • check Shadow DOM
  • check ES6 JavaScript
  • check Canvas 2D API
  • check Pointer / Touch Events

build Troubleshooting

Icons not showing?

  • Verify icon URLs resolve (check Network tab for 404s)
  • Ensure icon files have correct permissions (644, www-data readable)
  • Check CORS headers if loading icons from a different domain
  • Use 40×40px SVG icons for optimal rendering

Dial not rotating correctly?

  • Ensure the justify attribute matches your layout direction
  • Check that the FAB has enough viewport space — don't trap it behind other fixed elements
  • The rotation pivot is the FAB center, not the screen center

Component not mounting?

  • Ensure bzr-dial-menu.js loads before injecting <bzr-dial-menu> DOM
  • Use customElements.whenDefined('bzr-dial-menu') before DOM injection
  • Check browser console for registration errors

Audio visualizer not working?

  • WebAudio createMediaElementSource requires same-origin audio files or proper CORS headers
  • Set crossOrigin="anonymous" on cross-origin audio (already done by component)

Performance issues?

  • Keep item count under 10 (4–8 is optimal)
  • Use optimized SVG icons (under 1KB each)
  • The rAF loop runs continuously — ensure the page isn't running heavy JS elsewhere

history Changelog

v1.0.0-mvp June 2026

Initial MVP Release

  • Physics-based radial dial with inertial scrolling and spring snapping
  • Shadow DOM encapsulated — zero CSS leakage
  • Canvas-rendered rail with velocity-warp arc visualization
  • Inline content modal system: audio (with visualizer), video, image, email, phone, map, iframe
  • Slide-to-reposition FAB via double-click
  • Icon swipe-to-snap quick navigation
  • Custom bzr-change event
  • License key validation (format-only)
  • Haptic feedback (Vibration API)
  • Responsive resize handling
center_focus_strong
bzr-dial.ui

Built by Web Works Systems. Part of The Conglomerate Group. The code executes.