This commit is contained in:
2026-01-26 23:40:05 +08:00
parent 1ec60e3cbb
commit 24bf9dc3dd
7 changed files with 163 additions and 188 deletions

View File

@@ -14,10 +14,10 @@ export component Button {
// Callbacks
callback clicked();
// Calculate text color based on variant
// Calculate text color based on variant (shadcn design tokens)
private property <color> text-color: {
if disabled { Theme.colors.muted-foreground }
else if variant == "destructive" { Theme.colors.destructive-foreground }
else if variant == "destructive" { Theme.colors.destructive } // destructive uses destructive color for text
else if variant == "outline" { Theme.colors.foreground }
else if variant == "secondary" { Theme.colors.secondary-foreground }
else if variant == "ghost" { Theme.colors.foreground }
@@ -48,8 +48,9 @@ export component Button {
// Main container
container := Rectangle {
border-radius: SpacingSystem.radius.md;
border-width: variant == "outline" ? 1px : 0px;
border-color: Theme.colors.border;
// Outline variant always has border
border-width: root.variant == "outline" ? 1px : 0px;
border-color: root.variant == "outline" ? Theme.colors.border : Colors.transparent;
// Touch interaction area (must be defined before using touch.pressed/has-hover)
touch := TouchArea {
@@ -61,45 +62,42 @@ export component Button {
}
}
// Background with state-based colors (shadcn style)
background-rect := Rectangle {
width: 100%;
height: 100%;
border-radius: parent.border-radius;
// Calculate background color based on variant and state
background: {
if root.disabled {
Theme.colors.muted
} else if root.variant == "destructive" {
if touch.pressed { Theme.colors.destructive.darker(0.1) }
else if touch.has-hover { Theme.colors.destructive.darker(0.05) }
else { Theme.colors.destructive }
} else if root.variant == "outline" {
if touch.pressed { Theme.colors.accent.darker(0.05) }
else if touch.has-hover { Theme.colors.accent }
else { Colors.transparent }
} else if root.variant == "secondary" {
if touch.pressed { Theme.colors.secondary.darker(0.1) }
else if touch.has-hover { Theme.colors.secondary.darker(0.05) }
else { Theme.colors.secondary }
} else if root.variant == "ghost" {
if touch.pressed { Theme.colors.accent.darker(0.05) }
else if touch.has-hover { Theme.colors.accent }
else { Colors.transparent }
} else {
// default variant
if touch.pressed { Theme.colors.primary.darker(0.1) }
else if touch.has-hover { Theme.colors.primary.darker(0.05) }
else { Theme.colors.primary }
}
};
// Smooth transitions
animate background {
duration: Animations.durations.fast;
easing: Animations.ease-in-out;
// Calculate background color based on variant and state (shadcn official design)
background: {
if root.disabled {
Theme.colors.muted
} else if root.variant == "destructive" {
// destructive: bg-destructive/10 hover:bg-destructive/20
if touch.pressed { Theme.colors.destructive.with-alpha(0.25) }
else if touch.has-hover { Theme.colors.destructive.with-alpha(0.2) }
else { Theme.colors.destructive.with-alpha(0.1) }
} else if root.variant == "outline" {
// outline: bg-background hover:bg-muted
if touch.pressed { Theme.colors.muted.darker(0.05) }
else if touch.has-hover { Theme.colors.muted }
else { Theme.colors.background }
} else if root.variant == "secondary" {
// secondary: bg-secondary hover:bg-secondary/80
if touch.pressed { Theme.colors.secondary.with-alpha(0.7) }
else if touch.has-hover { Theme.colors.secondary.with-alpha(0.8) }
else { Theme.colors.secondary }
} else if root.variant == "ghost" {
// ghost: transparent hover:bg-muted
if touch.pressed { Theme.colors.muted.darker(0.05) }
else if touch.has-hover { Theme.colors.muted }
else { Colors.transparent }
} else {
// default (primary): bg-primary hover:bg-primary/80
if touch.pressed { Theme.colors.primary.with-alpha(0.7) }
else if touch.has-hover { Theme.colors.primary.with-alpha(0.8) }
else { Theme.colors.primary }
}
};
// Smooth transitions
animate background {
duration: Animations.durations.fast;
easing: Animations.ease-in-out;
}
// Content layout

View File

@@ -15,11 +15,11 @@ export component Demo inherits Window {
title: "Slint Shadcn UI - Task Manager Demo";
background: Theme.colors.background;
// Window size settings - reduced for lower memory usage
min-width: 800px;
min-height: 600px;
preferred-width: 1000px;
preferred-height: 700px;
// 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: "";

View File

@@ -1,5 +1,6 @@
// Shadcn-style Color System
// Based on shadcn/ui zinc theme with light/dark mode support
// Based on shadcn/ui official neutral theme with light/dark mode support
// Source: https://github.com/shadcn-ui/ui/blob/main/apps/v4/styles/globals.css
// Color palette structure
export struct ColorPalette {
@@ -24,52 +25,53 @@ export struct ColorPalette {
ring: color,
}
// Light mode colors - shadcn zinc theme
// Light mode colors - shadcn official neutral theme
// oklch values converted to hex for Slint compatibility
export global LightColors {
out property <ColorPalette> palette: {
background: #ffffff,
foreground: #09090b,
card: #ffffff,
card-foreground: #09090b,
popover: #ffffff,
popover-foreground: #09090b,
primary: #18181b,
primary-foreground: #fafafa,
secondary: #f4f4f5,
secondary-foreground: #18181b,
muted: #f4f4f5,
muted-foreground: #71717a,
accent: #f4f4f5,
accent-foreground: #18181b,
destructive: #ef4444,
destructive-foreground: #fafafa,
border: #e4e4e7,
input: #e4e4e7,
ring: #18181b,
background: #ffffff, // oklch(1 0 0)
foreground: #252525, // oklch(0.145 0 0)
card: #ffffff, // oklch(1 0 0)
card-foreground: #252525, // oklch(0.145 0 0)
popover: #ffffff, // oklch(1 0 0)
popover-foreground: #252525, // oklch(0.145 0 0)
primary: #343434, // oklch(0.205 0 0)
primary-foreground: #fbfbfb, // oklch(0.985 0 0)
secondary: #f7f7f7, // oklch(0.97 0 0)
secondary-foreground: #343434, // oklch(0.205 0 0)
muted: #f7f7f7, // oklch(0.97 0 0)
muted-foreground: #8e8e8e, // oklch(0.556 0 0)
accent: #f7f7f7, // oklch(0.97 0 0)
accent-foreground: #343434, // oklch(0.205 0 0)
destructive: #ef4444, // oklch(0.577 0.245 27.325)
destructive-foreground: #f7f7f7, // oklch(0.97 0.01 17) - light red/pink, not white!
border: #ebebeb, // oklch(0.922 0 0)
input: #ebebeb, // oklch(0.922 0 0)
ring: #b4b4b4, // oklch(0.708 0 0)
};
}
// Dark mode colors - shadcn zinc theme
// Dark mode colors - shadcn official neutral theme
export global DarkColors {
out property <ColorPalette> palette: {
background: #09090b,
foreground: #fafafa,
card: #09090b,
card-foreground: #fafafa,
popover: #09090b,
popover-foreground: #fafafa,
primary: #fafafa,
primary-foreground: #18181b,
secondary: #27272a,
secondary-foreground: #fafafa,
muted: #27272a,
muted-foreground: #a1a1aa,
accent: #27272a,
accent-foreground: #fafafa,
destructive: #7f1d1d,
destructive-foreground: #fafafa,
border: #27272a,
input: #27272a,
ring: #d4d4d8,
background: #252525, // oklch(0.145 0 0)
foreground: #fbfbfb, // oklch(0.985 0 0)
card: #343434, // oklch(0.205 0 0)
card-foreground: #fbfbfb, // oklch(0.985 0 0)
popover: #444444, // oklch(0.269 0 0)
popover-foreground: #fbfbfb, // oklch(0.985 0 0)
primary: #ebebeb, // oklch(0.922 0 0)
primary-foreground: #343434, // oklch(0.205 0 0)
secondary: #444444, // oklch(0.269 0 0)
secondary-foreground: #fbfbfb, // oklch(0.985 0 0)
muted: #444444, // oklch(0.269 0 0)
muted-foreground: #b4b4b4, // oklch(0.708 0 0)
accent: #5e5e5e, // oklch(0.371 0 0)
accent-foreground: #fbfbfb, // oklch(0.985 0 0)
destructive: #dc2626, // oklch(0.704 0.191 22.216)
destructive-foreground: #ef4444, // oklch(0.58 0.22 27) - red color, not white!
border: #1a1a1a, // oklch(1 0 0 / 10%) - 10% white on dark
input: #262626, // oklch(1 0 0 / 15%) - 15% white on dark
ring: #8e8e8e, // oklch(0.556 0 0)
};
}