移除resizeable组件

This commit is contained in:
tommy
2025-11-04 13:44:56 +08:00
parent 5565147d70
commit 777467c0c4
5 changed files with 9 additions and 256 deletions

View File

@@ -692,88 +692,6 @@
background: transparent;
}
.ui-resizable-panels {
display: flex;
gap: 0.5rem;
align-items: stretch;
}
.ui-resizable-panels[data-orientation="vertical"] {
flex-direction: column;
height: 100%;
}
.ui-resizable-pane {
flex: 0 1 auto;
background-color: hsl(var(--background));
border: 1px solid hsl(var(--border));
border-radius: calc(var(--radius) - 2px);
padding: 0.75rem;
box-shadow: var(--shadow-xs);
min-width: 6rem;
min-height: 4rem;
}
.ui-resizable-handle-stack {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.35rem;
}
.ui-resizable-panels[data-orientation="vertical"] .ui-resizable-handle-stack {
flex-direction: row;
}
.ui-resizable-handle {
width: 0.4rem;
height: 3rem;
border-radius: 999px;
background: repeating-linear-gradient(
90deg,
hsl(var(--border)),
hsl(var(--border)) 2px,
transparent 2px,
transparent 4px
);
opacity: 0.6;
}
.ui-resizable-panels[data-orientation="vertical"] .ui-resizable-handle {
width: 3rem;
height: 0.4rem;
background: repeating-linear-gradient(
0deg,
hsl(var(--border)),
hsl(var(--border)) 2px,
transparent 2px,
transparent 4px
);
}
.ui-resizable-slider {
appearance: none;
width: 4.5rem;
height: 0.3rem;
border-radius: 999px;
background: hsl(var(--muted));
cursor: ew-resize;
}
.ui-resizable-slider::-webkit-slider-thumb {
appearance: none;
width: 0.9rem;
height: 0.9rem;
border-radius: 50%;
background: hsl(var(--primary));
box-shadow: var(--shadow-sm);
}
.ui-resizable-panels[data-orientation="vertical"] .ui-resizable-slider {
cursor: ns-resize;
}
.ui-dropzone {
position: relative;
border: 1.5px dashed hsl(var(--border));

View File

@@ -238,29 +238,6 @@ fn ScrollAreaSample() -> Element {
}
```
### ResizablePanels
可拖拽的双列布局。
- `initial`/`min`/`max` 控制百分比分布;`orientation` 可设 Horizontal / Vertical。
- `on_resize` 回调返回当前主面板占比。
```rust
use crate::components::ui::{ResizableOrientation, ResizablePanels};
use dioxus::prelude::*;
#[component]
fn ResizableSample() -> Element {
rsx! {
ResizablePanels {
orientation: ResizableOrientation::Horizontal,
first: rsx! { div { class: "ui-pane-muted", "左侧面板" } },
second: rsx! { div { class: "ui-pane-surface", "右侧面板" } },
}
}
}
```
### Sidebar 体系
包含构建侧边导航所需的所有子组件。

View File

@@ -30,7 +30,6 @@ mod pagination;
mod popover;
mod progress;
mod radio_group;
mod resizable;
mod scroll_area;
mod select;
mod separator;
@@ -76,7 +75,6 @@ pub use pagination::*;
pub use popover::*;
pub use progress::*;
pub use radio_group::*;
pub use resizable::*;
pub use scroll_area::*;
pub use select::*;
pub use separator::*;

View File

@@ -1,104 +0,0 @@
use dioxus::html::events::FormEvent;
use dioxus::prelude::*;
fn merge_class(base: &str, extra: Option<String>) -> String {
if let Some(extra) = extra.filter(|extra| !extra.trim().is_empty()) {
format!("{base} {}", extra.trim())
} else {
base.to_string()
}
}
#[allow(dead_code)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ResizableOrientation {
Horizontal,
Vertical,
}
impl ResizableOrientation {
fn as_str(&self) -> &'static str {
match self {
ResizableOrientation::Horizontal => "horizontal",
ResizableOrientation::Vertical => "vertical",
}
}
}
impl Default for ResizableOrientation {
fn default() -> Self {
ResizableOrientation::Horizontal
}
}
#[component]
pub fn ResizablePanels(
first: Element,
second: Element,
#[props(default = 0.5f32)] initial: f32,
#[props(default = 0.2f32)] min: f32,
#[props(default = 0.8f32)] max: f32,
#[props(default)] orientation: ResizableOrientation,
#[props(optional)] on_resize: Option<EventHandler<f32>>,
#[props(into, default)] class: Option<String>,
) -> Element {
let min_clamped = min.clamp(0.05, 0.95);
let max_clamped = max.clamp(min_clamped + f32::EPSILON, 0.95);
let initial_ratio = initial.clamp(min_clamped, max_clamped);
let ratio = use_signal(move || initial_ratio);
let classes = merge_class("ui-resizable-panels", class);
let orientation_attr = orientation.as_str();
let on_resize_handler = on_resize.clone();
let slider_min = (min_clamped * 100.0).round();
let slider_max = (max_clamped * 100.0).round();
let ratio_value = ratio();
let first_basis = format!("{:.2}%", ratio_value * 100.0);
let second_basis = format!("{:.2}%", (1.0 - ratio_value) * 100.0);
let slider_value = format!("{:.0}", ratio_value * 100.0);
rsx! {
div {
class: classes,
"data-orientation": orientation_attr,
div {
class: "ui-resizable-pane",
style: format!("flex-basis: {first_basis};"),
{first}
}
div {
class: "ui-resizable-handle-stack",
div { class: "ui-resizable-handle" }
input {
class: "ui-resizable-slider",
r#type: "range",
min: format!("{slider_min:.0}"),
max: format!("{slider_max:.0}"),
step: "1",
value: slider_value,
"aria-label": "Resize panels",
oninput: {
let mut ratio_signal = ratio.clone();
let min = min_clamped;
let max = max_clamped;
let handler = on_resize_handler.clone();
move |event: FormEvent| {
if let Ok(raw) = event.value().parse::<f32>() {
let value = (raw / 100.0).clamp(min, max);
ratio_signal.set(value);
if let Some(callback) = handler.clone() {
callback.call(value);
}
}
}
},
}
}
div {
class: "ui-resizable-pane",
style: format!("flex-basis: {second_basis};"),
{second}
}
}
}
}

View File

@@ -6,14 +6,14 @@ use crate::components::ui::{
ContextItem, ContextMenu, Crumb, DateRange, DateRangePicker, Dialog, DropdownMenu,
DropdownMenuItem, FileDropZone, FileMetadata, FormField, FormMessage, FormMessageVariant,
HoverCard, Input, Label, Menubar, MenubarItem, MenubarMenu, NavigationItem, NavigationMenu,
Pagination, Popover, Progress, RadioGroup, RadioGroupItem, ResizableOrientation,
ResizablePanels, ScrollArea, Select, SelectOption, Separator, SeparatorOrientation, Sheet,
SheetSide, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent,
SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarLayout, SidebarMenu, SidebarMenuButton,
SidebarMenuItem, SidebarSeparator, SidebarTrigger, Skeleton, Slider, StepItem, Steps, Switch,
Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs,
TabsContent, TabsList, TabsTrigger, Textarea, Toast, ToastViewport, Toggle, ToggleGroup,
ToggleGroupItem, ToggleGroupMode, ToggleGroupOrientation, Tooltip,
Pagination, Popover, Progress, RadioGroup, RadioGroupItem, ScrollArea, Select, SelectOption,
Separator, SeparatorOrientation, Sheet, SheetSide, Sidebar, SidebarContent, SidebarFooter,
SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset,
SidebarLayout, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarSeparator,
SidebarTrigger, Skeleton, Slider, StepItem, Steps, Switch, Table, TableBody, TableCaption,
TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList,
TabsTrigger, Textarea, Toast, ToastViewport, Toggle, ToggleGroup, ToggleGroupItem,
ToggleGroupMode, ToggleGroupOrientation, Tooltip,
};
use chrono::NaiveDate;
use dioxus::html::events::FormEvent;
@@ -69,7 +69,6 @@ fn UiShowcase() -> Element {
))
});
let dropzone_files = use_signal(|| Vec::<FileMetadata>::new());
let resizable_ratio = use_signal(|| 0.45f32);
let slider_value_signal = slider_value.clone();
let slider_value_setter = slider_value.clone();
let contact_method_signal = contact_method.clone();
@@ -109,8 +108,6 @@ fn UiShowcase() -> Element {
let date_range_setter = date_range_value.clone();
let dropzone_files_signal = dropzone_files.clone();
let dropzone_files_setter = dropzone_files.clone();
let resizable_ratio_signal = resizable_ratio.clone();
let resizable_ratio_setter = resizable_ratio.clone();
let intensity_text = move || format!("Accent intensity: {:.0}%", slider_value_signal());
let contact_text = move || format!("Preferred contact: {}", contact_method_signal());
let profile_preview = move || {
@@ -167,14 +164,6 @@ fn UiShowcase() -> Element {
format!("{} file(s) staged.", files.len())
}
};
let resizable_summary = move || {
let ratio = resizable_ratio_signal();
format!(
"Split: {:.0}% / {:.0}%",
ratio * 100.0,
(1.0 - ratio) * 100.0
)
};
let select_options = vec![
SelectOption::new("System", "system"),
SelectOption::new("Light", "light"),
@@ -504,7 +493,7 @@ fn UiShowcase() -> Element {
Card {
CardHeader {
CardTitle { "Layout & uploads" }
CardDescription { "Aspect ratios, resizable panels, and drag-and-drop staging." }
CardDescription { "Aspect ratios and drag-and-drop staging." }
}
CardContent {
div { class: "ui-stack",
@@ -515,31 +504,6 @@ fn UiShowcase() -> Element {
"Video or hero media stays perfectly scaled."
}
}
ResizablePanels {
orientation: ResizableOrientation::Horizontal,
initial: resizable_ratio_signal(),
on_resize: {
let mut setter = resizable_ratio_setter.clone();
move |ratio| setter.set(ratio)
},
first: rsx! {
div { class: "ui-stack",
SpanHelper { "Primary workbench" }
SpanHelper { "Keep data tables or editors anchored on the left." }
}
},
second: rsx! {
div { class: "ui-stack",
SpanHelper { "Preview" }
SpanHelper { "Live output or documentation tracks on the right pane." }
}
}
}
FormMessage {
variant: FormMessageVariant::Helper,
class: Some("ui-field-helper".to_string()),
"{resizable_summary()}"
}
FileDropZone {
multiple: true,
on_files: {