Visual Elements¶
Hamr provides rich visual elements for result items. This page covers sliders, switches, badges, gauges, and more.
Slider Items¶
Sliders let users adjust numeric values (volume, brightness, etc.).

{
"type": "results",
"results": [
{
"id": "volume",
"type": "slider", # Makes this a slider
"name": "Volume",
"icon": "volume_up",
"value": 75, # Current value
"min": 0, # Minimum
"max": 100, # Maximum
"step": 5, # Increment
"unit": "%" # Optional: suffix
}
]
}
| Field | Type | Description |
|---|---|---|
value |
number | Current slider value |
min |
number | Minimum value |
max |
number | Maximum value |
step |
number | Step increment (also determines decimal precision) |
unit |
string | Unit suffix (e.g., "%", "px", "ms") |
displayValue |
string | Override display text entirely |
Handling Slider Changes¶
When user drags the slider:
Handle it and return updated results:
if action == "slider":
item_id = selected.get("id")
new_value = input_data.get("value", 0)
# Apply the change
set_volume(item_id, new_value)
# Return updated results
print(json.dumps({
"type": "results",
"results": get_all_sliders(),
"navigateForward": False # Don't change navigation
}))
Example plugin: sound/
Switch Items¶
Switches are boolean toggles (mute, enable/disable).

{
"type": "results",
"results": [
{
"id": "mute",
"type": "switch", # Makes this a switch
"name": "Mute Volume", # Action description
"description": "Mute audio output",
"icon": "volume_up", # Shows current state
"value": False # Current state
}
]
}
Naming Convention¶
The name describes the action, the icon shows the current state:
| State | Name | Icon |
|---|---|---|
| Not muted | "Mute Volume" | volume_up |
| Muted | "Unmute Volume" | volume_off |
Handling Switch Changes¶
When user toggles:
{
"step": "action",
"selected": {"id": "mute"},
"action": "switch",
"value": True # New value after toggle
}
Return an update response:
if action == "switch":
new_value = input_data.get("value", False)
set_mute(new_value)
print(json.dumps({
"type": "update",
"items": [
{
"id": "mute",
"value": new_value,
"name": "Unmute Volume" if new_value else "Mute Volume",
"icon": "volume_off" if new_value else "volume_up"
}
]
}))
Example plugin: sound/
Badges¶
Small circular indicators beside the item name. Max 5 per item.

{
"id": "task-1",
"name": "Review PR",
"icon": "task",
"badges": [
{"text": "JD"}, # Initials
{"text": "!", "color": "#f44336"}, # Alert (red text)
{"icon": "verified", "color": "#4caf50"}, # Icon badge
{"image": "/path/to/avatar.png"} # Avatar image
]
}
| Field | Type | Description |
|---|---|---|
text |
string | 1-3 characters (initials) |
icon |
string | Material icon (overrides text) |
image |
string | Image path (overrides text) |
color |
string | Text/icon color (hex) |
Note: Background is always theme default. Use color to tint text/icons.
Chips¶
Pill-shaped tags for longer text. Show beside the item name.

{
"id": "task-1",
"name": "Review PR",
"icon": "task",
"chips": [
{"text": "In Progress"}, # Simple label
{"text": "Frontend", "icon": "code"}, # With icon
{"text": "Urgent", "color": "#f44336"} # Colored
]
}
| Field | Type | Description |
|---|---|---|
text |
string | Label text |
icon |
string | Optional icon before text |
color |
string | Text/icon color (hex) |
Gauge¶
Circular progress indicator shown in place of the icon.

{
"id": "disk",
"name": "Disk Space",
"gauge": {
"value": 75, # Current value
"max": 100, # Maximum value
"label": "75%" # Center label
}
}
| Field | Type | Description |
|---|---|---|
value |
number | Current value |
max |
number | Maximum value |
label |
string | Center text (optional) |
Graph¶
Line graph shown in place of the icon. Good for trends/history.

{
"id": "cpu",
"name": "CPU Usage",
"graph": {
"data": [45, 52, 48, 61, 55, 50, 47], # Y values
"min": 0, # Optional: min Y
"max": 100 # Optional: max Y
}
}
If min/max not provided, auto-scales from data.
Progress Bar¶
Horizontal progress bar shown below the name. Replaces description.

{
"id": "download",
"name": "Downloading file.zip",
"icon": "downloading",
"progress": {
"value": 65, # Current value
"max": 100, # Maximum value
"label": "65%", # Text beside bar
"color": "#4caf50" # Custom bar color
}
}
| Field | Type | Description |
|---|---|---|
value |
number | Current progress |
max |
number | Maximum value (default: 100) |
label |
string | Text shown beside bar |
color |
string | Custom bar color (hex) |
Preview Panel¶
Add a preview field to show rich content in a side panel on hover/selection.

{
"id": "image-1",
"name": "sunset.jpg",
"icon": "image",
"preview": {
"type": "image", # "image", "markdown", "text", "metadata"
"content": "/path/to/sunset.jpg",
"title": "Sunset Photo",
"metadata": [
{"label": "Size", "value": "3840x2160"},
{"label": "Date", "value": "2024-01-15"}
],
"actions": [
{"id": "open", "name": "Open", "icon": "open_in_new"}
],
"detachable": true # Allow pinning
}
}
Preview Types¶
| Type | Content Field | Description |
|---|---|---|
image |
File path | Shows image with optional metadata |
markdown |
Markdown text | Renders markdown |
text |
Plain text | Monospace display |
metadata |
(uses metadata array) | Key-value pairs only |
Detachable Previews¶
Users can pin previews to a floating panel that persists after launcher closes.

Example plugins: pictures/, notes/
Visual Priority¶
If multiple visual elements are set on an item:
Icon area priority: graph > gauge > thumbnail > icon
Progress bar: Independent, replaces description.
Icon Types¶
Material Icons (Default)¶
Use any icon from Material Symbols.
Common icons:
| Category | Icons |
|---|---|
| Navigation | arrow_back, home, menu, close |
| Actions | open_in_new, content_copy, delete, edit, add |
| Files | folder, description, image, video_file |
| UI | search, settings, star, favorite, info |
System Icons¶
For desktop application icons, set iconType: "system":
{
"id": "chrome",
"name": "Google Chrome",
"icon": "google-chrome", # From .desktop file
"iconType": "system"
}
Auto-detection: Icons with . or - are assumed system icons. Simple names like btop need explicit iconType: "system".
Thumbnails¶
Show image previews instead of icons:
Use sparingly - thumbnails load images and impact performance.
Updating Visual Elements¶
Use type: "update" to patch items without replacing the entire list:
{
"type": "update",
"items": [
{
"id": "volume",
"gauge": {"value": 80, "max": 100, "label": "80%"},
"badges": [{"text": "M", "color": "#f44336"}]
}
]
}
This preserves selection and focus - ideal for:
- Slider adjustments
- Live status updates
- Real-time data changes
Example plugin: sound/