ux4g-components-web
v1.4.1
Published
UX4G Design System — CSS bundle, design tokens, utilities, and shared Class_Builder types
Readme
ux4g-components-web
CSS bundle, design tokens, utilities, shared types, and runtime module for the UX4G Design System.
This is the foundation package — it provides the complete CSS system that powers all UX4G components. Framework wrappers (ux4g-components-react, ux4g-components-angular) depend on this package for styles and Class_Builder types.
Installation
npm install ux4g-components-webQuick Start
HTML / CSS
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="node_modules/ux4g-components-web/styles/ux4g.css" />
</head>
<body>
<button class="ux4g-btn-primary ux4g-btn-md">Save</button>
</body>
</html>JavaScript / TypeScript bundler
import 'ux4g-components-web/styles.css';CSS @import
@import 'ux4g-components-web/styles.css';Available Exports
| Export Path | Description |
|---|---|
| ux4g-components-web/styles.css | Pre-built CSS bundle (~7 MB, fonts embedded as base64) |
| ux4g-components-web/types | Class_Builder functions and TypeScript types |
| ux4g-components-web/runtime | initRuntime() / destroyRuntime() — explicit control |
| ux4g-components-web/runtime/bootstrap | Side-effect import — auto-initializes runtime on import |
CSS Bundle
The bundle includes all layers in the correct cascade order:
- Reset — browser normalization
- Tokens — CSS custom properties (primitive values)
- Semantic — semantic aliases (
--ux4g-bg-primary-strong, etc.) - Foundations — fonts and icons (base64-embedded)
- Utilities — 27 single-purpose helper class modules
- Components — approved component CSS
- Layout — container, flex-grid, grid utilities
- Cascade Fixes — vendor specificity overrides
Component Examples (Plain HTML/CSS)
Button
<!-- Primary button -->
<button class="ux4g-btn-primary ux4g-btn-md">Save</button>
<!-- Outline danger, large -->
<button class="ux4g-btn-outline-danger ux4g-btn-lg">Delete</button>
<!-- Tonal primary, pill shape, small -->
<button class="ux4g-btn-tonal-primary ux4g-btn-sm ux4g-btn-pill">Tag</button>
<!-- Disabled state -->
<button class="ux4g-btn-primary ux4g-btn-md ux4g-btn-disabled" disabled>Disabled</button>
<!-- Loading state -->
<button class="ux4g-btn-primary ux4g-btn-md ux4g-btn-loading">
<span class="ux4g-btn-spinner" aria-hidden="true"></span>
Saving...
</button>Available classes:
- Variants:
ux4g-btn-primary,ux4g-btn-outline-primary,ux4g-btn-text-primary,ux4g-btn-tonal-primary,ux4g-btn-danger,ux4g-btn-outline-danger,ux4g-btn-text-danger,ux4g-btn-tonal-danger - Sizes:
ux4g-btn-xl,ux4g-btn-lg,ux4g-btn-md,ux4g-btn-sm,ux4g-btn-xs - Modifiers:
ux4g-btn-pill,ux4g-btn-disabled,ux4g-btn-loading
Spinner
<!-- Primary full spinner, medium (default) -->
<span class="ux4g-spinner-primary-full" role="status" aria-label="Loading"></span>
<!-- Danger split spinner, large -->
<span class="ux4g-spinner-danger-split ux4g-spinner-lg" role="status" aria-label="Loading"></span>
<!-- Inverse partial spinner, extra small -->
<span class="ux4g-spinner-inverse-partial ux4g-spinner-xs" role="status" aria-label="Loading"></span>Pattern: ux4g-spinner-{variant}-{type} + optional ux4g-spinner-{size}
- Variants:
primary,inverse,danger - Types:
full,split,partial - Sizes:
ux4g-spinner-xl,ux4g-spinner-lg,ux4g-spinner-sm,ux4g-spinner-xs(md is default, no class needed)
Link
<!-- Default link, medium -->
<a href="#" class="ux4g-text-link-md">Learn more</a>
<!-- Neutral link, small -->
<a href="#" class="ux4g-text-link-neutral-sm">View details</a>Pattern: ux4g-text-link-{size} or ux4g-text-link-neutral-{size}
- Variants:
default,neutral - Sizes:
sm,md
Badge
<!-- Dot badge, primary -->
<span class="ux4g-badge-dot-primary"></span>
<!-- Digit badge, danger, medium -->
<span class="ux4g-badge-digit-danger ux4g-badge-m">5</span>
<!-- Icon badge, success, large -->
<span class="ux4g-badge-icon-success ux4g-badge-l">
<i class="ux4g-icon-check"></i>
</span>Pattern: ux4g-badge-{type}-{color} + optional ux4g-badge-{size}
- Types:
dot,icon,digit - Colors:
primary,success,warning,danger,info,secondary,tertiary,neutral - Sizes:
s,m,l,profile-l,profile-xl,profile-2xl,profile-3xl
Avatar
<!-- Status avatar, medium -->
<div class="ux4g-avatar ux4g-avatar-status ux4g-avatar-m">
<img src="user.jpg" alt="User" />
</div>
<!-- Profile avatar, large -->
<div class="ux4g-avatar ux4g-avatar-profile ux4g-avatar-l">
<img src="profile.jpg" alt="Profile" />
</div>
<!-- Avatar group -->
<div class="ux4g-avatar-group">
<div class="ux4g-avatar ux4g-avatar-status ux4g-avatar-s"><img src="u1.jpg" alt="" /></div>
<div class="ux4g-avatar ux4g-avatar-status ux4g-avatar-s"><img src="u2.jpg" alt="" /></div>
</div>Pattern: ux4g-avatar ux4g-avatar-{type} + optional ux4g-avatar-{size}
- Types:
status,profile,group - Sizes:
xs,s,m,l,xl,2xl,3xl
Image
<!-- Basic image with ratio -->
<div class="ux4g-ratio-16-9">
<img src="photo.jpg" alt="Photo" />
</div>
<!-- Rounded image with overlay -->
<div class="ux4g-img-overlay ux4g-img-rounded ux4g-ratio-4-3">
<img src="photo.jpg" alt="Photo" />
<div class="ux4g-img-overlay-content">Caption</div>
</div>Classes: ux4g-img-overlay, ux4g-img-rounded, ux4g-ratio-{ratio}
- Ratios:
1-1,4-3,3-2,16-10,16-9,2-1,5-2,3-1,1-16,2-3,3-4
Chip
<!-- Filter chip, medium -->
<button class="ux4g-filter-chip-md">Category</button>
<!-- Choice chip, small, active -->
<button class="ux4g-choice-chip-sm active">Selected</button>
<!-- Input chip, extra small -->
<span class="ux4g-input-chip-xs">Tag <button class="ux4g-chip-close">×</button></span>Pattern: ux4g-{type}-chip-{size} + optional active
- Types:
filter,choice,input - Sizes:
md,sm,xs(xs only valid for input chips)
Tag
<!-- Tonal neutral tag -->
<span class="ux4g-tag-tonal-neutral">Default</span>
<!-- Filled success tag, small -->
<span class="ux4g-tag-filled-success ux4g-tag-s">Active</span>
<!-- Outline error tag -->
<span class="ux4g-tag-outline-error">Error</span>Pattern: ux4g-tag-{variant}-{color} + optional ux4g-tag-s
- Variants:
tonal,filled,outline,text - Colors:
neutral,brand,success,warning,error,info
Divider
<!-- Horizontal divider -->
<hr class="ux4g-divider-horizontal" />
<!-- Vertical divider -->
<div class="ux4g-divider-vertical"></div>Breadcrumb
<!-- Breadcrumb with divider separator -->
<nav class="ux4g-breadcrumb ux4g-breadcrumb-divider">
<a href="#">Home</a>
<a href="#">Products</a>
<span>Current Page</span>
</nav>
<!-- Breadcrumb with icon separator -->
<nav class="ux4g-breadcrumb ux4g-breadcrumb-icon">
<a href="#">Home</a>
<a href="#">Category</a>
<span>Item</span>
</nav>Checkbox
<!-- Medium checkbox -->
<label class="ux4g-checkbox ux4g-checkbox-md">
<input type="checkbox" />
<span>Accept terms</span>
</label>
<!-- Small checkbox with error -->
<label class="ux4g-checkbox ux4g-checkbox-sm ux4g-checkbox-error">
<input type="checkbox" />
<span>Required field</span>
</label>Sizes: ux4g-checkbox-sm, ux4g-checkbox-md, ux4g-checkbox-lg
Radio
<!-- Medium radio -->
<label class="ux4g-radio ux4g-radio-md">
<input type="radio" name="option" />
<span>Option A</span>
</label>
<!-- Large radio with error -->
<label class="ux4g-radio ux4g-radio-lg ux4g-radio-error">
<input type="radio" name="option" />
<span>Option B</span>
</label>Sizes: ux4g-radio-sm, ux4g-radio-md, ux4g-radio-lg
Switch
<!-- Medium switch -->
<label class="ux4g-switch ux4g-switch-md">
<input type="checkbox" role="switch" />
<span>Enable notifications</span>
</label>Sizes: ux4g-switch-sm, ux4g-switch-md, ux4g-switch-lg
Card
<!-- Solid vertical card -->
<div class="ux4g-card ux4g-card-solid ux4g-card-vertical">
<div class="ux4g-card-header">Title</div>
<div class="ux4g-card-body">Content goes here.</div>
<div class="ux4g-card-footer">Footer</div>
</div>
<!-- Outline horizontal card -->
<div class="ux4g-card ux4g-card-outline ux4g-card-horizontal">
<img src="thumb.jpg" alt="" />
<div class="ux4g-card-body">Horizontal layout</div>
</div>Variants: ux4g-card-solid, ux4g-card-outline, ux4g-card-no-fill
Layouts: ux4g-card-vertical, ux4g-card-horizontal
Input
<!-- Medium input, default state -->
<div class="ux4g-input-container ux4g-input-md ux4g-input-default">
<label>Email</label>
<input type="email" placeholder="Enter email" />
</div>
<!-- Large input, error state -->
<div class="ux4g-input-container ux4g-input-lg ux4g-input-error">
<label>Password</label>
<input type="password" />
<span class="ux4g-input-helper">Password is required</span>
</div>Sizes: ux4g-input-sm, ux4g-input-md, ux4g-input-lg, ux4g-input-xl
States: ux4g-input-default, ux4g-input-error, ux4g-input-success, ux4g-input-warning
List
<ul class="ux4g-list ux4g-list-default ux4g-list-m">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>Variants: ux4g-list-default, ux4g-list-error, ux4g-list-success, ux4g-list-warning
Sizes: ux4g-list-s, ux4g-list-m, ux4g-list-l, ux4g-list-xl
Dropdown
<div class="ux4g-dropdown ux4g-dropdown-selection ux4g-dropdown-single ux4g-dropdown-md ux4g-dropdown-default">
<button data-ux-toggle="dropdown" aria-expanded="false">Select option</button>
<ul class="dropdown-menu">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
</div>Types: ux4g-dropdown-selection, ux4g-dropdown-button, ux4g-dropdown-overflow
Modes: ux4g-dropdown-single, ux4g-dropdown-multi
Sizes: ux4g-dropdown-sm, ux4g-dropdown-md, ux4g-dropdown-lg
States: ux4g-dropdown-default, ux4g-dropdown-error, ux4g-dropdown-success, ux4g-dropdown-warning
Open state: is-open
Combobox
<div class="ux4g-combobox ux4g-combobox-single ux4g-combobox-md ux4g-combobox-default">
<input type="text" role="combobox" aria-expanded="false" placeholder="Search..." />
<ul class="dropdown-menu" role="listbox">
<li role="option">Result 1</li>
<li role="option">Result 2</li>
</ul>
</div>Types: ux4g-combobox-single, ux4g-combobox-multi
Sizes: ux4g-combobox-sm, ux4g-combobox-md, ux4g-combobox-lg
States: ux4g-combobox-default, ux4g-combobox-error, ux4g-combobox-success, ux4g-combobox-warning
Modal
<!-- Trigger -->
<button data-ux-toggle="modal" data-ux-target="#myModal">Open Modal</button>
<!-- Modal -->
<div id="myModal" class="ux4g-modal-backdrop ux4g-modal-backdrop-50" role="dialog" aria-modal="true">
<div class="ux4g-modal-box ux4g-modal-m">
<div class="ux4g-modal-header">
<h2>Title</h2>
<button data-ux-dismiss="modal">×</button>
</div>
<div class="ux4g-modal-body">Content here</div>
<div class="ux4g-modal-footer">
<button class="ux4g-btn-primary ux4g-btn-md">Confirm</button>
</div>
</div>
</div>Backdrop: ux4g-modal-backdrop-25, ux4g-modal-backdrop-50, ux4g-modal-backdrop-75
Blur: ux4g-modal-backdrop-blur
Sizes: ux4g-modal-s, ux4g-modal-m, ux4g-modal-l
Center content: ux4g-modal-center-content
Alert / Toast
<!-- Inline alert -->
<div class="ux4g-alert ux4g-alert-info">
<span>This is an informational message.</span>
</div>
<!-- Context alert -->
<div class="ux4g-context-alert ux4g-alert-warning">
<span>Warning: Check your input.</span>
</div>
<!-- Alert container (for toast positioning) -->
<div class="ux4g-alert-container ux4g-alert-top-right">
<div class="ux4g-alert ux4g-alert-success">Saved successfully!</div>
</div>Variants: ux4g-alert-info, ux4g-alert-success, ux4g-alert-warning, ux4g-alert-error
Layouts: ux4g-alert-center, ux4g-alert-wide
Positions: ux4g-alert-top-left, ux4g-alert-top-right, ux4g-alert-bottom-left, ux4g-alert-bottom-right
Search
<div class="ux4g-search-container ux4g-search-m">
<input type="search" placeholder="Search..." />
<button class="ux4g-search-btn" aria-label="Search">
<i class="ux4g-icon-search"></i>
</button>
</div>Sizes: ux4g-search-s, ux4g-search-m, ux4g-search-lg
Pagination
<!-- Default pagination -->
<nav class="ux4g-pagination">
<button class="ux4g-pagination-prev">«</button>
<button class="active">1</button>
<button>2</button>
<button>3</button>
<button class="ux4g-pagination-next">»</button>
</nav>
<!-- Dotted pagination, solid style -->
<nav class="ux4g-pagination ux4g-pagination-dotted ux4g-pagination-solid">
<span class="active"></span>
<span></span>
<span></span>
</nav>Variants: default, ux4g-pagination-dotted
Styles (dotted only): ux4g-pagination-solid, ux4g-pagination-translucent
Table
<table class="ux4g-table ux4g-table-m">
<thead>
<tr><th>Name</th><th>Email</th><th>Role</th></tr>
</thead>
<tbody>
<tr><td>Alice</td><td>[email protected]</td><td>Admin</td></tr>
<tr><td>Bob</td><td>[email protected]</td><td>User</td></tr>
</tbody>
</table>
<!-- Interactive table with zebra rows and column dividers -->
<table class="ux4g-table ux4g-table-s ux4g-table-column-dividers ux4g-table-zebra-rows ux4g-table-interactive">
...
</table>Sizes: ux4g-table-s, ux4g-table-m, ux4g-table-lg
Dividers: ux4g-table-column-dividers, ux4g-table-no-row-dividers
Zebra: ux4g-table-zebra-rows, ux4g-table-zebra-cols
Modifiers: ux4g-table-interactive, ux4g-table-sortable, ux4g-table-resizable, ux4g-table-header-brand
Popover
<button data-ux-toggle="popover" data-ux-content="Popover body text" data-ux-title="Popover Title" data-ux-placement="right">
Show Popover
</button>Placements: top, top-start, top-end, bottom, bottom-start, bottom-end, left, left-start, left-end, right, right-start, right-end
Tooltip
<button data-ux-toggle="tooltip" data-ux-content="Tooltip text" data-ux-placement="top" title="Tooltip text">
Hover me
</button>Placements: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right, left-center, right-center
Sizes: ux4g-tooltip-s, ux4g-tooltip-xs
Tab
<div class="ux4g-tab ux4g-tab-underline ux4g-tab-md">
<nav class="nav" role="tablist">
<button role="tab" data-ux-toggle="tab" data-ux-target="#tab1" class="active" aria-selected="true">Tab 1</button>
<button role="tab" data-ux-toggle="tab" data-ux-target="#tab2">Tab 2</button>
</nav>
<div class="tab-content">
<div id="tab1" class="tab-pane active show">Content 1</div>
<div id="tab2" class="tab-pane">Content 2</div>
</div>
</div>Variants: ux4g-tab-underline, ux4g-tab-pill
Sizes: ux4g-tab-sm, ux4g-tab-md, ux4g-tab-lg
Vertical: ux4g-tab-vertical
Icon Button
<button class="ux4g-icon-btn ux4g-icon-btn-primary ux4g-icon-btn-md">
<i class="ux4g-icon-edit"></i>
</button>
<!-- Pill icon button -->
<button class="ux4g-icon-btn ux4g-icon-btn-tonal-primary ux4g-icon-btn-lg ux4g-icon-btn-pill">
<i class="ux4g-icon-plus"></i>
</button>Variants: ux4g-icon-btn-primary, ux4g-icon-btn-outline-primary, ux4g-icon-btn-tonal-primary, ux4g-icon-btn-text-primary
Sizes: ux4g-icon-btn-xl, ux4g-icon-btn-lg, ux4g-icon-btn-md, ux4g-icon-btn-sm, ux4g-icon-btn-xs
Pill: ux4g-icon-btn-pill
Accessibility Bar
<div class="ux4g-topbar">
<a href="#main-content" class="ux4g-skip-link">Skip to main content</a>
<!-- Additional accessibility controls -->
</div>Accordion
<div class="ux4g-accordion ux4g-accordion-arrow-right">
<div class="ux4g-accordion-item">
<button data-ux-toggle="collapse" data-ux-target="#acc1" aria-expanded="false">
Section 1
</button>
<div id="acc1" class="collapse">
<div class="ux4g-accordion-body">Content for section 1</div>
</div>
</div>
</div>
<!-- Bordered variant with left arrow -->
<div class="ux4g-accordion ux4g-accordion-arrow-left ux4g-accordion-bordered">
...
</div>Arrow position: ux4g-accordion-arrow-right, ux4g-accordion-arrow-left
Variant: ux4g-accordion-bordered
Stepper
<!-- Horizontal stepper -->
<div class="ux4g-stepper">
<div class="ux4g-stepper-step completed">Step 1</div>
<div class="ux4g-stepper-step active">Step 2</div>
<div class="ux4g-stepper-step">Step 3</div>
</div>
<!-- Vertical stepper, small -->
<div class="ux4g-stepper ux4g-stepper-vertical ux4g-stepper-s">
...
</div>
<!-- Horizontal centered with bottom-line variant -->
<div class="ux4g-stepper ux4g-stepper-horizontal ux4g-stepper-center ux4g-stepper-bottom-line">
...
</div>Orientation: ux4g-stepper-vertical, ux4g-stepper-horizontal
Alignment: ux4g-stepper-center, ux4g-stepper-left
Variants: ux4g-stepper-bottom-line, ux4g-stepper-bottom-line-fill, ux4g-stepper-mobile, ux4g-stepper-progress
Size: ux4g-stepper-s
Slider
<div class="ux4g-slider-field">
<input type="range" min="0" max="100" value="50" />
</div>
<!-- Medium slider -->
<div class="ux4g-slider-field ux4g-slider-md">
<input type="range" min="0" max="100" value="75" />
</div>Sizes: default (sm), ux4g-slider-md
Drawer
<!-- Trigger -->
<button data-ux-toggle="offcanvas" data-ux-target="#drawer1">Open Drawer</button>
<!-- Drawer -->
<div id="drawer1" class="ux4g-drawer ux4g-drawer-right">
<div class="ux4g-drawer-header">
<h3>Drawer Title</h3>
<button data-ux-dismiss="offcanvas">×</button>
</div>
<div class="ux4g-drawer-body">Drawer content</div>
</div>Placements: ux4g-drawer-right, ux4g-drawer-left, ux4g-drawer-top, ux4g-drawer-bottom
Open state: ux4g-drawer-open
Date-Time Picker
<!-- Date picker -->
<div class="ux4g-date-picker-container">
<input type="date" />
</div>
<!-- Time picker -->
<div class="ux4g-time-picker-container">
<input type="time" />
</div>Status Pipeline
<div class="ux4g-status-pipeline-stepper">
<div class="ux4g-status-pipeline-step completed">Submitted</div>
<div class="ux4g-status-pipeline-step active">In Review</div>
<div class="ux4g-status-pipeline-step">Approved</div>
</div>
<!-- Vertical status pipeline -->
<div class="ux4g-status-pipeline-stepper ux4g-status-pipeline-vertical">
...
</div>Orientation: ux4g-status-pipeline-vertical, ux4g-status-pipeline-horizontal
Alignment: ux4g-status-pipeline-center, ux4g-status-pipeline-left
Variants: ux4g-status-pipeline-bottom-line, ux4g-status-pipeline-bottom-line-fill, ux4g-status-pipeline-mobile, ux4g-status-pipeline-progress
Size: ux4g-status-pipeline-s
Journey Timeline
<!-- Vertical timeline (default) -->
<div class="ux4g-journey-timeline ux4g-journey-timeline--vertical">
<div class="ux4g-journey-timeline-item">
<div class="ux4g-journey-timeline-marker"></div>
<div class="ux4g-journey-timeline-content">Event 1</div>
</div>
</div>
<!-- Horizontal timeline -->
<div class="ux4g-journey-timeline ux4g-journey-timeline--horizontal">
...
</div>Form Field Group
<div class="ux4g-form-group">
<label>Full Name</label>
<input type="text" class="ux4g-input-md" />
<span class="ux4g-form-helper">Enter your full legal name</span>
</div>OTP Input
<!-- Default OTP -->
<div class="ux4g-otp">
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
</div>
<!-- Error state -->
<div class="ux4g-otp ux4g-otp-error">
...
</div>States: default, ux4g-otp-success, ux4g-otp-error, ux4g-otp-locked
File Upload
<div class="ux4g-upload ux4g-upload-state-default">
<input type="file" />
<span>Drag & drop or click to upload</span>
</div>
<!-- Uploaded state -->
<div class="ux4g-upload ux4g-upload-state-uploaded">
<span>document.pdf</span>
<button class="ux4g-upload-remove">×</button>
</div>States: ux4g-upload-state-default, ux4g-upload-state-default-vle, ux4g-upload-state-selecting, ux4g-upload-state-scanning, ux4g-upload-state-uploaded, ux4g-upload-state-uploaded-vle, ux4g-upload-state-error
Progress Indicator
<!-- Bar progress -->
<div class="ux4g-progress-bar">
<div class="ux4g-progress-bar-fill" style="width: 60%"></div>
</div>
<!-- Circle progress -->
<div class="ux4g-progress-circle">
<svg><!-- circle SVG --></svg>
</div>Types: ux4g-progress-bar, ux4g-progress-circle
Feedback
<div class="ux4g-feedback">
<p>Was this helpful?</p>
<button>Yes</button>
<button>No</button>
</div>Draft Status Banner
<!-- Default -->
<div class="ux4g-daft-staus-bar">Draft saved</div>
<!-- Auto-save variant -->
<div class="ux4g-auto-daft-staus-bar">Auto-saving...</div>
<!-- Success variant -->
<div class="ux4g-success-daft-staus-bar">Published successfully</div>SLA Progress Indicator
<!-- Circle SLA -->
<div class="ux4g-sla-circle">
<span>75%</span>
</div>
<!-- Linear SLA -->
<div class="ux4g-sla-linear">
<div class="ux4g-sla-fill" style="width: 75%"></div>
</div>
<!-- Badge SLA -->
<span class="ux4g-sla-badge">On Track</span>Types: ux4g-sla-circle, ux4g-sla-linear, ux4g-sla-badge
Carousel
<div class="ux4g-carousel" data-ux-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">Slide 1</div>
<div class="carousel-item">Slide 2</div>
<div class="carousel-item">Slide 3</div>
</div>
<button data-ux-slide="prev">Prev</button>
<button data-ux-slide="next">Next</button>
</div>Empty State
<div class="ux4g-empty-state">
<img src="empty-illustration.svg" alt="" />
<h3>No results found</h3>
<p>Try adjusting your search or filters.</p>
<button class="ux4g-btn-primary ux4g-btn-md">Reset Filters</button>
</div>Chip Group
<!-- Filter chip group -->
<div class="ux4g-filter-chip-group">
<button class="ux4g-filter-chip-md active">All</button>
<button class="ux4g-filter-chip-md">Category A</button>
<button class="ux4g-filter-chip-md">Category B</button>
</div>
<!-- Choice chip group -->
<div class="ux4g-choice-chip-group">
<button class="ux4g-choice-chip-md active">Option 1</button>
<button class="ux4g-choice-chip-md">Option 2</button>
</div>Navbar
<nav class="ux4g-navbar">
<a href="/" class="ux4g-navbar-brand">Logo</a>
<ul class="ux4g-navbar-nav">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>Social Links
<div class="ux4g-d-flex ux4g-gap-s">
<a href="#" aria-label="Twitter"><i class="ux4g-icon-twitter"></i></a>
<a href="#" aria-label="LinkedIn"><i class="ux4g-icon-linkedin"></i></a>
<a href="#" aria-label="GitHub"><i class="ux4g-icon-github"></i></a>
</div>Size via gap: ux4g-gap-xs (sm), ux4g-gap-s (md), ux4g-gap-m (lg)
Slot Grid
<!-- Weekly slot grid -->
<div class="ux4g-time-slot-weekly-container">
<div class="ux4g-time-slot">9:00 AM</div>
<div class="ux4g-time-slot">10:00 AM</div>
</div>
<!-- Compact slot grid -->
<div class="ux4g-time-slot-compact-container">
<div class="ux4g-time-slot">9:00</div>
<div class="ux4g-time-slot">9:30</div>
</div>Footer
<footer class="ux4g-footer-primary">
<div class="ux4g-footer-content">
<p>© 2024 Company Name</p>
</div>
</footer>Themes: default (no class), ux4g-footer-primary, ux4g-footer-dark
Result List Row
<div class="ux4g-result-list">
<div class="ux4g-result-list-item">
<h4>Result Title</h4>
<p>Description text</p>
</div>
</div>
<!-- Variation v2 -->
<div class="ux4g-result-list ux4g-result-list-v2">
...
</div>Variations: default, ux4g-result-list-v1, ux4g-result-list-v2, ux4g-result-list-v3, ux4g-result-list-v4, ux4g-result-list-v5
Runtime Module
The runtime module provides interactive behaviors (dropdowns, modals, tooltips, accordions, carousels, drawers, tabs) without requiring React or Angular. It uses event delegation on document — no per-element binding needed.
Explicit Initialization (recommended for apps that need control)
import { initRuntime, destroyRuntime } from 'ux4g-components-web/runtime';
// Call once at app startup
initRuntime();
// Call for cleanup (testing, SSR teardown)
destroyRuntime();Auto-Bootstrap (side-effect import)
import 'ux4g-components-web/runtime/bootstrap';
// Runtime is initialized immediately on importBehaviors Provided
| Behavior | Data Attribute | Description |
|---|---|---|
| Dropdown | data-ux-toggle="dropdown" | Toggle dropdown menus |
| Modal | data-ux-toggle="modal" | Open/close modals with escape/backdrop |
| Tooltip | data-ux-toggle="tooltip" | Show/hide on hover/focus |
| Popover | data-ux-toggle="popover" | Show/hide on click |
| Collapse | data-ux-toggle="collapse" | Expand/collapse sections |
| Tab | data-ux-toggle="tab" | Switch tab panels |
| Carousel | data-ux-ride="carousel" | Auto-slide, next/prev controls |
| Offcanvas/Drawer | data-ux-toggle="offcanvas" | Slide-in panels |
| Toast | .toast | Auto-hide notifications |
| ScrollSpy | data-ux-spy="scroll" | Highlight nav on scroll |
Design Notes
- Singleton guard:
window.__UX4G_RUNTIME_INITIALIZED__prevents duplicate initialization - SSR-safe: No-ops when
window/documentare unavailable - Event delegation: All listeners attached to
document - Cleanup:
destroyRuntime()removes all listeners and resets the guard
Shared Types (Class_Builder)
Framework wrappers import Class_Builder functions from this package to map typed props to CSS class strings:
import { buildButtonClasses, ButtonVariant, ButtonSize } from 'ux4g-components-web/types';
const classes = buildButtonClasses('primary', 'md', false, false);
// → "ux4g-btn-primary ux4g-btn-md"Custom Integrations
You can use Class_Builder functions in any framework (Vue, Svelte, vanilla JS):
import { buildCardClasses } from 'ux4g-components-web/types';
import { buildSpinnerClasses } from 'ux4g-components-web/types';
// Use in a Vue component
const cardClass = buildCardClasses('outline', 'horizontal');
// → "ux4g-card ux4g-card-outline ux4g-card-horizontal"
const spinnerClass = buildSpinnerClasses('primary', 'lg', 'full');
// → "ux4g-spinner-primary-full ux4g-spinner-lg"Utility Classes
Use utility classes directly in HTML — no wrapper component needed:
<div class="ux4g-d-flex ux4g-gap-4 ux4g-p-m ux4g-bg-primary-soft ux4g-radius-md">
<span class="ux4g-body-m-default ux4g-text-neutral-primary">Content</span>
</div>Available Utility Categories (27 modules)
| Category | Modules |
|---|---|
| Typography & Text | typography, typescale, colors, text-transform, vertical-align |
| Layout & Spacing | spacing, sizing, gap, object-fit, overflow, position, z-index, visibility, display, display-responsive |
| Flexbox & Grid | flex, flex-responsive, align, justify, order |
| Visual Effects | background, border, radius, shadow, opacity, blur |
| Interaction | interaction |
Common Utility Examples
<!-- Flexbox layout -->
<div class="ux4g-d-flex ux4g-justify-between ux4g-align-center ux4g-gap-m">
...
</div>
<!-- Typography -->
<h1 class="ux4g-heading-xl-bold">Title</h1>
<p class="ux4g-body-m-default">Body text</p>
<!-- Spacing -->
<div class="ux4g-p-l ux4g-m-m">Padded and margined</div>
<!-- Background and border -->
<div class="ux4g-bg-neutral-soft ux4g-border-neutral ux4g-radius-lg ux4g-shadow-md">
Card-like container
</div>Dark Theme
Apply the dark theme by adding the data-theme="dark" attribute to any container or the <html> element:
<html data-theme="dark">
<!-- All components automatically use dark tokens -->
</html>Or scope it to a section:
<div data-theme="dark">
<button class="ux4g-btn-primary ux4g-btn-md">Dark themed button</button>
</div>The design tokens automatically switch values based on the data-theme attribute — no additional CSS imports needed.
Focus Ring
UX4G provides built-in focus ring styles for keyboard accessibility. Focus rings appear automatically when users navigate with the keyboard and are suppressed for mouse interactions:
<!-- Focus ring is applied automatically to interactive elements -->
<button class="ux4g-btn-primary ux4g-btn-md">Focusable</button>
<!-- Custom focus ring via utility -->
<div tabindex="0" class="ux4g-focus-ring">Custom focusable element</div>Related Packages
ux4g-components-react— React wrapper componentsux4g-components-angular— Angular wrapper components
License
MIT
