This commit is contained in:
2026-01-30 12:56:00 +08:00
parent 91f24cb462
commit dcbbda951e
89 changed files with 13486 additions and 72 deletions

View File

@@ -0,0 +1,116 @@
import { Theme, SpacingSystem, Typography, Animations } from "../theme/theme.slint";
export struct AccordionItemData {
title: string,
expanded: bool,
}
export component Accordion {
in-out property <[AccordionItemData]> items: [];
in property <bool> allow-multiple: false;
callback item-toggled(int, bool);
VerticalLayout {
spacing: 0;
for item[index] in root.items: AccordionItem {
title: item.title;
expanded: item.expanded;
is-last: index == root.items.length - 1;
toggled => {
root.item-toggled(index, !item.expanded);
}
}
}
}
component AccordionItem {
in property <string> title: "";
in property <bool> expanded: false;
in property <bool> is-last: false;
callback toggled();
private property <bool> hovered: false;
VerticalLayout {
spacing: 0;
// Header
header := Rectangle {
height: 48px;
background: root.hovered ? Theme.colors.muted : transparent;
animate background { duration: Animations.durations.fast; }
HorizontalLayout {
padding-left: SpacingSystem.spacing.s4;
padding-right: SpacingSystem.spacing.s4;
spacing: SpacingSystem.spacing.s4;
alignment: space-between;
Text {
text: root.title;
color: Theme.colors.foreground;
font-size: Typography.sizes.sm;
font-weight: Typography.weights.medium;
vertical-alignment: center;
}
chevron := Text {
text: "";
color: Theme.colors.muted-foreground;
font-size: Typography.sizes.lg;
font-weight: Typography.weights.bold;
vertical-alignment: center;
width: 20px;
horizontal-alignment: center;
rotation-angle: root.expanded ? 90deg : 0deg;
rotation-origin-x: self.width / 2;
rotation-origin-y: self.height / 2;
animate rotation-angle { duration: Animations.durations.normal; easing: Animations.ease-out; }
}
}
touch := TouchArea {
clicked => {
root.toggled();
}
moved => {
root.hovered = self.has-hover;
}
}
}
// Content
if root.expanded: content-wrapper := Rectangle {
background: transparent;
VerticalLayout {
padding: SpacingSystem.spacing.s4;
padding-top: 0;
padding-bottom: SpacingSystem.spacing.s4;
@children
}
}
// Border
if !root.is-last: Rectangle {
height: 1px;
background: Theme.colors.border;
}
}
}
// Wrapper for accordion content
export component AccordionContent {
VerticalLayout {
@children
}
}