mirror of
https://github.com/mztlive/dx-admin-template.git
synced 2025-12-22 21:59:59 +00:00
移除resizeable组件
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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 体系
|
||||
|
||||
包含构建侧边导航所需的所有子组件。
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user