1027 lines
49 KiB
Plaintext
1027 lines
49 KiB
Plaintext
// Demo Application - Task Manager
|
|
// Showcases all shadcn-style UI components
|
|
|
|
import { Theme, Typography, SpacingSystem } from "theme/theme.slint";
|
|
import { Button } from "components/button.slint";
|
|
import { Input } from "components/input.slint";
|
|
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "components/card.slint";
|
|
import { Badge } from "components/badge.slint";
|
|
import { Item } from "components/item.slint";
|
|
import { Sidebar, NavItem } from "components/sidebar.slint";
|
|
import { Dialog } from "components/dialog.slint";
|
|
import { ToastContainer, ToastMessage } from "components/toast.slint";
|
|
import { Accordion, AccordionItemData } from "components/accordion.slint";
|
|
import { Switch } from "components/switch.slint";
|
|
import { Progress } from "components/progress.slint";
|
|
import { Select, SelectOption } from "components/select.slint";
|
|
import { Tabs, TabItem, TabContent } from "components/tabs.slint";
|
|
import { Label, LabelSize, LabelColor } from "components/label.slint";
|
|
import { Separator, Orientation } from "components/separator.slint";
|
|
import { StatusIndicator, StatusState } from "components/status-indicator.slint";
|
|
import { Tooltip } from "components/tooltip.slint";
|
|
import { Empty } from "components/empty.slint";
|
|
|
|
export component Demo inherits Window {
|
|
title: "Slint Shadcn UI - Task Manager Demo";
|
|
background: Theme.colors.background;
|
|
|
|
// Window size settings - optimized for lower memory usage
|
|
min-width: 600px;
|
|
min-height: 400px;
|
|
preferred-width: 800px;
|
|
preferred-height: 600px;
|
|
|
|
// Application state
|
|
in-out property <string> new-task-title: "";
|
|
in-out property <string> current-view: "tasks";
|
|
in-out property <bool> sidebar-collapsed: false;
|
|
in-out property <bool> dialog-open: false;
|
|
in-out property <[ToastMessage]> toasts: [];
|
|
|
|
// Component showcase state
|
|
in-out property <bool> switch-checked: false;
|
|
in-out property <float> progress-value: 65;
|
|
in-out property <int> selected-option: -1;
|
|
in-out property <int> current-tab: 0;
|
|
in-out property <bool> tooltip-visible: false;
|
|
in-out property <[AccordionItemData]> accordion-items: [
|
|
{ title: "What is Slint?", expanded: false },
|
|
{ title: "How do I get started?", expanded: false },
|
|
{ title: "Can I use it in production?", expanded: false },
|
|
];
|
|
|
|
// Sidebar navigation items
|
|
property <[NavItem]> nav-items: [
|
|
{ icon: "📝", label: "Tasks", active: current-view == "tasks" },
|
|
{ icon: "🎨", label: "Components", active: current-view == "components" },
|
|
{ icon: "⚙", label: "Settings", active: current-view == "settings" },
|
|
];
|
|
|
|
// Callbacks
|
|
callback add-task(string);
|
|
callback show-toast(string, string);
|
|
|
|
// Main layout
|
|
VerticalLayout {
|
|
// Top bar
|
|
Rectangle {
|
|
height: 60px;
|
|
background: Theme.colors.card;
|
|
|
|
Rectangle {
|
|
y: parent.height - 1px;
|
|
height: 1px;
|
|
background: Theme.colors.border;
|
|
}
|
|
|
|
HorizontalLayout {
|
|
padding: SpacingSystem.spacing.s4;
|
|
spacing: SpacingSystem.spacing.s4;
|
|
alignment: space-between;
|
|
|
|
// Left: Title and badge
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
alignment: start;
|
|
|
|
Text {
|
|
text: "📋 Task Manager";
|
|
font-size: Typography.sizes.xl;
|
|
font-weight: Typography.weights.bold;
|
|
color: Theme.colors.foreground;
|
|
vertical-alignment: center;
|
|
}
|
|
|
|
Badge {
|
|
text: "Demo";
|
|
variant: "secondary";
|
|
}
|
|
}
|
|
|
|
// Right: Theme toggle button
|
|
Button {
|
|
text: Theme.is-dark-mode ? "☀ Light" : "🌙 Dark";
|
|
variant: "outline";
|
|
size: "sm";
|
|
|
|
clicked => {
|
|
Theme.toggle-theme();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Main content area
|
|
HorizontalLayout {
|
|
// Sidebar
|
|
Sidebar {
|
|
items: nav-items;
|
|
collapsed: sidebar-collapsed;
|
|
|
|
item-clicked(index) => {
|
|
if index == 0 { current-view = "tasks"; }
|
|
else if index == 1 { current-view = "components"; }
|
|
else if index == 2 { current-view = "settings"; }
|
|
}
|
|
|
|
toggle-collapsed => {
|
|
sidebar-collapsed = !sidebar-collapsed;
|
|
}
|
|
}
|
|
|
|
// Main content area
|
|
Rectangle {
|
|
background: Theme.colors.background;
|
|
horizontal-stretch: 1;
|
|
vertical-stretch: 1;
|
|
|
|
Flickable {
|
|
width: 100%;
|
|
height: 100%;
|
|
viewport-height: content-layout.preferred-height;
|
|
|
|
content-layout := VerticalLayout {
|
|
padding: SpacingSystem.spacing.s6;
|
|
spacing: SpacingSystem.spacing.s6;
|
|
|
|
// Tasks view
|
|
if current-view == "tasks": VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s6;
|
|
|
|
// Add task card
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Add New Task"; }
|
|
CardDescription { text: "Create a new task to track your work"; }
|
|
}
|
|
|
|
CardContent {
|
|
Input {
|
|
value <=> new-task-title;
|
|
placeholder: "Enter task title...";
|
|
|
|
accepted(text) => {
|
|
if text != "" {
|
|
root.add-task(text);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CardFooter {
|
|
Button {
|
|
text: "Add Task";
|
|
|
|
clicked => {
|
|
if new-task-title != "" {
|
|
root.add-task(new-task-title);
|
|
}
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Clear";
|
|
variant: "outline";
|
|
|
|
clicked => {
|
|
new-task-title = "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Example task 1
|
|
Card {
|
|
hoverable: true;
|
|
|
|
CardHeader {
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
alignment: space-between;
|
|
|
|
CardTitle { text: "Design UI Components"; }
|
|
Badge { text: "In Progress"; variant: "default"; }
|
|
}
|
|
}
|
|
|
|
CardContent {
|
|
CardDescription {
|
|
text: "Create a comprehensive set of UI components following shadcn design principles with proper theming support.";
|
|
}
|
|
}
|
|
|
|
CardFooter {
|
|
Button {
|
|
text: "Complete";
|
|
size: "sm";
|
|
|
|
clicked => {
|
|
root.show-toast("Task completed!", "success");
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Delete";
|
|
variant: "destructive";
|
|
size: "sm";
|
|
|
|
clicked => {
|
|
dialog-open = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Example task 2
|
|
Card {
|
|
hoverable: true;
|
|
|
|
CardHeader {
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
alignment: space-between;
|
|
|
|
CardTitle { text: "Write Documentation"; }
|
|
Badge { text: "Todo"; variant: "secondary"; }
|
|
}
|
|
}
|
|
|
|
CardContent {
|
|
CardDescription {
|
|
text: "Document all components with usage examples and API references for developers.";
|
|
}
|
|
}
|
|
|
|
CardFooter {
|
|
Button {
|
|
text: "Start";
|
|
variant: "outline";
|
|
size: "sm";
|
|
|
|
clicked => {
|
|
root.show-toast("Task started!", "default");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Example task 3
|
|
Card {
|
|
hoverable: true;
|
|
|
|
CardHeader {
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
alignment: space-between;
|
|
|
|
CardTitle { text: "Test Components"; }
|
|
Badge { text: "Done"; variant: "outline"; }
|
|
}
|
|
}
|
|
|
|
CardContent {
|
|
CardDescription {
|
|
text: "Thoroughly test all components across different themes and screen sizes.";
|
|
}
|
|
}
|
|
|
|
CardFooter {
|
|
Button {
|
|
text: "View Details";
|
|
variant: "ghost";
|
|
size: "sm";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Components showcase view
|
|
if current-view == "components": VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s6;
|
|
|
|
// Button showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Button Component"; }
|
|
CardDescription { text: "Various button styles and sizes"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
// Variants
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Button { text: "Default"; }
|
|
Button { text: "Secondary"; variant: "secondary"; }
|
|
Button { text: "Outline"; variant: "outline"; }
|
|
Button { text: "Ghost"; variant: "ghost"; }
|
|
Button { text: "Destructive"; variant: "destructive"; }
|
|
}
|
|
|
|
// Sizes
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
alignment: center;
|
|
|
|
Button { text: "Small"; size: "sm"; }
|
|
Button { text: "Medium"; size: "md"; }
|
|
Button { text: "Large"; size: "lg"; }
|
|
}
|
|
|
|
// Disabled
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Button { text: "Disabled"; disabled: true; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Badge showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Badge Component"; }
|
|
CardDescription { text: "Status indicators and labels"; }
|
|
}
|
|
|
|
CardContent {
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Badge { text: "Default"; }
|
|
Badge { text: "Secondary"; variant: "secondary"; }
|
|
Badge { text: "Destructive"; variant: "destructive"; }
|
|
Badge { text: "Outline"; variant: "outline"; }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Input showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Input Component"; }
|
|
CardDescription { text: "Text input fields with various states"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
Input { placeholder: "Normal input..."; }
|
|
Input { placeholder: "Disabled input..."; disabled: true; }
|
|
Input { placeholder: "Error input..."; error: true; }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Item showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Item Component"; }
|
|
CardDescription { text: "List items with icons and descriptions"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Item {
|
|
icon: "📁";
|
|
title: "Project Files";
|
|
description: "All your project documents and resources";
|
|
}
|
|
|
|
Item {
|
|
icon: "⭐";
|
|
title: "Favorites";
|
|
description: "Your starred items for quick access";
|
|
selected: true;
|
|
}
|
|
|
|
Item {
|
|
icon: "🗑";
|
|
title: "Trash";
|
|
description: "Recently deleted items";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Dialog and Toast showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Dialog & Toast"; }
|
|
CardDescription { text: "Modal dialogs and notification toasts"; }
|
|
}
|
|
|
|
CardContent {
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Button {
|
|
text: "Open Dialog";
|
|
|
|
clicked => {
|
|
dialog-open = true;
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Show Success Toast";
|
|
variant: "outline";
|
|
|
|
clicked => {
|
|
root.show-toast("Operation successful!", "success");
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Show Error Toast";
|
|
variant: "outline";
|
|
|
|
clicked => {
|
|
root.show-toast("Something went wrong!", "error");
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Show Warning Toast";
|
|
variant: "outline";
|
|
|
|
clicked => {
|
|
root.show-toast("Please be careful!", "warning");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Switch showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Switch Component"; }
|
|
CardDescription { text: "Toggle switches for boolean settings"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
alignment: start;
|
|
|
|
Switch {
|
|
checked: switch-checked;
|
|
toggled(new-state) => {
|
|
switch-checked = new-state;
|
|
}
|
|
}
|
|
|
|
Text {
|
|
text: switch-checked ? "Enabled" : "Disabled";
|
|
color: Theme.colors.foreground;
|
|
font-size: Typography.sizes.sm;
|
|
vertical-alignment: center;
|
|
}
|
|
}
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
alignment: start;
|
|
|
|
Switch {
|
|
checked: true;
|
|
enabled: false;
|
|
}
|
|
|
|
Text {
|
|
text: "Disabled (checked)";
|
|
color: Theme.colors.muted-foreground;
|
|
font-size: Typography.sizes.sm;
|
|
vertical-alignment: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Progress showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Progress Component"; }
|
|
CardDescription { text: "Progress bars for loading states"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
Progress {
|
|
value: progress-value;
|
|
}
|
|
|
|
Progress {
|
|
value: progress-value;
|
|
show-label: true;
|
|
}
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Button {
|
|
text: "Increase";
|
|
size: "sm";
|
|
clicked => {
|
|
progress-value = Math.min(100, progress-value + 10);
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Decrease";
|
|
size: "sm";
|
|
variant: "outline";
|
|
clicked => {
|
|
progress-value = Math.max(0, progress-value - 10);
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Reset";
|
|
size: "sm";
|
|
variant: "ghost";
|
|
clicked => {
|
|
progress-value = 65;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Select showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Select Component"; }
|
|
CardDescription { text: "Dropdown select menus"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
Select {
|
|
options: [
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Cherry", value: "cherry" },
|
|
{ label: "Date", value: "date" },
|
|
];
|
|
selected-index: selected-option;
|
|
placeholder: "Select a fruit...";
|
|
|
|
selected(index, value) => {
|
|
selected-option = index;
|
|
root.show-toast("Selected: " + value, "default");
|
|
}
|
|
}
|
|
|
|
Select {
|
|
options: [
|
|
{ label: "Option 1", value: "1" },
|
|
{ label: "Option 2", value: "2" },
|
|
];
|
|
enabled: false;
|
|
placeholder: "Disabled select";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tabs showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Tabs Component"; }
|
|
CardDescription { text: "Tabbed navigation interface"; }
|
|
}
|
|
|
|
CardContent {
|
|
Tabs {
|
|
tabs: [
|
|
{ title: "Account" },
|
|
{ title: "Password" },
|
|
{ title: "Settings" },
|
|
];
|
|
current-index: current-tab;
|
|
|
|
tab-changed(index) => {
|
|
current-tab = index;
|
|
}
|
|
|
|
TabContent {
|
|
index: 0;
|
|
current-index: current-tab;
|
|
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
padding: SpacingSystem.spacing.s4;
|
|
|
|
Text {
|
|
text: "Account Settings";
|
|
font-size: Typography.sizes.base;
|
|
font-weight: Typography.weights.semibold;
|
|
color: Theme.colors.foreground;
|
|
}
|
|
|
|
Text {
|
|
text: "Manage your account settings and preferences.";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
}
|
|
}
|
|
}
|
|
|
|
TabContent {
|
|
index: 1;
|
|
current-index: current-tab;
|
|
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
padding: SpacingSystem.spacing.s4;
|
|
|
|
Text {
|
|
text: "Password Settings";
|
|
font-size: Typography.sizes.base;
|
|
font-weight: Typography.weights.semibold;
|
|
color: Theme.colors.foreground;
|
|
}
|
|
|
|
Text {
|
|
text: "Change your password and security settings.";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
}
|
|
}
|
|
}
|
|
|
|
TabContent {
|
|
index: 2;
|
|
current-index: current-tab;
|
|
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
padding: SpacingSystem.spacing.s4;
|
|
|
|
Text {
|
|
text: "General Settings";
|
|
font-size: Typography.sizes.base;
|
|
font-weight: Typography.weights.semibold;
|
|
color: Theme.colors.foreground;
|
|
}
|
|
|
|
Text {
|
|
text: "Configure general application settings.";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Label showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Label Component"; }
|
|
CardDescription { text: "Text labels with various sizes and colors"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
// Sizes
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
alignment: center;
|
|
|
|
Label { text: "Extra Small"; size: LabelSize.xs; }
|
|
Label { text: "Small"; size: LabelSize.sm; }
|
|
Label { text: "Base"; size: LabelSize.base; }
|
|
Label { text: "Large"; size: LabelSize.lg; }
|
|
Label { text: "Extra Large"; size: LabelSize.xl; }
|
|
}
|
|
|
|
// Colors
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
|
|
Label { text: "Foreground"; color-variant: LabelColor.foreground; }
|
|
Label { text: "Muted"; color-variant: LabelColor.muted; }
|
|
Label { text: "Primary"; color-variant: LabelColor.primary; }
|
|
Label { text: "Destructive"; color-variant: LabelColor.destructive; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Separator showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Separator Component"; }
|
|
CardDescription { text: "Visual dividers for content sections"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
Text {
|
|
text: "Horizontal Separator";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
}
|
|
|
|
Separator { orientation: Orientation.horizontal; }
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
height: 60px;
|
|
|
|
Text {
|
|
text: "Vertical";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
vertical-alignment: center;
|
|
}
|
|
|
|
Separator { orientation: Orientation.vertical; }
|
|
|
|
Text {
|
|
text: "Separator";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
vertical-alignment: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Status Indicator showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Status Indicator Component"; }
|
|
CardDescription { text: "Animated status indicators"; }
|
|
}
|
|
|
|
CardContent {
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s6;
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
alignment: center;
|
|
|
|
StatusIndicator { state: StatusState.stopped; }
|
|
Text {
|
|
text: "Stopped";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.foreground;
|
|
vertical-alignment: center;
|
|
}
|
|
}
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
alignment: center;
|
|
|
|
StatusIndicator { state: StatusState.starting; }
|
|
Text {
|
|
text: "Starting";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.foreground;
|
|
vertical-alignment: center;
|
|
}
|
|
}
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
alignment: center;
|
|
|
|
StatusIndicator { state: StatusState.running; }
|
|
Text {
|
|
text: "Running";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.foreground;
|
|
vertical-alignment: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tooltip showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Tooltip Component"; }
|
|
CardDescription { text: "Hover tooltips for additional information"; }
|
|
}
|
|
|
|
CardContent {
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Rectangle {
|
|
width: 120px;
|
|
height: 36px;
|
|
|
|
Button {
|
|
text: "Hover Me";
|
|
variant: "outline";
|
|
}
|
|
|
|
Tooltip {
|
|
text: "This is a tooltip!";
|
|
show: tooltip-visible;
|
|
}
|
|
|
|
TouchArea {
|
|
moved => {
|
|
tooltip-visible = self.has-hover;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Accordion showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Accordion Component"; }
|
|
CardDescription { text: "Collapsible content sections"; }
|
|
}
|
|
|
|
CardContent {
|
|
Accordion {
|
|
items: accordion-items;
|
|
|
|
item-toggled(index, expanded) => {
|
|
accordion-items[index].expanded = expanded;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Empty showcase
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Empty Component"; }
|
|
CardDescription { text: "Empty state placeholders"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s6;
|
|
|
|
Empty {
|
|
icon: "📭";
|
|
title: "No Messages";
|
|
description: "You don't have any messages yet.";
|
|
min-height: 150px;
|
|
}
|
|
|
|
Separator { orientation: Orientation.horizontal; }
|
|
|
|
Empty {
|
|
icon: "🔍";
|
|
title: "No Results Found";
|
|
description: "Try adjusting your search criteria.";
|
|
min-height: 150px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Settings view
|
|
if current-view == "settings": VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s6;
|
|
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "Appearance"; }
|
|
CardDescription { text: "Customize the look and feel of the application"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s4;
|
|
alignment: space-between;
|
|
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s1;
|
|
|
|
Text {
|
|
text: "Theme";
|
|
font-size: Typography.sizes.base;
|
|
font-weight: Typography.weights.medium;
|
|
color: Theme.colors.foreground;
|
|
}
|
|
|
|
Text {
|
|
text: "Choose between light and dark mode";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: Theme.is-dark-mode ? "Dark Mode" : "Light Mode";
|
|
variant: "outline";
|
|
|
|
clicked => {
|
|
Theme.toggle-theme();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Card {
|
|
CardHeader {
|
|
CardTitle { text: "About"; }
|
|
CardDescription { text: "Information about this demo application"; }
|
|
}
|
|
|
|
CardContent {
|
|
VerticalLayout {
|
|
spacing: SpacingSystem.spacing.s3;
|
|
|
|
Text {
|
|
text: "Slint Shadcn UI Component Library";
|
|
font-size: Typography.sizes.base;
|
|
font-weight: Typography.weights.semibold;
|
|
color: Theme.colors.foreground;
|
|
}
|
|
|
|
Text {
|
|
text: "A comprehensive set of UI components inspired by shadcn/ui, built with Slint. Features include theme support, smooth animations, and a clean, modern design.";
|
|
font-size: Typography.sizes.sm;
|
|
color: Theme.colors.muted-foreground;
|
|
wrap: word-wrap;
|
|
}
|
|
|
|
HorizontalLayout {
|
|
spacing: SpacingSystem.spacing.s2;
|
|
|
|
Badge { text: "v1.0.0"; variant: "secondary"; }
|
|
Badge { text: "Slint 1.14"; variant: "outline"; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Dialog overlay - inline implementation
|
|
Dialog {
|
|
open: dialog-open;
|
|
title: "Confirm Delete";
|
|
description: "Are you sure you want to delete this task? This action cannot be undone.";
|
|
|
|
close => {
|
|
dialog-open = false;
|
|
}
|
|
}
|
|
|
|
// Toast container
|
|
Rectangle {
|
|
x: parent.width - 390px;
|
|
y: 20px;
|
|
width: 370px;
|
|
|
|
ToastContainer {
|
|
toasts: toasts;
|
|
|
|
toast-dismissed(index) => {
|
|
// Will be handled by Rust
|
|
}
|
|
}
|
|
}
|
|
}
|