Skip to main content

fret_ui/resizable_panel_group/
style.rs

1use fret_core::{Color, Px};
2
3use crate::Theme;
4
5#[derive(Debug, Clone)]
6pub struct ResizablePanelGroupStyle {
7    /// Layout gap between panels in logical px.
8    ///
9    /// This does **not** need to match `hit_thickness`: it is common to keep the visual/layout gap
10    /// small (or zero) while using a larger hit area for usability.
11    pub gap: Px,
12    /// Thickness of the handle region in logical px.
13    ///
14    /// This region is used for hit-testing (and can be larger than `gap`).
15    pub hit_thickness: Px,
16    /// Visual thickness in *device* pixels (converted using the current scale factor).
17    pub paint_device_px: f32,
18    pub handle_color: Color,
19    pub handle_alpha: f32,
20    pub handle_hover_alpha: f32,
21    pub handle_drag_alpha: f32,
22}
23
24impl Default for ResizablePanelGroupStyle {
25    fn default() -> Self {
26        Self {
27            gap: Px(0.0),
28            hit_thickness: Px(6.0),
29            paint_device_px: 1.0,
30            handle_color: Color {
31                r: 1.0,
32                g: 1.0,
33                b: 1.0,
34                a: 1.0,
35            },
36            // Align with shadcn/ui: the handle line should use the border color at full opacity.
37            // Contrast remains subtle because the `border` token is intentionally low-contrast.
38            handle_alpha: 1.0,
39            handle_hover_alpha: 1.0,
40            handle_drag_alpha: 1.0,
41        }
42    }
43}
44
45impl ResizablePanelGroupStyle {
46    pub fn from_theme(theme: &Theme) -> Self {
47        let handle_color = theme
48            .color_by_key("border")
49            .or_else(|| theme.color_by_key("input"))
50            .unwrap_or(theme.snapshot().colors.panel_border);
51
52        Self {
53            // Note: this runtime crate intentionally avoids reading component-layer extension tokens
54            // (e.g. `component.*`). Component libraries should resolve their own chrome and pass an
55            // explicit `ResizablePanelGroupStyle` when needed.
56            gap: Px(0.0),
57            hit_thickness: Px(6.0),
58            paint_device_px: 1.0,
59            handle_color,
60            ..Default::default()
61        }
62    }
63}