Tab Widgets
Tabs
Horizontal tab bar with clickable tabs.
| Prop | Type | Description |
|---|---|---|
tabs | Vec<Tab> | Tab items |
tab(Tab) | method | Add a single tab |
active | usize | Active tab index |
divider | char | Separator between tabs |
border | bool | Show border |
border_style | BorderStyle | Border style |
padding | impl Into<Padding> | Padding |
style | Style | Bar idle style |
focus_style | Style | Bar focus style |
hover_style | Style | Bar hover style |
tab_hover_style | Style | Individual tab hover style |
active_style | Style | Active tab style |
disabled | bool | Disable all tabs |
disabled_style | Style | Style when disabled |
focusable | bool | Accept focus |
width | Length | Width |
height | Length | Height |
on_change | Callback<TabsEvent> | Active tab changed |
on_click | Callback<TabsEvent> | Tab clicked |
on_key | KeyHandler | Key handler |
Tabs::new()
.tabs(vec![
Tab::new("Editor"),
Tab::new("Terminal"),
Tab::new("Log"),
])
.active(self.active_tab)
.border(true)
.active_style(Style::new().fg(Color::Cyan).bold())
.on_change(ctx.link().callback(|e: TabsEvent| Msg::TabChanged(e.index)))Tab construction:
Tab::new("Label")
.style(Style::new().fg(Color::White))
.disabled(false)TabsEvent fields: index: usize
DraggableTabBar
Editor-style tab bar with drag reordering, per-tab close buttons, file icons, and cross-bar transfer.
| Prop | Type | Description |
|---|---|---|
tabs | Vec<DraggableTab> | Tab items |
tab(DraggableTab) | method | Add a single tab |
active | usize | Active tab index |
variant | DraggableTabBarVariant | Bordered or FrameLine |
draggable | bool | Enable drag reordering |
drag_preview | bool | Floating tab label near the pointer while dragging (default: true) |
reorder_mode | DragReorderMode | Live or OnDrop |
drag_threshold | u16 | Pixels before drag starts |
show_close_buttons | bool | Show close buttons |
close_symbol | &str | Close button symbol |
close_on_hover_only | bool | Show close only on hover |
tab_max_width | Option<u16> | Maximum tab width in cells |
scroll_wheel | bool | Mouse wheel to scroll tabs |
show_overflow_controls | bool | Show < > overflow buttons |
overflow_style | Style | Overflow button style |
overflow_hover_style | Style | Overflow button hover style |
scroll_offset | usize | Controlled scroll offset |
show_file_icons | bool | Show file type icons |
file_icon_style | FileIconStyle | Icon style (Nerd, NerdColored, Emoji) |
file_icon_palette | FileIconPalette | Custom icon colors |
file_icon_override | HashMap<Arc<str>, FileIconOverride> | Per-extension overrides |
bar_id | &str | Bar identifier for drag groups |
drag_group | &str | Group name for cross-bar transfer |
style | Style | Bar idle style |
focus_style | Style | Bar focus style |
hover_style | Style | Bar hover style |
tab_hover_style | Style | Hover style for inactive tabs (active tab keeps active_style) |
active_style | Style | Active tab style (takes priority over hover) |
close_style | Style | Close button style |
close_hover_style | Style | Close button hover style |
divider | char | Tab separator character |
accent_symbol | char | Left/right accent character |
active_accent_symbol | char | Active tab accent |
accent_style | Style | Accent style |
active_accent_style | Style | Active tab accent style |
border | bool | Show border |
border_style | BorderStyle | Border style |
padding | impl Into<Padding> | Padding |
disabled | bool | Disable all tabs |
disabled_style | Style | Style when disabled |
focusable | bool | Accept focus |
width | Length | Width |
height | Length | Height |
on_change | Callback<TabsEvent> | Active tab changed |
on_close | Callback<DraggableTabCloseEvent> | Close button clicked |
on_reorder | Callback<DraggableTabReorderEvent> | Tab dragged to new position |
on_transfer | Callback<DraggableTabTransferEvent> | Tab transferred to another bar |
on_click | Callback<TabsEvent> | Tab clicked |
on_key | KeyHandler | Key handler |
Tab Construction
DraggableTab::new("main.rs")
.closeable(true)
.style(Style::new())
.path("src/main.rs") // For file icon auto-lookup
.icon(Span::new(" ").fg(Color::Red)) // Manual icon override
.right_badge(Span::new("M").fg(Color::Yellow)) // Git status markerTo show a spinner in the icon position (replaces icon and file-icon when set):
DraggableTab::new("Session 1")
.leading(
Spinner::new()
.spinner_style(SpinnerStyle::Dots)
.speed(SpinnerSpeed::Normal)
.style(Style::new().fg(Color::Cyan))
.into()
)Spinner label and layout properties are ignored in tabs because the tab owns its label and sizing.
The same slot also accepts Text elements for static fallbacks:
DraggableTab::new("Session 1")
.leading(Text::new("⋯").style(Style::new().fg(Color::Cyan)).into())The spinner glyph occupies the same slot as the icon - its width is determined by SpinnerStyle::width(). Tab spinners animate automatically with the app runtime. Spinner/text content takes priority over icon and file icons.
Events
// TabsEvent { index: usize }
// DraggableTabCloseEvent { index: usize }
// DraggableTabReorderEvent { from: usize, to: usize }
// DraggableTabTransferEvent { from_bar: String, to_bar: String, from: usize, to: usize }File Icons
DraggableTabBar::new()
.show_file_icons(true)
.file_icon_style(FileIconStyle::NerdFontColored)
.file_icon_palette(FileIconPalette { /* custom colors */ })FileIconStyle variants: NerdFont, NerdFontColored, Emoji.
File icon is auto-resolved from DraggableTab::path(...). Use file_icon_override for per-extension customization.
Cross-Bar Drag (Drag Groups)
// Left editor bar
DraggableTabBar::new()
.bar_id("left-editor")
.drag_group("editors")
.tabs(self.left_tabs.clone())
.on_transfer(ctx.link().callback(Msg::TransferFromLeft))
// Right editor bar
DraggableTabBar::new()
.bar_id("right-editor")
.drag_group("editors")
.tabs(self.right_tabs.clone())
.on_transfer(ctx.link().callback(Msg::TransferFromRight))Tabs can be dragged between bars that share the same drag_group. The on_transfer callback fires on the source bar and reports from_bar, to_bar, from index, and to index.
Full Example
rsx! {
DraggableTabBar {
tabs: vec![
DraggableTab::new("main.rs").closeable(true).path("src/main.rs"),
DraggableTab::new("lib.rs").closeable(true).path("src/lib.rs"),
DraggableTab::new("README.md").path("README.md"),
],
bar_id: "editor",
drag_group: "editors",
active: self.active_tab,
variant: DraggableTabBarVariant::FrameLine,
tab_max_width: Some(20),
show_file_icons: true,
file_icon_style: FileIconStyle::NerdFontColored,
show_close_buttons: true,
show_overflow_controls: true,
active_style: Style::new().fg(Color::Cyan).bold(),
on_change: ctx.link().callback(|e| Msg::SetActive(e.index)),
on_close: ctx.link().callback(Msg::CloseTab),
on_reorder: ctx.link().callback(Msg::ReorderTabs),
}
}Image Chip Bar Pattern
Use DraggableTabBar as an image attachment chip bar above TextArea:
DraggableTabBar::new()
.tabs(images.iter().enumerate().map(|(i, _)| {
DraggableTab::new(format!("Image {}", i + 1))
.closeable(true)
}))
.active(usize::MAX) // No active tab (no highlight)
.close_symbol("x")
.draggable(false)
.focusable(false)
.on_close(ctx.link().callback(Msg::RemoveImage))
.height(Length::Auto)