调整布局

This commit is contained in:
tommy
2025-11-03 15:25:50 +08:00
parent 68ae1b27eb
commit a6ac4833b6
4 changed files with 117 additions and 70 deletions

View File

@@ -1,7 +1,7 @@
:root {
--sidebar-width: 280px;
--sidebar-collapsed-width: 72px;
--topbar-height: 72px;
--topbar-height: 60px;
}
.ui-shell {
@@ -29,6 +29,7 @@
display: flex;
flex-direction: column;
gap: 24px;
width: 100%;
background-color: hsl(var(--card));
border-right: 1px solid hsl(var(--border));
padding: 28px 24px;
@@ -106,6 +107,7 @@
.ui-sidebar-menu-button {
display: inline-flex;
align-items: flex-start;
width: 100%;
gap: 12px;
padding: 10px 12px;
@@ -142,16 +144,20 @@
display: flex;
flex-direction: column;
gap: 3px;
flex: 1;
min-width: 0;
}
.ui-sidebar-label {
font-size: 0.9rem;
font-weight: 600;
white-space: normal;
}
.ui-sidebar-description {
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
white-space: normal;
}
.ui-sidebar-badge {
@@ -193,15 +199,32 @@
position: sticky;
top: 0;
z-index: 5;
display: flex;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 18px;
justify-content: space-between;
padding: 24px 32px;
gap: 16px;
padding: 0 24px;
border-bottom: 1px solid hsl(var(--border));
background-color: hsla(var(--background), 0.95);
backdrop-filter: blur(12px);
min-height: var(--topbar-height);
height: var(--topbar-height);
}
.admin-shell-command {
display: flex;
}
.admin-command-button {
font-weight: 600;
font-size: 0.95rem;
border: 1px solid hsl(var(--border));
background-color: hsl(var(--card));
color: hsl(var(--foreground));
border-radius: calc(var(--radius) - 2px);
padding: 0.45rem 0.9rem;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.admin-shell-meta {
@@ -212,22 +235,21 @@
.admin-shell-title {
margin: 0;
font-size: 1.5rem;
font-size: 1.25rem;
font-weight: 600;
}
.admin-shell-description {
margin: 0;
color: hsl(var(--muted-foreground));
font-size: 0.95rem;
}
.admin-shell-actions {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 12px;
}
.admin-shell-theme {
font-weight: 500;
}
.admin-shell-content {
flex: 1;
width: 100%;
@@ -241,35 +263,30 @@
margin: 0;
}
.ui-sidebar-trigger {
display: inline-flex;
align-items: center;
gap: 8px;
border: 1px solid hsl(var(--border));
background-color: hsl(var(--card));
color: hsl(var(--foreground));
border-radius: calc(var(--radius) - 2px);
padding: 0.5rem 0.8rem;
font-weight: 500;
.dashboard-root,
.component-page {
display: flex;
flex-direction: column;
gap: 24px;
}
.ui-sidebar[data-collapsed="true"] .sidebar-name,
.ui-sidebar[data-collapsed="true"] .sidebar-subtitle,
.ui-sidebar[data-collapsed="true"] .ui-sidebar-text,
.ui-sidebar[data-collapsed="true"] .ui-sidebar-badge,
.ui-sidebar[data-collapsed="true"] .sidebar-profile div,
.ui-sidebar[data-collapsed="true"] .sidebar-profile-role,
.ui-sidebar[data-collapsed="true"] .ui-sidebar-group-label {
display: none;
.page-heading {
display: flex;
flex-direction: column;
gap: 6px;
}
.ui-sidebar[data-collapsed="true"] .sidebar-profile {
justify-content: center;
padding: 12px 8px;
.page-heading h1 {
margin: 0;
font-size: 1.5rem;
font-weight: 600;
}
.ui-sidebar[data-collapsed="true"] .ui-sidebar-menu-button {
justify-content: center;
.page-heading p {
margin: 0;
color: hsl(var(--muted-foreground));
font-size: 0.95rem;
max-width: 640px;
}
@media (max-width: 960px) {

View File

@@ -10,3 +10,9 @@ body {
font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
-webkit-font-smoothing: antialiased;
}
*,
*::before,
*::after {
box-sizing: border-box;
}

View File

@@ -113,7 +113,11 @@ pub fn Home() -> Element {
rsx! {
div {
class: "dashboard-root",
style: "display: flex; flex-direction: column; gap: 24px;",
div {
class: "page-heading",
h1 { "Dashboard overview" }
p { "Track product health, monitor key funnels, and coordinate the team from one place." }
}
section {
class: "dashboard-kpis",
style: "display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));",
@@ -266,7 +270,15 @@ pub fn Home() -> Element {
#[component]
pub fn Components() -> Element {
rsx! {
UiShowcase {}
div {
class: "component-page",
div {
class: "page-heading",
h1 { "Component library" }
p { "Browse every primitive wired into this starter so new screens stay consistent." }
}
UiShowcase {}
}
}
}
#[component]

View File

@@ -1,46 +1,53 @@
use crate::{
components::ui::{
Avatar, Badge, BadgeVariant, Button, ButtonVariant, Sidebar, SidebarContent, SidebarFooter,
SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset,
SidebarLayout, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarRail,
SidebarSeparator, SidebarTrigger,
Avatar, Button, ButtonVariant, Sidebar, SidebarContent, SidebarFooter, SidebarGroup,
SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarLayout,
SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarRail, SidebarSeparator,
},
Route,
};
use dioxus::prelude::*;
fn page_meta(route: &Route) -> (&'static str, &'static str) {
fn page_title(route: &Route) -> &'static str {
match route {
Route::Home {} => (
"Dashboard overview",
"Track product health, monitor key funnels, and coordinate the team from one place.",
),
Route::Components {} => (
"Component library",
"Browse every primitive wired into this starter so new views stay consistent.",
),
Route::Home {} => "Dashboard overview",
Route::Components {} => "Component library",
}
}
#[component]
pub fn Navbar() -> Element {
let collapsed = use_signal(|| false);
let current_route: Route = use_route();
let collapsed_state = collapsed();
let collapsed_setter = collapsed.clone();
let is_dark = use_signal(|| false);
let shell_class = if is_dark() {
"ui-shell shadcn dark"
} else {
"ui-shell shadcn"
};
let (page_title, page_description) = page_meta(&current_route);
let title = page_title(&current_route);
let is_dashboard = matches!(current_route, Route::Home { .. });
let is_components = matches!(current_route, Route::Components { .. });
let theme_label = {
let is_dark = is_dark.clone();
move || {
if is_dark() {
"Light mode"
} else {
"Dark mode"
}
}
};
let theme_toggle = is_dark.clone();
rsx! {
section {
class: "ui-shell shadcn",
class: shell_class,
SidebarLayout {
class: "admin-shell",
SidebarRail { }
SidebarRail {}
Sidebar {
collapsed: collapsed_state,
SidebarHeader {
div { class: "sidebar-brand",
span { class: "sidebar-logo", "" }
@@ -76,7 +83,7 @@ pub fn Navbar() -> Element {
}
}
}
SidebarSeparator { }
SidebarSeparator {}
SidebarGroup {
SidebarGroupLabel { "Shortcuts" }
SidebarGroupContent {
@@ -126,23 +133,28 @@ pub fn Navbar() -> Element {
class: "admin-shell-inset",
header {
class: "admin-shell-topbar",
SidebarTrigger {
collapsed: collapsed_state,
on_toggle: move |next_collapsed: bool| {
collapsed_setter.clone().set(next_collapsed);
},
div { class: "admin-shell-command",
Button {
variant: ButtonVariant::Ghost,
class: Some("admin-command-button".to_string()),
r#type: "button".to_string(),
"⌘K"
}
}
div { class: "admin-shell-meta",
h1 { class: "admin-shell-title", "{page_title}" }
p { class: "admin-shell-description", "{page_description}" }
h1 { class: "admin-shell-title", "{title}" }
}
div { class: "admin-shell-actions",
Badge { variant: BadgeVariant::Secondary, "Operational" }
Button {
variant: ButtonVariant::Default,
class: Some("admin-shell-report".to_string()),
variant: ButtonVariant::Secondary,
class: Some("admin-shell-theme".to_string()),
r#type: "button".to_string(),
"New report"
on_click: move |_| {
let mut handle = theme_toggle.clone();
let current = handle();
handle.set(!current);
},
"{theme_label()}"
}
}
}