init
This commit is contained in:
138
ui/components/sidebar.slint
Normal file
138
ui/components/sidebar.slint
Normal file
@@ -0,0 +1,138 @@
|
||||
// Sidebar Component
|
||||
// Collapsible navigation sidebar with menu items
|
||||
|
||||
import { Theme, Typography, SpacingSystem } from "../theme/theme.slint";
|
||||
import { Animations } from "../utils/animations.slint";
|
||||
|
||||
// Navigation item structure
|
||||
export struct NavItem {
|
||||
icon: string, // Text icon/emoji
|
||||
label: string,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
export component Sidebar {
|
||||
// Public properties
|
||||
in-out property <bool> collapsed: false;
|
||||
in property <[NavItem]> items: [];
|
||||
|
||||
// Callbacks
|
||||
callback item-clicked(int); // Pass item index
|
||||
callback toggle-collapsed();
|
||||
|
||||
// Calculate width based on collapsed state
|
||||
private property <length> sidebar-width: collapsed ? 60px : 240px;
|
||||
|
||||
width: sidebar-width;
|
||||
|
||||
animate width {
|
||||
duration: Animations.durations.normal;
|
||||
easing: Animations.ease-in-out;
|
||||
}
|
||||
|
||||
// Main container
|
||||
Rectangle {
|
||||
background: Theme.colors.card;
|
||||
|
||||
Rectangle {
|
||||
x: parent.width - 1px;
|
||||
width: 1px;
|
||||
height: parent.height;
|
||||
background: Theme.colors.border;
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
padding: SpacingSystem.spacing.s4;
|
||||
spacing: SpacingSystem.spacing.s2;
|
||||
|
||||
// Toggle button
|
||||
Rectangle {
|
||||
height: 40px;
|
||||
background: Colors.transparent;
|
||||
border-radius: SpacingSystem.radius.md;
|
||||
|
||||
HorizontalLayout {
|
||||
padding: SpacingSystem.spacing.s2;
|
||||
spacing: SpacingSystem.spacing.s2;
|
||||
|
||||
Text {
|
||||
text: collapsed ? "☰" : "✕";
|
||||
font-size: Typography.sizes.xl;
|
||||
color: Theme.colors.foreground;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
|
||||
if !collapsed: Text {
|
||||
text: "Menu";
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: Typography.weights.medium;
|
||||
color: Theme.colors.foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
root.toggle-collapsed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
height: 1px;
|
||||
background: Theme.colors.border;
|
||||
}
|
||||
|
||||
// Navigation items
|
||||
for item[index] in items: Rectangle {
|
||||
height: 44px;
|
||||
background: item.active ? Theme.colors.accent : Colors.transparent;
|
||||
border-radius: SpacingSystem.radius.md;
|
||||
|
||||
states [
|
||||
hovered when touch-area.has-hover && !item.active: {
|
||||
background: Theme.colors.muted;
|
||||
}
|
||||
]
|
||||
|
||||
animate background {
|
||||
duration: Animations.durations.fast;
|
||||
easing: Animations.ease-in-out;
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
padding: SpacingSystem.spacing.s2;
|
||||
spacing: SpacingSystem.spacing.s3;
|
||||
alignment: start;
|
||||
|
||||
// Icon
|
||||
Text {
|
||||
text: item.icon;
|
||||
font-size: Typography.sizes.xl;
|
||||
color: item.active ? Theme.colors.accent-foreground : Theme.colors.foreground;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
// Label (only when not collapsed)
|
||||
if !collapsed: Text {
|
||||
text: item.label;
|
||||
font-size: Typography.sizes.base;
|
||||
font-weight: item.active ? Typography.weights.medium : Typography.weights.normal;
|
||||
color: item.active ? Theme.colors.accent-foreground : Theme.colors.foreground;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
touch-area := TouchArea {
|
||||
clicked => {
|
||||
root.item-clicked(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user