JavaScript Required

Dashboard

Interactive dashboard layout with drag-and-drop widgets, resize handles, collision detection, and keyboard navigation. For static dashboard layouts, use Grid + Widget components instead.

Interactive Example

Click "Edit Mode" to enable drag-and-drop. Drag widgets by their headers, resize using the bottom-right handle.

Locked

Total Users

24,568 +12%

Revenue

$45.2K +8%

Active Sessions

1,247 -3%

Revenue Chart

40K 30K 20K 10K Jan Feb Mar Apr May Jun

Recent Activity

Order #1234 - $150
Order #1235 - $89
Order #1236 - $220
Order #1237 - $65

Usage

import { dashboard } from 'omniui/js/dashboard.js';

// Initialize dashboard
const db = dashboard(document.querySelector('.my-dashboard'), {
  columns: 12,
  rowHeight: 100,
  gap: 16,
  collision: 'push'
});

// Enable editing
db.unlock();

// Get current layout
const layout = db.getLayout();

// Restore saved layout
db.setLayout(savedLayout);

// Clean up
db.destroy();

HTML Structure

<div class="my-dashboard">
  <div class="omni-widget" id="widget-1" data-x="0" data-y="0" data-w="4" data-h="2">
    <div class="omni-widget-header">
      <h3 class="omni-widget-title">Widget Title</h3>
    </div>
    <div class="omni-widget-content">
      <!-- Content -->
    </div>
    <div class="omni-widget-resize" aria-label="Resize widget"></div>
  </div>
</div>

Features

  • Drag & Drop: Move widgets by dragging their headers
  • Resize: Resize widgets via the corner handle
  • Collision Detection: Widgets push others out of the way
  • Gravity: Widgets pack upward when space is available
  • Keyboard Navigation: Full support for arrow keys, Enter, Escape
  • ARIA Announcements: Screen reader feedback during operations
  • Layout Persistence: Save and restore layouts via getLayout()/setLayout()
  • Reduced Motion: Respects prefers-reduced-motion

API Reference

Options

Option Type Default Description
columns number 12 Number of grid columns
rowHeight number 100 Row height in pixels
gap number 16 Gap between widgets in pixels
widgets string '.omni-widget' Widget selector
handle string '.omni-widget-header' Drag handle selector
resizeHandle string '.omni-widget-resize' Resize handle selector
minW / maxW number 1 / 12 Min/max width in columns
minH / maxH number 1 / 8 Min/max height in rows
collision 'push' | 'none' 'push' How to handle overlapping widgets
float boolean false If true, widgets don't pack upward

Methods

Method Description
unlock() Enable editing mode (drag and resize)
lock() Disable editing mode
getLayout() Returns array of widget positions
setLayout(layout) Restore a saved layout
compact() Pack all widgets upward
addWidget(element, position) Add a new widget to the dashboard
removeWidget(element) Remove a widget from the dashboard
destroy() Clean up event listeners and reset styles

Callbacks

Callback Arguments Description
onDragStart (widget) Called when drag begins
onDrag (widget, position) Called during drag
onDragEnd (widget, position) Called when drag ends
onResizeStart (widget) Called when resize begins
onResize (widget, position) Called during resize
onResizeEnd (widget, position) Called when resize ends
onChange (layout) Called when layout changes

Data Attributes

Attribute Description
data-x Initial column position (0-based)
data-y Initial row position (0-based)
data-w Width in columns
data-h Height in rows

Static Layouts

If you don't need drag-and-drop functionality, use Grid with Widget components for a pure CSS solution:

<div class="omni-bento-grid">
  <div class="omni-widget bento-span-2">...</div>
  <div class="omni-widget">...</div>
  <div class="omni-widget bento-span-2 bento-row-2">...</div>
</div>

Accessibility

  • Keyboard Navigation: Tab to widget headers, Enter/Space to start drag, arrow keys to move, Escape to cancel
  • ARIA Announcements: Screen readers announce when dragging starts, position changes, and operation completes
  • Focus Management: Focus returns to widget after operations
  • Reduced Motion: Animations disabled when prefers-reduced-motion: reduce is set
  • Resize Handles: Include aria-label="Resize widget" for screen readers

Components Used

Other OmniUI components demonstrated on this page: