Core color palette and design tokens for the design system
Status indicators and labels for counts, notifications, or status information
Visual representations of users with images, initials, and icons
Compact elements for categories, filters, and selections
Navigation for organizing content into separate views
Action containers with buttons and controls
File upload with drag & drop support and validation
Tag management with input fields and categorization
Complete guide to using and implementing Bugasura UI components in your projects
The Bugasura Component Library is a comprehensive collection of reusable UI components built with modern web standards. Each component follows consistent design patterns, uses CSS variables for theming, and adheres to BEM naming methodology.
To use the Bugasura Component Library, you need to include the following dependencies in your project:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
Used for DOM manipulation and event handling in interactive components.
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
Required for modal dialogs, tooltips, and tab navigation components.
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
Icon font used throughout the component library for buttons, navigation, and UI elements.
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap">
Primary typeface used in the design system. Fallback to system fonts if not loaded.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bugasura Components</title>
<!-- CSS Dependencies -->
<link rel="stylesheet" href="{{PUBLIC_URL}}assets/css/platformCustom.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap">
</head>
<body>
<!-- Your component markup here -->
<!-- JavaScript Dependencies -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</body>
</html>
Every component in this library follows a consistent structure:
<div class="component-name">
<div class="component-name__element">
Content
</div>
</div>
Modifiers change the appearance or behavior of components:
<!-- Default button -->
<button class="ba-btn">Button</button>
<!-- Primary button with modifier -->
<button class="ba-btn ba-btn--primary">Primary</button>
<!-- Large button with size modifier -->
<button class="ba-btn ba-btn--large">Large Button</button>
All components use Block Element Modifier (BEM) methodology for consistent and maintainable CSS:
.block__element--modifier
A standalone component that is meaningful on its own.
<div class="card"></div>
<button class="button"></button>
<div class="user-profile"></div>
A part of a block that has no standalone meaning. Always part of a block.
<div class="card">
<h3 class="card__title">Title</h3>
<p class="card__description">Description</p>
<button class="card__action">Action</button>
</div>
A flag that changes the appearance or behavior of a block or element.
<div class="card card--featured"></div>
<button class="button button--primary"></button>
<div class="alert alert--error"></div>
.user-profile.block__element.block--modifier.block__element, not .block__element__subelementComponents use CSS custom properties (variables) for consistent theming and easy customization. All design tokens are defined in the Design Primitives section.
/* Brand Colors */
var(--Brand-Colors-Primary-700)
var(--Brand-Colors-Secondary-700)
/* Status Colors */
var(--Status-Colors-Success-700)
var(--Status-Colors-Warning-700)
var(--Status-Colors-Error-700)
/* Text Colors */
var(--ba-text-primary)
var(--ba-text-secondary)
var(--ba-text-tertiary)
var(--Spacing-XS) /* 4px */
var(--Spacing-S) /* 8px */
var(--Spacing-M) /* 12px */
var(--Spacing-L) /* 16px */
var(--Spacing-XL) /* 24px */
var(--Spacing-2XL) /* 32px */
var(--Spacing-3XL) /* 48px */
var(--Spacing-4XL) /* 64px */
var(--Font-Size-XS) /* 12px */
var(--Font-Size-S) /* 14px */
var(--Font-Size-M) /* 16px */
var(--Font-Size-L) /* 18px */
var(--Font-Size-XL) /* 24px */
Click on any component below to view its detailed documentation, examples, and specifications.
.block__element--modifier patternjs- prefix for JavaScript-specific classes$ prefix for jQuery objects<button>, <nav>, etc.)aria-label for icon-only buttonsloading="lazy" for imagesAccess component CSS and design tokens for your projects.
Core color palette and design tokens for the Bugasura design system
--Brand-Colors-Primary-100
--Brand-Colors-Primary-200
--Brand-Colors-Primary-300
--Brand-Colors-Primary-400
--Brand-Colors-Primary-500
--Brand-Colors-Primary-600
--Brand-Colors-Primary-700
--Brand-Colors-Primary-800
--Brand-Colors-Primary-900
--Brand-Colors-Primary-1000
--Brand-Colors-Secondary-50
--Brand-Colors-Secondary-100
--Brand-Colors-Secondary-200
--Brand-Colors-Secondary-300
--Brand-Colors-Secondary-400
--Brand-Colors-Secondary-500
--Brand-Colors-Secondary-600
--Brand-Colors-Secondary-700
--Brand-Colors-Secondary-800
--Brand-Colors-Secondary-900
--Brand-Colors-Secondary-1000
--Brand-Colors-Accent-100
--Brand-Colors-Accent-200
--Brand-Colors-Accent-300
--Brand-Colors-Accent-400
--Brand-Colors-Accent-500
--Brand-Colors-Accent-600
--Brand-Colors-Accent-700
--Brand-Colors-Accent-800
--Brand-Colors-Accent-900
--Brand-Colors-Accent-1000
--Status-Colors-Success-100
--Status-Colors-Success-200
--Status-Colors-Success-300
--Status-Colors-Success-400
--Status-Colors-Success-500
--Status-Colors-Success-600
--Status-Colors-Success-700
--Status-Colors-Success-800
--Status-Colors-Success-900
--Status-Colors-Success-1000
--Status-Colors-Warning-100
--Status-Colors-Warning-200
--Status-Colors-Warning-300
--Status-Colors-Warning-400
--Status-Colors-Warning-500
--Status-Colors-Warning-600
--Status-Colors-Warning-700
--Status-Colors-Warning-800
--Status-Colors-Warning-900
--Status-Colors-Warning-1000
--Status-Colors-Error-100
--Status-Colors-Error-200
--Status-Colors-Error-300
--Status-Colors-Error-400
--Status-Colors-Error-500
--Status-Colors-Error-600
--Status-Colors-Error-700
--Status-Colors-Error-800
--Status-Colors-Error-900
--Status-Colors-Error-1000
--Neutral-Colors-Main-Neutrals-25
--Neutral-Colors-Main-Neutrals-50
--Neutral-Colors-Main-Neutrals-100
--Neutral-Colors-Main-Neutrals-200
--Neutral-Colors-Main-Neutrals-300
--Neutral-Colors-Main-Neutrals-400
--Neutral-Colors-Main-Neutrals-500
--Neutral-Colors-Main-Neutrals-600
--Neutral-Colors-Main-Neutrals-700
--Neutral-Colors-Main-Neutrals-800
--Neutral-Colors-Main-Neutrals-900
--Neutral-Colors-Main-Neutrals-1000
--Neutral-Colors-Tonal-Neutrals-100
--Neutral-Colors-Tonal-Neutrals-200
--Neutral-Colors-Tonal-Neutrals-300
--Neutral-Colors-Tonal-Neutrals-400
--Neutral-Colors-Tonal-Neutrals-500
--Neutral-Colors-Tonal-Neutrals-600
--Neutral-Colors-Tonal-Neutrals-700
--Neutral-Colors-Tonal-Neutrals-800
--Neutral-Colors-Tonal-Neutrals-900
--Neutral-Colors-Tonal-Neutrals-1000
--Neutral-Colors-Alpha-Neutrals-100
--Neutral-Colors-Alpha-Neutrals-200
--Neutral-Colors-Alpha-Neutrals-300
--Neutral-Colors-Alpha-Neutrals-400
--Neutral-Colors-Alpha-Neutrals-500
--Neutral-Colors-Alpha-Neutrals-600
--Neutral-Colors-Alpha-Neutrals-700
--Neutral-Colors-Alpha-Neutrals-800
--Neutral-Colors-Alpha-Neutrals-900
--Neutral-Colors-Alpha-Neutrals-1000
--Base-Colors-Base-White
--Base-Colors-Base-Black
Font Name - Roboto
| Variable Name | Spacing Value (px) | Spacing Value (rem) | Visual |
|---|---|---|---|
| XS | 2px | 0.179rem | |
| S | 4px | 0.357rem | |
| M | 6px | 0.536rem | |
| L | 8px | 0.714rem | |
| XL | 12px | 1.071rem |
| Variable Name | Radius Value (px) | Radius Value (rem) | Visual |
|---|---|---|---|
| S | 4px | 0.357rem |
S
|
| M | 8px | 0.714rem |
M
|
| L | 12px | 1.071rem |
L
|
| Variable Name | Effect Value (px) | Effect Value (rem) |
|---|---|---|
| 1 | 2px | 0.179rem |
| 2 | 4px | 0.357rem |
| 3 | 6px | 0.536rem |
| 4 | 8px | 0.714rem |
Small status indicators and labels for displaying counts, notifications, or status information
<span class="ba-badge ba-badge--neutral">2</span>
<span class="ba-badge ba-badge--primary">2</span>
<span class="ba-badge ba-badge--danger">2</span>
<span class="ba-badge ba-badge--ghost">2</span>
<span class="ba-badge ba-badge--neutral">24</span>
<span class="ba-badge ba-badge--primary">24</span>
<span class="ba-badge ba-badge--danger">24</span>
<span class="ba-badge ba-badge--ghost">24</span>
<span class="ba-badge ba-badge--primary disabled">24</span>
<span class="ba-badge ba-badge--neutral disabled">24</span>
<span class="ba-badge ba-badge--danger disabled">24</span>
<span class="ba-badge ba-badge--ghost disabled">24</span>
<span class="ba-badge ba-badge--primary ba-badge--lg">Large</span>
<span class="ba-badge ba-badge--primary">Default</span>
<span class="ba-badge ba-badge--primary ba-badge--sm">Small</span>
Badges are used to display small pieces of information like counts, statuses, or labels. They should be concise and easy to scan.
<span class="ba-badge ba-badge--[variant] ba-badge--[size]">
Content
</span>
| Class | Description | Use Case |
|---|---|---|
.ba-badge--neutral |
Neutral gray badge | Default, non-critical information |
.ba-badge--primary |
Primary brand color | Important, actionable items |
.ba-badge--success |
Success/positive state | Completed, successful, positive counts |
.ba-badge--warning |
Warning/caution state | Items needing attention |
.ba-badge--danger |
Error/critical state | Critical items, errors, urgent notifications |
.ba-badge--ghost |
Outlined transparent | Secondary information, tags |
| Property | Value | Token |
|---|---|---|
| Font Size | 12px / 1.071rem | var(--Body-B5-Medium-Size) |
| Font Weight | 500 | var(--Weight-Medium) |
| Padding (Vertical) | 4px / 0.357rem | var(--Spacing-S) |
| Padding (Horizontal) | 8px / 0.714rem | var(--Spacing-L) |
| Border Radius | 8px / 0.714rem | var(--Radius-M) |
| Size | Class | Padding | Font Size |
|---|---|---|---|
| Large | .ba-badge--lg |
6px / 12px | 14px |
| Default | - | 4px / 8px | 12px |
| Small | .ba-badge--sm |
2px / 6px | 11px |
| Variant | Background | Text Color |
|---|---|---|
| Neutral | Neutral-100 | Neutral-900 |
| Primary | Primary-100 | Primary-900 |
| Success | Success-100 | Success-900 |
| Warning | Warning-100 | Warning-900 |
| Danger | Error-100 | Error-900 |
Interactive elements that trigger actions or navigate users within the application
<button class="ba-btn ba-btn--primary ba-btn--lg">Large Button</button>
<button class="ba-btn ba-btn--primary">Default Button</button>
<button class="ba-btn ba-btn--primary ba-btn--sm">Small Button</button>
<button class="ba-btn ba-btn--primary ba-btn--xs">Tiny Button</button>
<button class="ba-btn ba-btn--secondary ba-btn--lg">Large Button</button>
<button class="ba-btn ba-btn--secondary">Default Button</button>
<button class="ba-btn ba-btn--secondary ba-btn--sm">Small Button</button>
<button class="ba-btn ba-btn--secondary ba-btn--xs">Tiny Button</button>
<button class="ba-btn ba-btn--tertiary ba-btn--lg">Large Button</button>
<button class="ba-btn ba-btn--tertiary">Default Button</button>
<button class="ba-btn ba-btn--tertiary ba-btn--sm">Small Button</button>
<button class="ba-btn ba-btn--tertiary ba-btn--xs">Tiny Button</button>
<button class="ba-btn ba-btn--primary">
<i class="material-symbols-rounded">add</i>
<span>Add New</span>
</button>
<button class="ba-btn ba-btn--secondary">
<i class="material-symbols-rounded">download</i>
<span>Download</span>
</button>
<button class="ba-btn ba-btn--primary ba-btn--icon ba-btn--lg" title="Add">
<i class="material-symbols-rounded">add</i>
</button>
<button class="ba-btn ba-btn--primary ba-btn--icon" title="Edit">
<i class="material-symbols-rounded">edit</i>
</button>
<button class="ba-btn ba-btn--primary">Normal</button>
<button class="ba-btn ba-btn--primary" disabled>Disabled</button>
Buttons trigger actions or navigate users. They should have clear, action-oriented labels that describe what will happen when clicked.
<!-- Basic button -->
<button class="ba-btn ba-btn--[variant] ba-btn--[size]">
Button Text
</button>
<!-- Button with icon -->
<button class="ba-btn ba-btn--[variant]">
<i class="material-symbols-rounded">icon_name</i>
<span>Button Text</span>
</button>
<!-- Icon-only button -->
<button class="ba-btn ba-btn--[variant] ba-btn--icon" title="Description">
<i class="material-symbols-rounded">icon_name</i>
</button>
| Class | Visual Style | Use Case |
|---|---|---|
.ba-btn--primary |
Filled, high emphasis | Main action on the page |
.ba-btn--secondary |
Outlined, medium emphasis | Secondary actions |
.ba-btn--tertiary |
Text only, low emphasis | Tertiary actions, Cancel |
title or aria-label attributesdisabled attribute, not just visual styling| Property | Value | Token |
|---|---|---|
| Font Size (Default) | 14px / 1.25rem | var(--Body-B3-Medium-Size) |
| Font Weight | 500 | var(--Weight-Medium) |
| Border Width | 2px | var(--Stroke-M) |
| Border Radius | 8px / 0.714rem | var(--Radius-M) |
| Icon Gap | 8px / 0.714rem | var(--Spacing-L) |
| Size | Class | Height | Padding | Font Size |
|---|---|---|---|---|
| Large | .ba-btn--lg |
48px | 12px / 16px | 16px |
| Default | - | 40px | 8px / 12px | 14px |
| Small | .ba-btn--sm |
32px | 6px / 8px | 12px |
| Extra Small | .ba-btn--xs |
24px | 4px / 6px | 11px |
| Variant | State | Background | Text | Border |
|---|---|---|---|---|
| Primary | Normal | Primary-700 | White | Primary-700 |
| Hover | Primary-900 | White | Primary-900 | |
| Disabled | Primary-700 (40% opacity) | White | Primary-700 | |
| Secondary | Normal | Transparent | Primary-700 | Primary-700 |
| Hover | Primary-100 | Primary-900 | Primary-900 | |
| Disabled | Transparent (40% opacity) | Primary-700 | Primary-700 | |
| Tertiary | Normal | Transparent | Primary-700 | Transparent |
| Hover | Neutral-100 | Primary-900 | Transparent | |
| Disabled | Transparent (40% opacity) | Primary-700 | Transparent |
Visual indicators showing completion status of tasks, uploads, or processes
Progress bars work in Bootstrap grid, Flexbox, and Grid layouts
<!-- Bootstrap 3.4 Grid -->
<div class="row">
<div class="col-xs-12">
<div class="ba-progress">
<span class="ba-progress__bar" style="width: 50%"></span>
</div>
</div>
</div>
Shows progress along a horizontal line
<div class="ba-progress">
<span class="ba-progress__bar" style="width: 50%"></span>
</div>
Different color variants for different contexts
<!-- Primary (default) -->
<div class="ba-progress">
<span class="ba-progress__bar" style="width: 50%"></span>
</div>
<!-- Success variant -->
<div class="ba-progress ba-progress--success">
<span class="ba-progress__bar" style="width: 75%"></span>
</div>
Use for unknown duration loading states
<!-- Animated indeterminate progress -->
<div class="ba-progress ba-progress--indeterminate">
<span class="ba-progress__bar" style="width: 30%"></span>
</div>
Bootstrap-style striped progress bar with animation
<!-- Striped animated progress -->
<div class="ba-progress ba-progress--striped ba-progress--animated">
<span class="ba-progress__bar" style="width: 60%"></span>
</div>
<!-- With success variant -->
<div class="ba-progress ba-progress--striped ba-progress--animated ba-progress--success">
<span class="ba-progress__bar" style="width: 75%"></span>
</div>
Pulsing animation to show ongoing activity
<!-- Pulsing progress bar -->
<div class="ba-progress ba-progress--pulse">
<span class="ba-progress__bar" style="width: 45%"></span>
</div>
Flowing gradient effect for visual interest
<!-- Gradient animated progress -->
<div class="ba-progress ba-progress--gradient">
<span class="ba-progress__bar" style="width: 70%"></span>
</div>
Pulsing glow effect for emphasis
<!-- Glowing progress bar -->
<div class="ba-progress ba-progress--glow">
<span class="ba-progress__bar" style="width: 55%"></span>
</div>
Animated progress that increases with percentage counter (JavaScript controlled)
<!-- HTML -->
<div>
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>Upload Progress</span>
<span id="progress-text">0%</span>
</div>
<div class="ba-progress ba-progress--smooth">
<span id="progress-bar" class="ba-progress__bar" style="width: 0%"></span>
</div>
</div>
<!-- JavaScript -->
<script>
function animateProgress(targetPercent, duration) {
var $bar = $('#progress-bar');
var $text = $('#progress-text');
var start = 0;
var startTime = Date.now();
function update() {
var elapsed = Date.now() - startTime;
var progress = Math.min(elapsed / duration, 1);
var current = Math.floor(start + (targetPercent - start) * progress);
$bar.css('width', current + '%');
$text.text(current + '%');
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
// Usage: Animate to 85% over 2 seconds
animateProgress(85, 2000);
</script>
Progress bar that changes color based on percentage
<!-- HTML -->
<div class="ba-progress ba-progress--dynamic">
<span id="dynamic-bar" class="ba-progress__bar" data-progress="0" style="width: 0%"></span>
</div>
<!-- JavaScript -->
<script>
function animateColorProgress(targetPercent, duration) {
var $bar = $('#dynamic-bar');
var start = 0;
var startTime = Date.now();
function getColorByPercent(percent) {
if (percent < 30) return 'var(--Status-Colors-Error-700)';
if (percent < 70) return 'var(--Status-Colors-Warning-700)';
return 'var(--Status-Colors-Success-700)';
}
function update() {
var elapsed = Date.now() - startTime;
var progress = Math.min(elapsed / duration, 1);
var current = Math.floor(start + (targetPercent - start) * progress);
$bar.css({
'width': current + '%',
'background': getColorByPercent(current)
});
$bar.attr('data-progress', current);
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
// Usage: Animate to 100% over 3 seconds
animateColorProgress(100, 3000);
</script>
Shows progress in a circular format
<div class="ba-circular">
<svg class="ba-circular__svg" viewBox="0 0 120 120">
<circle class="ba-circular__track" cx="60" cy="60" r="54"></circle>
<circle class="ba-circular__bar" cx="60" cy="60" r="54"></circle>
</svg>
<div class="ba-circular__label">75%</div>
</div>
Indeterminate progress using MDL spinner with Bugasura design tokens
<!-- MDL Spinner with Bugasura wrapper -->
<div class="ba-loader ba-loader--primary">
<div class="mdl-spinner mdl-spinner--single-color mdl-js-spinner is-active"></div>
</div>
<!-- Large size -->
<div class="ba-loader ba-loader--lg ba-loader--primary">
<div class="mdl-spinner mdl-spinner--single-color mdl-js-spinner is-active"></div>
</div>
<!-- Success variant -->
<div class="ba-loader ba-loader--success">
<div class="mdl-spinner mdl-spinner--single-color mdl-js-spinner is-active"></div>
</div>
Lightweight alternative without MDL dependency
<!-- CSS-only spinner -->
<div class="ba-spinner"></div>
<div class="ba-spinner ba-spinner--lg"></div>
<div class="ba-spinner ba-spinner--success"></div>
Progress indicators inform users about the status of ongoing processes, such as loading, uploading, or task completion.
ba-progress--indeterminate)ba-progress--striped ba-progress--animated)ba-progress--pulse)ba-progress--gradient)ba-progress--glow)ba-progress--smooth)ba-progress--dynamic)<!-- Linear progress bar -->
<div class="ba-progress ba-progress--[variant]">
<span class="ba-progress__bar" style="width: [percentage]%">
<span class="ba-progress__label">[percentage]%</span>
</span>
</div>
<!-- Variants: leave empty for primary, or use --success, --warning, --error -->
<!-- Circular progress -->
<div class="ba-circular ba-circular--[size]">
<svg class="ba-circular__svg" viewBox="0 0 120 120">
<circle class="ba-circular__track" cx="60" cy="60" r="54"></circle>
<circle class="ba-circular__bar" cx="60" cy="60" r="54"></circle>
</svg>
<div class="ba-circular__label">[percentage]%</div>
</div>
<!-- Loading spinner -->
<div class="ba-spinner ba-spinner--[size]"></div>
// Update linear progress
function updateProgress(percentage) {
var $bar = $('.ba-progress__bar');
$bar.css('width', percentage + '%');
$bar.find('.ba-progress__label').text(percentage + '%');
}
// Update circular progress
function updateCircularProgress(percentage) {
var radius = 54;
var circumference = 2 * Math.PI * radius; // 339.292
var offset = circumference - (percentage / 100 * circumference);
$('.ba-circular__bar').css({
'stroke-dasharray': circumference,
'stroke-dashoffset': offset
});
$('.ba-circular__label').text(percentage + '%');
}
// Show/hide spinner
$('.ba-spinner').show(); // Show loading
$('.ba-spinner').hide(); // Hide when complete
role="progressbar" for progress indicatorsaria-valuenow, aria-valuemin, and aria-valuemaxaria-label to describe what is progressingaria-live="polite" to announce completion<div class="ba-progress"
role="progressbar"
aria-valuenow="60"
aria-valuemin="0"
aria-valuemax="100"
aria-label="Upload progress">
<span class="ba-progress__bar" style="width: 60%">
<span class="ba-progress__label">60%</span>
</span>
</div>
| Property | Value | Token |
|---|---|---|
| Height | 8px / 0.714rem | var(--Spacing-L) |
| Border Radius | 12px / 1.071rem | var(--Radius-L) |
| Track Background | Neutral-100 | var(--Neutral-Colors-Main-Neutrals-100) |
| Bar Background | Primary-700 | var(--Primary-Colors-Primary-700) |
| Transition | width 0.3s ease | - |
| Size | Class | Diameter | Stroke Width | Font Size |
|---|---|---|---|---|
| Extra Large | .ba-circular--xl |
168px / 12rem | 15px / 1.071rem | 18px |
| Large | .ba-circular--lg |
134.4px / 9.6rem | 12.5px / 0.893rem | 16px |
| Medium | .ba-circular--md |
112px / 8rem | 10px / 0.714rem | 14px |
| Default | - | 96px / 6.857rem | 8px / 0.571rem | 14px |
| Small | .ba-circular--sm |
89.6px / 6.4rem | 7.5px / 0.536rem | 12px |
| Extra Small | .ba-circular--xs |
67.2px / 4.8rem | 5px / 0.357rem | 11px |
| Size | Class | Diameter | Border Width |
|---|---|---|---|
| Extra Large | .ba-spinner--xl |
64px / 4.571rem | 6px |
| Large | .ba-spinner--lg |
48px / 3.429rem | 5px |
| Medium | .ba-spinner--md |
40px / 2.857rem | 4px |
| Default | - | 32px / 2.286rem | 4px |
| Small | .ba-spinner--sm |
24px / 1.714rem | 3px |
| Extra Small | .ba-spinner--xs |
16px / 1.143rem | 2px |
| Variant | Class | Color | Token |
|---|---|---|---|
| Primary | .ba-progress (default) |
Primary-700 | var(--ba-interactive-primary) |
| Success | .ba-progress--success |
Success-700 | var(--Status-Colors-Success-700) |
| Warning | .ba-progress--warning |
Warning-700 | var(--Status-Colors-Warning-700) |
| Error/Danger | .ba-progress--error |
Error-700 | var(--Status-Colors-Error-700) |
| Component | Animation | Duration | Timing Function |
|---|---|---|---|
| Linear Progress Bar | Width transition | 0.3s | ease |
| Circular Progress | Stroke dashoffset | 0.3s | ease-in-out |
| Spinner | Rotation | 1s | linear (infinite) |
| Variant | Class | Animation | Duration | Use Case |
|---|---|---|---|---|
| Indeterminate | .ba-progress--indeterminate |
Sliding bar | 1.5s | Unknown duration loading |
| Striped | .ba-progress--striped |
Static stripes | - | Visual distinction |
| Striped Animated | .ba-progress--striped.ba-progress--animated |
Moving stripes | 1s | Active processes |
| Pulse | .ba-progress--pulse |
Opacity pulse | 1.5s | Waiting states |
| Gradient | .ba-progress--gradient |
Flowing gradient | 2s | Visual interest |
| Glow | .ba-progress--glow |
Pulsing shadow | 2s | Emphasis |
| Smooth | .ba-progress--smooth |
Cubic bezier transition | 0.8s | JS-controlled updates |
| Dynamic | .ba-progress--dynamic |
Color + width transition | 0.3s / 0.8s | Color-changing progress |
Text input fields for capturing user data in forms and interfaces
Standard text input field
<input type="text" class="ba-input" placeholder="Enter text...">
<input type="email" class="ba-input" placeholder="Enter email...">
<input type="password" class="ba-input" placeholder="Enter password...">
Input field with associated label
<div class="ba-input-group"> <label for="input-email" class="ba-input-group__label">Email Address</label> <input type="email" id="input-email" class="ba-input" placeholder="john@example.com" aria-invalid="false"> </div>// Real-time email validation $('#input-email').on('blur', function() { var $input = $(this); var email = $input.val(); var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { $input.addClass('ba-input--error') .removeClass('ba-input--success') .attr('aria-invalid', 'true'); $input.siblings('.ba-input-group__message--error').show(); } else { $input.addClass('ba-input--success') .removeClass('ba-input--error').attr('aria-invalid', 'false'); $input.siblings('.ba-input-group__message--error').hide(); } });
Input field with leading or trailing icons
<div class="ba-input-group ba-input-group-icon--left"> <i class="material-symbols-rounded ba-input-group__icon">search</i> <input type="text" class="ba-input ba-input--search" placeholder="Search..."> </div><!-- Input with Right icon password Toggle --> <div class="ba-input-group ba-input-group-icon--right"> <input type="password" class="ba-input ba-input--with-icon-right" id="password" placeholder="Enter password"> <button type="button" class="ba-input-btn-icon ba-input-btn-icon--right js-toggle-password" aria-label="toggle-password-visibility"> <i class="material-symbols-rounded">visibility</i> </button> </div>// Toggle password visibility $('.js-toggle-password').on('click', function() { var $button = $(this); var $input = $button.siblings('input'); var $icon = $button.find('.material-symbols-rounded'); if ($input.attr('type') === 'password') { $input.attr('type', 'text'); $icon.text('visibility_off'); $button.attr('aria-label', 'Hide password'); } else { $input.attr('type', 'password'); $icon.text('visibility'); $button.attr('aria-label', 'Show password'); } });
Different states for user feedback
<!-- Error state -->
<div class="ba-input-group ba-input-group--error">
<label for="input-error" class="ba-input-group__label">Error State</label>
<input type="text" id="input-error" class="ba-input ba-input--error" value="Invalid input" aria-invalid="true" aria-describedby="error-message">
<span class="ba-input-group__message ba-input-group__message--error" id="error-message">This field is required</span>
</div>
Multi-line text input
<div class="ba-input-group"> <label for="textarea-desc" class="ba-input-group__label">Description</label> <textarea id="textarea-desc" class="ba-input ba-textarea" rows="4" placeholder="Enter description..." maxlength="500"></textarea> <div class="ba-input-group__message ba-character-count"> Maximum <span class="js-char-count">0</span> / 500 characters </div> </div>// Character counter for textarea $('.ba-textarea[maxlength]').on('input', function() { var $textarea = $(this); var maxLength = $textarea.attr('maxlength'); var currentLength = $textarea.val().length; $textarea.siblings('.ba-character-count') .find('.js-char-count') .text(currentLength); });
Search text input
<!-- Search input -->
<div class="ba-input-group ba-input-search ba-input-group-icon--left ba-input-group-icon--right">
<i class="material-symbols-rounded ba-input-group__icon">search</i>
<input type="text" class="ba-input ba-input-bg--gray ba-input--search ba-input--rounded" placeholder="Search...">
<i class="material-symbols-rounded ba-input--close ba-input-group__icon--right">close</i>
</div>
Different size variants
<input type="text" class="ba-input ba-input--lg" placeholder="Large input">
<input type="text" class="ba-input" placeholder="Default input">
<input type="text" class="ba-input ba-input--sm" placeholder="Small input">
Input field with JQuery Validation
<form id="userForm"> <div class="ba-col" style="gap: var(--Spacing-L); max-width: 400px; align-items: flex-start;"> <div class="ba-input-group"> <label for="input-name" class="ba-input-group__label">Full Name</label> <input type="text" id="input-name" name="fullname" class="ba-input" placeholder="John Doe"> </div> <div class="ba-input-group"> <label for="input-email" class="ba-input-group__label">Email Address</label> <input type="email" id="input-email" name="email" class="ba-input" placeholder="john@example.com"> </div> </div> <div style="margin-top: var(--Spacing-3XL);"> <button type="submit" class="ba-btn ba-btn--primary">Submit</button> </div> </form>// JQuery Validation for form $("#userForm").validate({ rules: { fullname: { required: true, firstCharSpace: true, minlength: 3 }, email: { required: true, validateEmail: true } }, messages: { fullname: { required: "Please enter your full name", firstCharSpace: "First character cannot be space", minlength: "At least 3 characters long" }, email: { required: "Please enter your email", validateEmail: "Please provide valid Email-Id" } }, errorElement: "span", errorClass: "ba-input-group__message ba-input-group__message--error", highlight: function (element) { $(element).addClass("is-invalid"); }, unhighlight: function (element) { $(element).removeClass("is-invalid"); }, submitHandler: function (form) { return } });
Input fields are used to capture user data in forms and interfaces. They should be clear, accessible, and provide appropriate feedback.
<!-- Basic input -->
<input type="text" class="ba-input" placeholder="Placeholder text">
<!-- Input with label -->
<div class="ba-input-group">
<label for="input-id" class="ba-input-group__label">Label</label>
<input type="text" id="input-id" class="ba-input" placeholder="Placeholder">
<span class="ba-input-group__message">Helper text</span>
</div>
<!-- Input with icon -->
<div class="ba-input-wrapper ba-input-wrapper--icon-left">
<i class="material-symbols-rounded ba-input-wrapper__icon">icon_name</i>
<input type="text" class="ba-input" placeholder="Placeholder">
</div>
<!-- Error state -->
<div class="ba-input-group ba-input-group--error">
<label class="ba-input-group__label">Label</label>
<input type="text" class="ba-input ba-input--error">
<span class="ba-input-group__message">Error message</span>
</div>
<!-- Textarea -->
<textarea class="ba-input ba-textarea" rows="4" placeholder="Placeholder"></textarea>
| Modifier | Description | Use Case |
|---|---|---|
.ba-input--lg |
Large input (48px height) | Primary forms, emphasis |
| Default | Standard input (40px height) | Most forms |
.ba-input--sm |
Small input (32px height) | Compact forms, filters |
.ba-input--search |
Search input styling | Search fields |
.ba-input--error |
Error state styling | Invalid input |
.ba-input--success |
Success state styling | Valid input |
.ba-input--disabled |
Disabled state styling | Non-editable fields |
for and id attributesaria-describedby to link helper text with inputsaria-invalid="true" for error statesrole="alert"aria-required="true" for required fields<div class="ba-input-group ba-input-group--error">
<label for="email" class="ba-input-group__label">
Email <span aria-label="required">*</span>
</label>
<input type="email"
id="email"
class="ba-input ba-input--error"
aria-required="true"
aria-invalid="true"
aria-describedby="email-error"
autocomplete="email">
<span id="email-error" class="ba-input-group__message" role="alert">
Please enter a valid email address
</span>
</div>
| Property | Value | Token |
|---|---|---|
| Font Size | 14px / 1.25rem | var(--Body-B3-Medium-Size) |
| Font Weight | 400 | var(--Weight-Regular) |
| Border Width | 2px | var(--Stroke-M) |
| Border Color | Neutral-300 | var(--ba-border-primary) |
| Border Radius | 8px / 0.714rem | var(--Radius-M) |
| Background | White | var(--Base-Colors-Base-White) |
| Text Color | Neutral-900 | var(--ba-text-primary) |
| Placeholder Color | Neutral-500 | var(--ba-text-tertiary) |
| Size | Class | Height | Padding | Font Size |
|---|---|---|---|---|
| Large | .ba-input--lg |
48px | 12px / 16px | 16px |
| Default | - | 40px | 8px / 12px | 14px |
| Small | .ba-input--sm |
32px | 6px / 8px | 12px |
| State | Border Color | Background | Additional Styling |
|---|---|---|---|
| Normal | Neutral-300 | White | - |
| Hover | Neutral-400 | White | - |
| Focus | Primary-700 | White | Box shadow: 0 0 0 3px Primary-100 |
| Error | Error-500 | White | Box shadow: 0 0 0 3px Error-100 |
| Success | Success-500 | White | Box shadow: 0 0 0 3px Success-100 |
| Disabled | Neutral-200 | Neutral-100 | Opacity: 0.6, cursor: not-allowed |
| Position | Class | Icon Size | Gap from Input |
|---|---|---|---|
| Left Icon | .ba-input-wrapper--icon-left |
20px | 12px padding-left on input |
| Right Icon | .ba-input-wrapper--icon-right |
20px | 12px padding-right on input |
| Element | Font Size | Font Weight | Color |
|---|---|---|---|
| Label | 14px | 500 (Medium) | Neutral-900 |
| Input Text | 14px | 400 (Regular) | Neutral-900 |
| Placeholder | 14px | 400 (Regular) | Neutral-500 |
| Helper Text | 12px | 400 (Regular) | Neutral-700 |
| Error Message | 12px | 400 (Regular) | Error-700 |
Visual representations of users or entities with support for images, initials, and icons
<div class="ba-avatar ba-avatar--xl">
<img src="avatar.png" alt="User">
</div>
<div class="ba-avatar ba-avatar--lg">
<img src="avatar.png" alt="User">
</div>
<div class="ba-avatar">
<img src="avatar.png" alt="User">
</div>
<div class="ba-avatar ba-avatar--sm">
<img src="avatar.png" alt="User">
</div>
<ul class="list-inline up__avatar-list"> <li> <img class="icon up__avatar-icon" src="..." alt=""> </li> </ul>var userList = new UserList('user_list', { names : ['avatar-1', 'avatar-2', 'avatar-3', 'avatar-4', 'avatar-7'], IsRemove : true, tooltip : true, showMax: 4, onRemove: function(index) { console.log('User removed at index:', index); } })
Use when no profile image is available
<div class="ba-avatar">
<span class="ba-avatar__initials">JD</span>
</div>
Use for system users or special entities
<div class="ba-avatar">
<i class="material-symbols-rounded">person</i>
</div>
Show online/offline or notification status
<div class="ba-avatar ba-avatar--has-badge">
<img src="avatar.png" alt="User">
<span class="ba-avatar__badge ba-avatar__badge--online"></span>
</div>
Display multiple avatars in a stack
<div class="ba-avatar-group">
<div class="ba-avatar">
<img src="user1.png" alt="User 1">
</div>
<div class="ba-avatar">
<img src="user2.png" alt="User 2">
</div>
<div class="ba-avatar">
<span class="ba-avatar__more">+5</span>
</div>
</div>
Avatars provide visual identification of users, teams, or entities throughout the application. They help users quickly recognize people and entities.
<!-- Avatar with image -->
<div class="ba-avatar ba-avatar--[size]">
<img src="path/to/image.jpg" alt="User Name">
</div>
<!-- Avatar with initials -->
<div class="ba-avatar ba-avatar--[size]" aria-label="User Name">
<span class="ba-avatar__initials">UN</span>
</div>
<!-- Avatar with icon -->
<div class="ba-avatar ba-avatar--[size]" aria-label="System User">
<i class="material-symbols-rounded">person</i>
</div>
<!-- Avatar with status badge -->
<div class="ba-avatar ba-avatar--has-badge">
<img src="avatar.jpg" alt="User Name">
<span class="ba-avatar__badge ba-avatar__badge--online" aria-label="Online"></span>
</div>
<!-- Avatar group -->
<div class="ba-avatar-group">
<div class="ba-avatar">...</div>
<div class="ba-avatar">...</div>
<div class="ba-avatar">
<span class="ba-avatar__more">+3</span>
</div>
</div>
| Modifier | Description | Use Case |
|---|---|---|
.ba-avatar--xl |
Extra large size (80px) | Profile pages, user settings |
.ba-avatar--lg |
Large size (64px) | Featured users, headers |
| Default | Standard size (40px) | Most common use cases |
.ba-avatar--sm |
Small size (32px) | Lists, compact views |
.ba-avatar--xs |
Extra small size (24px) | Dense lists, metadata |
.ba-avatar--has-badge |
Container for status badge | Online status, notifications |
| Property | Value | Token |
|---|---|---|
| Border Radius | 50% (Circle) | var(--Radius-Null) |
| Background (No Image) | Primary-100 | var(--Primary-Colors-Primary-100) |
| Text Color (Initials) | Primary-900 | var(--Primary-Colors-Primary-900) |
| Icon Color | Primary-700 | var(--Primary-Colors-Primary-700) |
| Border Width | 2px | var(--Stroke-M) |
| Border Color | White | var(--Base-Colors-Base-White) |
| Size | Class | Dimensions | Font Size | Icon Size |
|---|---|---|---|---|
| Extra Large | .ba-avatar--xl |
80px × 80px | 28px | 40px |
| Large | .ba-avatar--lg |
64px × 64px | 24px | 32px |
| Default | - | 40px × 40px | 16px | 20px |
| Small | .ba-avatar--sm |
32px × 32px | 14px | 16px |
| Extra Small | .ba-avatar--xs |
24px × 24px | 11px | 14px |
| Status | Class | Color | Position |
|---|---|---|---|
| Online | .ba-avatar__badge--online |
Success-500 | Bottom right |
| Offline | .ba-avatar__badge--offline |
Neutral-300 | Bottom right |
| Busy | .ba-avatar__badge--busy |
Error-500 | Bottom right |
| Away | .ba-avatar__badge--away |
Warning-500 | Bottom right |
| Notification | .ba-avatar__badge--notification |
Error-500 background | Top right |
| Property | Value | Description |
|---|---|---|
| Overlap | -8px | Negative margin for stacking effect |
| Border | 2px white | Separates overlapping avatars |
| Max Visible | 5-6 avatars | Recommended maximum before using "+N" |
| Z-index | Ascending left to right | Creates proper stacking order |
Checkboxes, radio buttons, and toggles for user selections and preferences
Allow multiple selections from a set of options
<label class="ba-checkbox">
<input type="checkbox" id="ba_check_1" class="ba-checkbox__input" checked>
<span class="ba-checkbox__box"></span>
<span class="ba-checkbox__label">Checked</span>
</label>
Allow single selection from a set of options
<label class="ba-radio">
<input type="radio" name="ba_r1" class="ba-radio__input" checked>
<span class="ba-radio__circle"></span>
<span class="ba-radio__label">Selected</span>
</label>
Binary on/off control for settings
<label class="ba-switch">
<input type="checkbox" class="ba-switch__input" checked>
<span class="ba-switch__track">
<span class="ba-switch__thumb"></span>
</span>
<span class="ba-switch__label">Enabled</span>
</label>
Multiple related checkboxes
<div class="ba-checkbox-group">
<div class="ba-checkbox-group__label">Select your interests:</div>
<label class="ba-checkbox">
<input type="checkbox" class="ba-checkbox__input" checked>
<span class="ba-checkbox__box"></span>
<span class="ba-checkbox__label">Technology</span>
</label>
<!-- More checkboxes... -->
</div>
Multiple related radio buttons
<div class="ba-radio-group">
<div class="ba-radio-group__label">Choose your plan:</div>
<label class="ba-radio">
<input type="radio" name="plan" class="ba-radio__input" checked>
<span class="ba-radio__circle"></span>
<span class="ba-radio__label">Pro</span>
</label>
<!-- More radios... -->
</div>
Multiple related checkboxes
<div class="ba-checkbox-group"> <label class="ba-checkbox"> <input type="checkbox" class="ba-checkbox__input js-select-all"> <span class="ba-checkbox__box"></span> <span class="ba-checkbox__label">Select All</span> </label> </div> <div class="ba-checkbox-group"> <div class="ba-col" style="gap: var(--Spacing-XL); margin-top: var(--Spacing-2XL);"> <label class="ba-checkbox js-checkbox-items"> <input type="checkbox" class="ba-checkbox__input js-item-checkbox"> <span class="ba-checkbox__box"></span> <span class="ba-checkbox__label">Technology</span> </label> <!-- More checkboxes... --> </div> </div>// Select All / Deselect All $('.js-select-all').on('change', function() { var isChecked = $(this).is(':checked'); $('.js-item-checkbox').prop('checked', isChecked); }); // Update "Select All" state when individual items change $('.js-item-checkbox').on('change', function() { var totalItems = $('.js-item-checkbox').length; var checkedItems = $('.js-item-checkbox:checked').length; $('.js-select-all').prop('checked', totalItems === checkedItems); // Indeterminate state (some but not all selected) $('.js-select-all').prop('indeterminate', checkedItems > 0 && checkedItems < totalItems); });
Selection controls allow users to make choices from a set of options. Choose the appropriate control based on the selection behavior needed.
<!-- Checkbox -->
<label class="ba-checkbox">
<input type="checkbox" id="checkbox-id" class="ba-checkbox__input">
<span class="ba-checkbox__box"></span>
<span class="ba-checkbox__label">Label Text</span>
</label>
<!-- Radio -->
<label class="ba-radio">
<input type="radio" name="group-name" class="ba-radio__input">
<span class="ba-radio__circle"></span>
<span class="ba-radio__label">Label Text</span>
</label>
<!-- Toggle Switch -->
<label class="ba-switch">
<input type="checkbox" class="ba-switch__input">
<span class="ba-switch__track">
<span class="ba-switch__thumb"></span>
</span>
<span class="ba-switch__label">Label Text</span>
</label>
<!-- Checkbox Group -->
<div class="ba-checkbox-group">
<div class="ba-checkbox-group__label">Group Label</div>
<label class="ba-checkbox">...</label>
<label class="ba-checkbox">...</label>
</div>
<!-- Radio Group -->
<div class="ba-radio-group">
<div class="ba-radio-group__label">Group Label</div>
<label class="ba-radio">...</label>
<label class="ba-radio">...</label>
</div>
<label> elements wrapping the input and text for clickable labelsid attributes for each inputname attribute for radio buttons in the same grouparia-describedby for additional instructions<fieldset>
<legend>Select your notification preferences</legend>
<label class="ba-checkbox">
<input type="checkbox" class="ba-checkbox__input"
id="email-notif"
aria-describedby="email-help">
<span class="ba-checkbox__box"></span>
<span class="ba-checkbox__label">Email notifications</span>
</label>
<span id="email-help" class="help-text">
Receive updates via email
</span>
</fieldset>
| Property | Value | Token |
|---|---|---|
| Size | 20px / 1.429rem | - |
| Border Width | 2px | var(--Stroke-M) |
| Border Radius | 4px / 0.357rem | var(--Radius-S) |
| Border Color (Unchecked) | Neutral-400 | var(--ba-border-secondary) |
| Background (Checked) | Primary-700 | var(--ba-interactive-primary) |
| Checkmark Icon | Material Symbols: check | - |
| Checkmark Size | 20px / 1.429rem | - |
| Label Gap | 8px / 0.714rem | var(--Spacing-L) |
| Property | Value | Token |
|---|---|---|
| Size | 20px / 1.429rem | - |
| Border Width | 2px | var(--Stroke-M) |
| Border Radius | 50% (Circle) | var(--Radius-Null) |
| Border Color (Unselected) | Neutral-400 | var(--ba-border-secondary) |
| Border Color (Selected) | Primary-700 | var(--ba-interactive-primary) |
| Inner Circle Size | 10px / 0.714rem | - |
| Inner Circle Color | Primary-700 | var(--ba-interactive-primary) |
| Label Gap | 8px / 0.714rem | var(--Spacing-L) |
| Property | Value | Token |
|---|---|---|
| Track Width | 50px / 3.571rem | - |
| Track Height | 28px / 2rem | - |
| Track Radius | 28px / 2rem (Full round) | var(--Radius-Null) |
| Track Color (Off) | Neutral-300 | var(--ba-surface-tertiary) |
| Track Color (On) | Primary-700 | var(--ba-interactive-primary) |
| Thumb Size | 20px / 1.429rem | - |
| Thumb Color | White | var(--Base-Colors-Base-White) |
| Thumb Offset | 4px / 0.357rem | var(--Spacing-S) |
| Label Gap | 8px / 0.714rem | var(--Spacing-L) |
| Component | State | Visual Change |
|---|---|---|
| Checkbox | Normal | Border: Neutral-400, Background: Transparent |
| Checked | Background: Primary-700, White checkmark | |
| Disabled | Opacity: 0.4, cursor: not-allowed | |
| Radio | Unselected | Border: Neutral-400, No inner circle |
| Selected | Border: Primary-700, Inner circle: Primary-700 | |
| Disabled | Opacity: 0.4, cursor: not-allowed | |
| Toggle | Off | Track: Neutral-300, Thumb at left |
| On | Track: Primary-700, Thumb at right | |
| Disabled | Opacity: 0.4, cursor: not-allowed |
| Element | Spacing | Token |
|---|---|---|
| Between control and label | 8px / 0.714rem | var(--Spacing-L) |
| Between group items | 12px / 1.071rem | var(--Spacing-XL) |
| Group label bottom margin | 8px / 0.714rem | var(--Spacing-L) |
| Clickable area (minimum) | 44px × 44px | - |
| Component | Animation | Duration | Timing |
|---|---|---|---|
| Checkbox | Checkmark scale & opacity | 0.2s | ease |
| Radio | Inner circle scale & opacity | 0.2s | ease |
| Toggle | Thumb slide & track color | 0.3s | ease-in-out |
Navigation components for organizing content into separate views within the same context
Simple text-based tab navigation
<ul class="ba-tabs ba-tabs--basic" role="tablist">
<li role="presentation" class="active">
<a href="#tab1" class="ba-tabs__tab" role="tab" data-toggle="tab">Overview</a>
</li>
<li role="presentation">
<a href="#tab2" class="ba-tabs__tab" role="tab" data-toggle="tab">Details</a>
</li>
<li role="presentation">
<a href="#tab3" class="ba-tabs__tab" role="tab" data-toggle="tab">Settings</a>
</li>
</ul>
Display counts or badges within tabs
<ul class="ba-tabs ba-tabs--with-counts" role="tablist">
<li role="presentation" class="active">
<a href="#tab1" class="ba-tabs__tab" role="tab" data-toggle="tab">
All Issues
<span class="ba-badge ba-badge--neutral ba-badge--sm">234</span>
</a>
</li>
<li role="presentation">
<a href="#tab2" class="ba-tabs__tab" role="tab" data-toggle="tab">
Open
<span class="ba-badge ba-badge--primary ba-badge--sm">45</span>
</a>
</li>
</ul>
Add icons for visual context
<ul class="ba-tabs ba-tabs--with-icons" role="tablist">
<li role="presentation" class="active">
<a href="#tab1" class="ba-tabs__tab" role="tab" data-toggle="tab">
<i class="material-symbols-rounded">dashboard</i>
<span>Dashboard</span>
</a>
</li>
<li role="presentation">
<a href="#tab2" class="ba-tabs__tab" role="tab" data-toggle="tab">
<i class="material-symbols-rounded">list</i>
<span>Projects</span>
</a>
</li>
</ul>
<ul class="ba-tabs ba-tabs--icon-only" role="tablist">
<li role="presentation" class="active">
<a href="#tab1" class="ba-tabs__tab" role="tab" data-toggle="tab" title="Grid View">
<i class="material-symbols-rounded">grid_view</i>
</a>
</li>
<li role="presentation">
<a href="#tab2" class="ba-tabs__tab" role="tab" data-toggle="tab" title="List View">
<i class="material-symbols-rounded">view_list</i>
</a>
</li>
</ul>
Tabs organize related content into separate views within the same context, allowing users to switch between them without leaving the page.
role="tablist", role="tab", and role="tabpanel"aria-selected to indicate active tabaria-controls and idaria-label or title<!-- Simple tabs -->
<ul class="ba-tabs ba-tabs--basic" role="tablist">
<li role="presentation" class="active">
<a href="#tab1" class="ba-tabs__tab" role="tab" data-toggle="tab">Overview</a>
</li>
<li role="presentation">
<a href="#tab2" class="ba-tabs__tab" role="tab" data-toggle="tab">Details</a>
</li>
<li role="presentation">
<a href="#tab3" class="ba-tabs__tab" role="tab" data-toggle="tab">Settings</a>
</li>
</ul>
<!-- Tabs with Icons -->
<ul class="ba-tabs ba-tabs--with-icons" role="tablist">
<li role="presentation" class="active">
<a href="#tab1" class="ba-tabs__tab" role="tab" data-toggle="tab">
<i class="material-symbols-rounded">dashboard</i>
<span>Dashboard</span>
</a>
</li>
<li role="presentation">
<a href="#tab2" class="ba-tabs__tab" role="tab" data-toggle="tab">
<i class="material-symbols-rounded">list</i>
<span>Projects</span>
</a>
</li>
</ul>
// Simple tab switching without Bootstrap
$('.ba-tabs__tab').on('click', function() {
var $this = $(this);
var tabId = $this.data('tab');
// Update active tab
$this.addClass('ba-tabs__tab--active')
.siblings().removeClass('ba-tabs__tab--active');
// Show corresponding content
$('#' + tabId).addClass('active').show()
.siblings('.tab-pane').removeClass('active').hide();
});
// Tab navigation with keyboard
$('.ba-tabs__tab').on('keydown', function(e) {
var $tabs = $('.ba-tabs__tab');
var $current = $(this);
var index = $tabs.index($current);
if (e.key === 'ArrowRight') {
e.preventDefault();
var $next = $tabs.eq(index + 1);
if ($next.length) $next.click().focus();
} else if (e.key === 'ArrowLeft') {
e.preventDefault();
var $prev = $tabs.eq(index - 1);
if ($prev.length) $prev.click().focus();
} else if (e.key === 'Home') {
e.preventDefault();
$tabs.first().click().focus();
} else if (e.key === 'End') {
e.preventDefault();
$tabs.last().click().focus();
}
});
// Bootstrap tabs usage
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
var activeTab = e.target; // newly activated tab
var previousTab = e.relatedTarget; // previous active tab
console.log('Switched from', previousTab, 'to', activeTab);
});
<button role="tab"
aria-selected="false"
aria-controls="panel-2"
id="tab-2"
class="ba-tabs__tab"
tabindex="-1">
Tab Two
</button>
</div>
| Property | Value | Token |
|---|---|---|
| Font Size | 14px / 1.25rem | var(--Body-B3-Medium-Size) |
| Font Weight | 500 | var(--Weight-Medium) |
| Padding (Horizontal) | 16px / 1.429rem | var(--Spacing-XL) |
| Padding (Vertical) | 8px / 0.714rem | var(--Spacing-L) |
| Border Width (Active) | 2px / 0.179rem | var(--Stroke-M) |
| Icon Size | 20px / 1.429rem | - |
| Icon Gap | 8px / 0.714rem | var(--Spacing-L) |
| State | Text Color | Border Bottom | Background |
|---|---|---|---|
| Default | Neutral-700 | Transparent | Transparent |
| Hover | Neutral-900 | Transparent | Neutral-100 |
| Active | Primary-700 | 2px Primary-700 | Transparent |
| Focus | Primary-700 | 2px Primary-700 | Primary-50 |
| Disabled | Neutral-400 | Transparent | Transparent |
| Property | Value |
|---|---|
| Tab Height | 40px / 2.857rem |
| Minimum Touch Target | 44px × 44px |
| Border Bottom (Container) | 1px solid Neutral-200 |
| Tab Spacing | 0px (adjacent) |
| Active Border Position | Bottom edge |
| Active Border Offset | -1px (overlaps container border) |
| Property | Value |
|---|---|
| Tab Min Width | 120px / 10.714rem |
| Tab Height | 40px / 2.857rem |
| Tab Spacing | 4px / 0.357rem |
| Active Border Position | Left edge |
| Active Border Width | 3px |
| Background (Active) | Primary-50 |
| Property | Value |
|---|---|
| Padding Top | 24px / 2.143rem |
| Padding (Other sides) | 16px / 1.429rem |
| Transition Duration | 0.3s |
| Transition Timing | ease-in-out |
| Element | Animation | Duration | Timing |
|---|---|---|---|
| Tab State Change | Color, border transition | 0.2s | ease |
| Tab Content | Fade in/out, opacity | 0.3s | ease-in-out |
| Active Indicator | Slide, border transition | 0.3s | ease |
| Breakpoint | Behavior |
|---|---|
| Desktop (>992px) | Full horizontal tab layout |
| Tablet (768px - 992px) | Horizontal with possible scrolling |
| Mobile (<768px) | Consider dropdown or stacked tabs |
| Overflow Behavior | Horizontal scroll or dropdown menu |
Now describes dropdown functionality (selection menus with revealed options)
<div class="dropdown ba-dropdown">
<button class="ba-btn ba-btn--secondary"
data-toggle="dropdown">Basic Dropdown</button>
<ul class="dropdown-menu ba-dropdown__menu">
<li class="ba-dropdown__header">Select Run</li>
<div class="ba-dropdown__body-wrapper">
<li class="ba-dropdown__body-items">
<div class="ba-input-group ba-input-group-icon--left ba-input-group-icon--right">
<i class="material-symbols-rounded ba-input-group__icon">search</i>
<input type="text"
data-do="search"
data-target="#basic_dropdown"
class="ba-input ba-input--search ba-input--rounded"
placeholder="Search...">
<i class="material-symbols-rounded ba-input--close ba-input-group__icon--right"
style="display: none;">close</i>
</div>
</li>
<div class="ba-dropdown__body-items scroll-thin"
id="basic_dropdown">
<li>
<a class="ba-dropdown__item" href="#" rel="nofollow">
<span class="ba__text handel-over-flow">Sprint 14-0{{i}}-2025Sprint 14-01-2025</span>
<i class="icon material-icons"></i>
</a>
</li>
<li class="no-results hidden">
<a class="ba-dropdown__item" href="#" rel="nofollow">
<span class="ba__text">Ah! That ain't here.</span>
</a>
</li>
</div>
</div>
</ul>
</div>
<div class="dropup ba-dropdown ba-dropdown--multi-dropdown">
<button class="ba-btn ba-btn--secondary"
data-toggle="dropdown">Dropdown</button>
<ul class="dropdown-menu ba-dropdown__menu"
style="--dropdown-width:50rem; --dropdown-max-width: 50rem">
<li class="ba-dropdown__header"
>Move test cases to</li>
<div class="ba-dropdown__body-wrapper">
<ul class="ba-dropdown__sidebar ba-dropdown__body-items">
<li>
<label for="multi_dropdown_option_1"
class="ba-dropdown__item dropdown-select"
data-section="saved">
<span>Saved Filters</span>
<i class="material-icons icon-arrow">chevron_right</i>
</label>
</li>
</ul>
<input type="radio"
name="ba-dropdown-radio" class="ba-dropdown-input visuallyhidden"
id="multi_dropdown_option_{{i}}" checked>
<ul class="ba-dropdown__content">
<li class="ba-dropdown__body-items">
<div class="ba-input-group ba-input-group-icon--left ba-input-group-icon--right">
<i class="material-symbols-rounded ba-input-group__icon"
>search</i>
<input type="text" data-do="search"
data-target="#multi_dropdown_{{i}}"
class="ba-input ba-input--search ba-input--rounded"
placeholder="Search...">
<i class="material-symbols-rounded ba-input--close ba-input-group__icon--right"
style="display: none;">close</i>
</div>
</li>
<div class="ba-dropdown__body-items scroll-thin"
id="multi_dropdown_{{i}}">
<li>
<a class="ba-dropdown__item" href="#"
data-value="bug-critical">
<span class="ba__text">Bug Critical</span>
<i class="material-icons icon">check</i>
</a>
</li>
<li class="no-results hidden">
<a class="ba-dropdown__item" href="#" rel="nofollow">
<span class="ba__text">Ah! That ain't here.</span>
</a>
</li>
</div>
</ul>
</div>
<li class="ba-dropdown__footer-items">
<button class="ba-btn ba-btn--primary">Copy</button>
</li>
</ul>
</div>
Dropdowns provide contextual menus and selectable lists that help users choose from a set of options. They conserve screen space while offering an organized way to present multiple choices.
<!-- Basic dropdown -->
<div class="dropdown ba-dropdown">
<button class="ba-btn ba-btn--secondary" data-toggle="dropdown">
Dropdown Button
</button>
<ul class="dropdown-menu ba-dropdown__menu">
<li class="ba-dropdown__header">Header Text</li>
<div class="ba-dropdown__body-wrapper">
<!-- Search input -->
<li class="ba-dropdown__body-items">
<div class="ba-input-group">
<i class="material-symbols-rounded">search</i>
<input type="text" class="ba-input" placeholder="Search...">
</div>
</li>
<!-- Menu items -->
<div class="ba-dropdown__body-items scroll-thin">
<li>
<a class="ba-dropdown__item" href="#">
<span class="ba__text">Option 1</span>
<i class="material-icons icon">check</i>
</a>
</li>
</div>
</div>
<!-- Optional footer -->
<li class="ba-dropdown__footer-items">
<a class="ba-dropdown__footer-item" href="#">
<span>Create new item</span>
</a>
</li>
</ul>
</div>
<!-- Multi-level dropdown -->
<div class="dropdown ba-dropdown ba-dropdown--multi-dropdown">
<button class="ba-btn ba-btn--secondary" data-toggle="dropdown">
Multi-level Dropdown
</button>
<ul class="dropdown-menu ba-dropdown__menu">
<li class="ba-dropdown__header">Select Category</li>
<div class="ba-dropdown__body-wrapper">
<!-- Sidebar with categories -->
<ul class="ba-dropdown__sidebar ba-dropdown__body-items">
<li>
<label for="option_1" class="ba-dropdown__item">
<span>Category 1</span>
<i class="material-icons icon-arrow">chevron_right</i>
</label>
</li>
</ul>
<!-- Content area -->
<input type="radio" name="dropdown-radio"
class="ba-dropdown-input visuallyhidden"
id="option_1" checked>
<ul class="ba-dropdown__content">
<!-- Search and items for this category -->
</ul>
</div>
</ul>
</div>
| Class | Purpose | Required |
|---|---|---|
.ba-dropdown
|
Wrapper container for dropdown component | Yes |
.ba-dropdown__menu
|
Dropdown panel containing all content | Yes |
.ba-dropdown__header
|
Header section with title/description | Optional |
.ba-dropdown__body-wrapper
|
Main content container | Yes |
.ba-dropdown__body-items
|
Container for dropdown items or search | Yes |
.ba-dropdown__item
|
Individual selectable item | Yes |
.ba-dropdown__footer-items
|
Footer section with actions | Optional |
.ba-dropdown--multi-dropdown
|
Modifier for multi-level dropdown layout | For multi-level |
.ba-dropdown__sidebar
|
Left sidebar for category navigation | For multi-level |
.ba-dropdown__content
|
Right content area for sub-options | For multi-level |
aria-expanded
to indicate dropdown state| Property | Value | Token |
|---|---|---|
| Font Size (Item) | 14px |
var(--Font-Size-4)
|
| Font Size (Header) | 16px |
var(--Font-Size-5)
|
| Font Weight (Regular) | 400 |
var(--Weight-Regular)
|
| Font Weight (Semibold) | 600 |
var(--Weight-SemiBold)
|
| Border Width | 2px |
var(--Stroke-M)
|
| Border Radius | 8px |
var(--Radius-M)
|
| Shadow | 0px 4px 20px rgba(0,0,0,0.1) |
var(--ba-shadow-lg)
|
| Element | Property | Value | Token |
|---|---|---|---|
| Menu Top Margin | margin-top | 4px |
var(--Spacing-S)
|
| Menu Padding | padding | 4px 0 |
var(--Spacing-S)
|
| Item Padding | padding | 8px 16px |
var(--Spacing-L) var(--Spacing-XL)
|
| Item Gap | gap | 8px |
var(--Spacing-L)
|
| Body Items Padding | padding | 24px |
var(--Spacing-2XL)
|
| Body Items Gap | gap | 12px |
var(--Spacing-M)
|
| Body Wrapper Gap | gap | 16px |
var(--Spacing-XL)
|
| Header/Footer Padding | padding | 24px 16px |
var(--Spacing-2XL) var(--Spacing-XL)
|
| Property | Default Value | CSS Variable | Notes |
|---|---|---|---|
| Min Width | 16rem (256px) | - | Minimum dropdown width |
| Default Width | 20rem (320px) |
--dropdown-width
|
Standard dropdown width |
| Max Width | 30rem (480px) |
--dropdown-max-width
|
Maximum dropdown width |
| Scrollable Max Height | 28.571rem (400px) |
--dropdown-max-height
|
Max height for .scroll-thin |
| Multi-level Width Example | 50rem (800px) |
--dropdown-width
|
For complex dropdowns |
| Element | State | Background | Text Color | Border |
|---|---|---|---|---|
| Menu | Closed | - | - | - |
| Open | var(--ba-surface-elevated) | - | var(--ba-border-secondary) | |
| Shadow | 0px 4px 20px rgba(0,0,0,0.1) | |||
| Item | Normal | transparent | var(--ba-text-primary) | - |
| Hover | var(--Surface-Surface-background) | var(--ba-text-primary) | - | |
| Active | var(--ba-surface-secondary) | var(--ba-text-primary) | - | |
| Selected | var(--Surface-Primary) | var(--Text-Primary) | - | |
| Selected Badge | Default | var(--ba-badge-light) | - | - |
| In Selected Item | var(--Primary-Hover-Contrast) | var(--Icons-Primary) | - | |
| Disabled Item | - | transparent (40% opacity) | var(--ba-text-disabled) | - |
| No Results | - | transparent | var(--Neutral-Colors-Tonal-Neutrals-400) | - |
| Header | - | - | var(--Text-High) | bottom: 1px solid var(--Outline-Low) |
| Footer | - | - | var(--Primary-Primary) | top: 1px solid var(--Outline-Low) |
| Property | Duration | Easing | Transform |
|---|---|---|---|
| Open Animation | 0.2s | ease | translateY(-0.714rem) → translateY(0) |
| Opacity | 0.2s | ease | 0 → 1 |
| Visibility | 0.2s | ease | hidden → visible |
| Item Hover | 0.15s | ease | background transition |
| Element | Property | Value |
|---|---|---|
| Body Wrapper | flex-direction | row |
| Sidebar | flex | 50% |
| Sidebar | border-right | 1px solid #e9ecef |
| Content | flex | 50% |
| Content | display (default) | none |
| Content (active) | display | flex |
Small contextual information displays that appear on hover or focus
Simple tooltips on hover
<!-- Tooltip on top -->
<button class="ba-btn ba-btn--secondary" data-toggle="tooltip" data-placement="top" title="Top tooltip">
Top
</button>
<!-- Tooltip on right -->
<button class="ba-btn ba-btn--secondary" data-toggle="tooltip" data-placement="right" title="Right tooltip">
Right
</button>
Tooltips can appear in different positions
<!-- Tooltip on top (white theme) -->
<button class="ba-btn ba-btn--secondary" data-toggle="tooltip" data-placement="top" data-custom-class="ba-tooltip--white" title="Top tooltip">
Top
</button>
<!-- Tooltip on right (white theme) -->
<button class="ba-btn ba-btn--secondary" data-toggle="tooltip" data-placement="right" data-custom-class="ba-tooltip--white" title="Right tooltip">
Right
</button>
Tooltips for icon-only buttons
<button class="ba-btn ba-btn--tertiary ba-btn--icon" data-toggle="tooltip" data-placement="top" title="Edit">
<i class="material-symbols-rounded">edit</i>
</button>
<button class="ba-btn ba-btn--tertiary ba-btn--icon" data-toggle="tooltip" data-placement="bottom" title="Delete">
<i class="material-symbols-rounded">delete</i>
</button>
Tooltips can contain HTML
<!-- Rich text tooltip (Top) -->
<button class="ba-btn ba-btn--primary"
data-toggle="tooltip"
data-placement="top"
data-html="true"
data-custom-class="ba-tooltip--richtext"
title="<strong>This is a tooltip</strong><br>Tooltips are used to describe or identify an element. In most scenarios, tooltips help the user understand meaning, function or alt-text.">
Tooltip Top
</button>
Tooltips provide brief, contextual information when users hover over or focus on an element. They should supplement, not replace, visible labels.
<!-- Basic tooltip -->
<button class="ba-btn ba-btn--secondary" data-toggle="tooltip" data-placement="top" title="Top tooltip">
Top
</button>
<!-- Custom Classes Tooltip -->
<button class="ba-btn ba-btn--secondary" data-toggle="tooltip" data-placement="top" data-custom-class="ba-tooltip--white" title="Top tooltip">
Top
</button>
<!-- Tooltip with HTML -->
<button class="ba-btn ba-btn--primary"
data-toggle="tooltip"
data-placement="top"
data-html="true"
data-custom-class="ba-tooltip--richtext"
title="<strong>This is a tooltip</strong><br>Tooltips are used to describe or identify an element. In most scenarios, tooltips help the user understand meaning, function or alt-text.">
Tooltip Top
</button>
// Initialize Bootstrap tooltips
$(function() {
$('[data-toggle="tooltip"]').tooltip({
delay: { show: 500, hide: 100 },
trigger: 'hover focus'
});
});
// Custom tooltip behavior
$('.ba-tooltip').each(function() {
var $tooltip = $(this);
var $trigger = $tooltip.children().first();
var $text = $tooltip.find('.ba-tooltip__text');
$trigger.on('mouseenter focus', function() {
clearTimeout($tooltip.data('hideTimer'));
var showTimer = setTimeout(function() {
$text.addClass('ba-tooltip__text--visible');
}, 500);
$tooltip.data('showTimer', showTimer);
});
$trigger.on('mouseleave blur', function() {
clearTimeout($tooltip.data('showTimer'));
var hideTimer = setTimeout(function() {
$text.removeClass('ba-tooltip__text--visible');
}, 100);
$tooltip.data('hideTimer', hideTimer);
});
// Dismiss on Esc key
$trigger.on('keydown', function(e) {
if (e.key === 'Escape') {
$text.removeClass('ba-tooltip__text--visible');
}
});
});
// Dynamic tooltip positioning
function positionTooltip($tooltip, $text) {
var triggerRect = $tooltip[0].getBoundingClientRect();
var tooltipRect = $text[0].getBoundingClientRect();
var viewportHeight = window.innerHeight;
var viewportWidth = window.innerWidth;
// Check if tooltip fits above
if (triggerRect.top - tooltipRect.height < 0) {
$tooltip.addClass('ba-tooltip--bottom');
}
// Check if tooltip fits on right
if (triggerRect.right + tooltipRect.width > viewportWidth) {
$tooltip.addClass('ba-tooltip--left');
}
}
role="tooltip" on tooltip contentaria-describedbyaria-label in addition to tooltip<div class="ba-tooltip">
<button class="ba-btn ba-btn--icon"
aria-label="Delete item"
aria-describedby="delete-tooltip">
<i class="material-symbols-rounded">delete</i>
</button>
<span class="ba-tooltip__text"
id="delete-tooltip"
role="tooltip">
Delete this item permanently
</span>
</div>
| Property | Value | Token |
|---|---|---|
| Font Size | 12px / 1.071rem | var(--Body-B5-Medium-Size) |
| Font Weight | 400 | var(--Weight-Regular) |
| Background Color | Neutral-900 | var(--Neutral-Colors-Main-Neutrals-900) |
| Text Color | White | var(--Base-Colors-Base-White) |
| Padding (Vertical) | 6px / 0.536rem | var(--Spacing-M) |
| Padding (Horizontal) | 8px / 0.714rem | var(--Spacing-L) |
| Border Radius | 4px / 0.357rem | var(--Radius-S) |
| Max Width | 200px / 17.857rem | - |
| Position | Offset from Trigger | Arrow Position |
|---|---|---|
| Top (default) | 8px above | Bottom center |
| Right | 8px to right | Left center |
| Bottom | 8px below | Top center |
| Left | 8px to left | Right center |
| Property | Value |
|---|---|
| Arrow Size | 6px / 0.536rem |
| Arrow Color | Neutral-900 (matches background) |
| Arrow Style | CSS triangle using borders |
| Arrow Offset from Edge | Center of trigger element |
| Element | Z-index |
|---|---|
| Tooltip Content | 1000 |
| Tooltip Arrow | 999 |
| State | Animation | Duration | Timing Function |
|---|---|---|---|
| Show | Fade in + translate | 200ms | ease-out |
| Hide | Fade out | 100ms | ease-in |
| Initial State | opacity: 0, translateY(5px) | - | - |
| Visible State | opacity: 1, translateY(0) | - | - |
| Event | Delay |
|---|---|
| Show on Hover | 500ms delay |
| Show on Focus | Immediate (0ms) |
| Hide on Mouse Leave | 100ms delay |
| Hide on Blur | 100ms delay |
| Property | Value |
|---|---|
| Box Shadow | 0 2px 8px rgba(0, 0, 0, 0.15) |
| Border | None |
| Property | Value |
|---|---|
| Line Height | 1.4 |
| Text Align | Center (for short text), Left (for multi-line) |
| Word Wrap | normal |
| White Space | normal |
| Max Width | 200px (wraps to multiple lines if needed) |
| Device | Behavior |
|---|---|
| Desktop | Show on hover and focus |
| Tablet | Show on tap and hold (consider alternatives) |
| Mobile | Avoid tooltips; use visible labels or help icons |
| Touch Devices | Consider using data-toggle for tap-to-show behavior |
File upload component with drag & drop support for attaching multiple files
Simple file upload with drag & drop support
Attachments
<!-- HTML -->
<div id="attachment_files"></div>
<!-- JavaScript -->
<script>
document.addEventListener('DOMContentLoaded', function() {
if (document.getElementById('file-upload-area')) {
var uploader1 = new FileUploadPlugin('file-upload-area', {
maxFileSize: 10,
maxFilesCount: 10,
allowedExtensions: ['png', 'jpg', 'jpeg', 'pdf', 'doc', 'docx'],
dragDropText: 'Drag & Drop files to attach or ',
browseButtonText: 'Browse',
customClass: 'bug__new-files attchment-files-box'
});
window.uploaderExample = uploader1;
}
});
</script>
Attachment upload with custom settings and file types
<!-- JavaScript -->
<script>
document.addEventListener('DOMContentLoaded', function() {
if (document.getElementById('attachment_example_2')) {
var uploader2 = new FileUploadPlugin('attachment_example_2', {
maxFileSize: 5,
maxFilesCount: 5,
allowedExtensions: ['png', 'jpg', 'jpeg'],
title: 'Upload Images',
dragDropText: 'Drop images here or ',
browseButtonText: 'Select Files',
showAttachmentInfo: true,
customClass: 'bug__new-files attchment-files-box'
});
}
});
</script>
The Attachments component provides a user-friendly interface for uploading multiple files with drag & drop support, file validation, and preview functionality.
<!-- Container div -->
<div id="attachment_files"></div>
<!-- Initialize with JavaScript -->
<script>
document.addEventListener('DOMContentLoaded', function() {
if (document.getElementById('file-upload-area')) {
var uploader1 = new FileUploadPlugin('file-upload-area', {
maxFileSize: 10,
maxFilesCount: 10,
allowedExtensions: ['png', 'jpg', 'jpeg', 'pdf', 'doc', 'docx'],
dragDropText: 'Drag & Drop files to attach or ',
browseButtonText: 'Browse',
customClass: 'bug__new-files attchment-files-box'
});
window.uploaderExample = uploader1;
}
});
</script>
| Option | Type | Default | Description |
|---|---|---|---|
maxFileSize |
Number | 10 | Maximum file size in MB |
maxFilesCount |
Number | 10 | Maximum number of files allowed |
allowedExtensions |
Array | ['png', 'jpg', ...] | Array of allowed file extensions |
title |
String | 'Attachments' | Title displayed above upload area |
dragDropText |
String | 'Drag & Drop files...' | Text shown in drag & drop area |
browseButtonText |
String | 'Browse' | Text for browse button |
showAttachmentInfo |
Boolean | true | Show info icon with tooltip |
customClass |
String | '' | Custom CSS class for container |
listClass |
String | '' | Custom CSS class for file list |
| Method | Parameters | Returns | Description |
|---|---|---|---|
getFiles() |
None | Array | Returns array of uploaded File objects |
clearFiles() |
None | void | Clears all uploaded files |
setMaxFileSize(size) |
Number | void | Updates maximum file size in MB |
setMaxFilesCount(count) |
Number | void | Updates maximum files count |
| Validation | Rule | Error Message |
|---|---|---|
| File Extension | Must be in allowed extensions list | "Please choose only valid file types." |
| File Size | Must not exceed maxFileSize | "File size exceeds the limit. Max file size allowed is {size}MB" |
| Files Count | Total files ≤ maxFilesCount | "Sorry, you can upload a maximum {count} files at a time." |
| Duplicate Files | No duplicate file names | File skipped silently |
| Category | Extensions |
|---|---|
| Images | png, jpg, jpeg, gif, bmp, tiff, tif, webp, svg, ico |
| Documents | pdf, doc, docx, odt, rtf |
| Spreadsheets | xls, xlsx, ods, csv |
| Presentations | ppt, pptx, odp |
| Text Files | txt, md, log |
| Archives | zip, rar, 7z, tar, gz |
| Audio | mp3, wav, ogg, flac, aac, m4a |
| Video | mp4, avi, mov, wmv, flv, webm, mkv |
Compact elements for displaying categories, filters, selections, or metadata
Simple Tags for categorization
<span class="ba-tag ba-tag--lg">Design</span>
<span class="ba-tag">Design</span>
<span class="ba-tag ba-tag--sm">Design</span>
Different color variants for different contexts
<span class="ba-tag ba-tag--primary">Primary</span>
<span class="ba-tag ba-tag--secondary">Secondary</span>
<span class="ba-tag ba-tag--success">Success</span>
<span class="ba-tag ba-tag--warning">Warning</span>
<span class="ba-tag ba-tag--danger">Danger</span>
<span class="ba-tag ba-tag--info">Info</span>
<span class="ba-tag ba-tag--accent">Accent</span>
Border-style tags for emphasis
<span class="ba-tag ba-tag--outlined ba-tag--primary">Primary</span>
<span class="ba-tag ba-tag--outlined ba-tag--secondary">Secondary</span>
<span class="ba-tag ba-tag--outlined ba-tag--success">Success</span>
Border-style tags for emphasis
<span class="ba-tag ba-tag--lg ba-tag--plain ba-tag--neutral">Neutral</span>
<span class="ba-tag ba-tag--lg ba-tag--plain ba-tag--primary">Primary</span>
<span class="ba-tag ba-tag--lg ba-tag--plain ba-tag--secondary">Secondary</span>
Add icons for visual context
<!-- Tag with left icon -->
<span class="ba-tag">
<i class="material-symbols-rounded icon">tag</i>
<span>Tag</span>
</span>
<!-- Tag with right icon -->
<span class="ba-tag ba-tag--success">
<span>Completed</span>
<i class="material-symbols-rounded icon">check_circle</i>
</span>
<!-- Tag with avatar -->
<span class="ba-tag">
<div class="ba-avatar ba-avatar--xs">
<span class="ba-avatar__initials">JD</span>
</div>
<span>John Doe</span>
</span>
Tags with close button for removal
<span class="ba-tag ba-tag--dismissible">
<span>Design</span>
<button class="ba-tag__close" title="Remove">
<i class="material-symbols-rounded">close</i>
</button>
</span>
Interactive tags for filtering or selection
<button class="ba-tag ba-tag--clickable">All</button>
<button class="ba-tag ba-tag--clickable active">Active</button>
<button class="ba-tag ba-tag--clickable">Completed</button>
Demo of filter functionality with removal
Active Filters:
<div class="ba-tag-group">
<span class="ba-tag ba-tag--primary ba-tag--dismissible">
<span>Transaction</span>
<button class="ba-tag__close">
<i class="material-symbols-rounded">close</i>
</button>
</span>
</div>
Different tag group spacing options
<!-- Default -->
<div class="ba-tag-group">...</div>
<!-- Tight -->
<div class="ba-tag-group ba-tag-group--tight">...</div>
<!-- Spacious -->
<div class="ba-tag-group ba-tag-group--spacious">...</div>
Tags are compact elements that represent an input, attribute, or action. They allow users to enter information, make selections, filter content, or trigger actions.
<!-- Basic Tag -->
<span class="ba-tag ba-tag--[variant] ba-tag--[size]">
Tag Text
</span>
<!-- Tag with icon -->
<span class="ba-tag ba-tag--[variant]">
<i class="material-symbols-rounded">icon_name</i>
<span>Tag Text</span>
</span>
<!-- Dismissible Tag -->
<span class="ba-tag ba-tag--dismissible ba-tag--[variant]">
<span>Tag Text</span>
<button class="ba-tag__close" title="Remove" aria-label="Remove Tag Text">
<i class="material-symbols-rounded">close</i>
</button>
</span>
<!-- Clickable Tag -->
<button class="ba-tag ba-tag--clickable">
Tag Text
</button>
<!-- Tag with avatar -->
<span class="ba-tag">
<div class="ba-avatar ba-avatar--xs">
<span class="ba-avatar__initials">JD</span>
</div>
<span>John Doe</span>
</span>
// Handle Tag dismissal
$('.ba-tag__close').on('click', function(e) {
e.stopPropagation();
$(this).closest('.ba-tag').fadeOut(200, function() {
$(this).remove();
// Trigger custom event or callback
$(document).trigger('tag:removed', { tag: this });
});
});
// Handle clickable tag selection
$('.ba-tag--clickable').on('click', function() {
// Toggle selected state
$(this).toggleClass('active');
// Or make exclusive selection
$(this).addClass('active')
.siblings('.ba-tag--clickable')
.removeClass('active');
});
<button> element for clickable and dismissible tagsrole="listbox" for chip groups with selection<div role="listbox" aria-label="Selected filters">
<span class="ba-tag ba-tag--dismissible" role="option">
<span>Design</span>
<button class="ba-tag__close"
title="Remove Design filter"
aria-label="Remove Design filter">
<i class="material-symbols-rounded">close</i>
</button>
</span>
</div>
<div aria-live="polite" aria-atomic="true" class="sr-only">
<!-- Announce removals here -->
</div>
| Property | Value | Token |
|---|---|---|
| Font Size | 12px / 1.071rem | var(--Body-B5-Medium-Size) |
| Font Weight | 500 | var(--Weight-Medium) |
| Border Radius | 8px / 0.714rem | var(--Radius-M) |
| Icon Size | 16px / 1.143rem | - |
| Icon Gap | 6px / 0.536rem | var(--Spacing-M) |
| Size | Class | Padding | Font Size | Height |
|---|---|---|---|---|
| Large | .ba-tag--lg |
6px / 12px | 14px | 32px |
| Default | - | 4px / 8px | 12px | 24px |
| Small | .ba-tag--sm |
2px / 6px | 11px | 20px |
| Variant | Background | Text Color | Border (if any) |
|---|---|---|---|
| Neutral | Neutral-100 | Neutral-900 | - |
| Primary | Primary-100 | Primary-900 | - |
| Success | Success-100 | Success-900 | - |
| Warning | Warning-100 | Warning-900 | - |
| Danger | Error-100 | Error-900 | - |
| Info | Info-100 | Info-900 | - |
| State | Visual Change |
|---|---|
| Default | Normal variant colors |
| Hover (clickable) | Background opacity: 0.8, cursor: pointer |
| Selected | Border: 2px variant color, background darker |
| Focus | Outline: 2px variant color |
| Disabled | Opacity: 0.5, cursor: not-allowed |
| Property | Value |
|---|---|
| Icon Size | 14px / 1.25rem |
| Button Size | 16px × 16px |
| Touch Target | 20px × 20px (with padding) |
| Margin Left | 4px / 0.357rem |
| Hover State | Opacity: 0.7 |
| Background | Transparent |
| Border | None |
| Context | Horizontal Gap | Vertical Gap |
|---|---|---|
| Tag group (inline) | 8px / 0.714rem | 8px / 0.714rem |
| Tag group (tight) | 4px / 0.357rem | 4px / 0.357rem |
| Tag group (spacious) | 12px / 1.071rem | 12px / 1.071rem |
