liora-components 0.1.7

Enterprise-style native GPUI component library for Liora applications.
Documentation
//! Divider module.
//!
//! This public module implements the Liora visual divider component for separating content groups. It keeps the reusable
//! component logic inside `liora-components` rather than Gallery or Docs so
//! downstream GPUI applications can compose the same behavior with their own
//! app state, assets, and release policy.
//!
//! ## Usage model
//!
//! Components in this module render native GPUI element trees. Stateless builder
//! values can be constructed inline, while controls with focus, selection,
//! popup, drag, or editing state should be stored as `gpui::Entity<T>` fields in
//! the parent view so state survives GPUI render passes.
//!
//! ## Design contract
//!
//! The implementation should use Liora theme tokens from `liora-core` and
//! `liora-theme`, keep accessibility-oriented keyboard/pointer behavior close to
//! the component, and avoid app-specific Gallery/Docs resources in this SDK
//! crate.

use gpui::{App, Component, IntoElement, RenderOnce, Window, prelude::*, px};

/// Fluent native GPUI component for rendering Liora divider.
pub struct Divider {
    vertical: bool,
    label: Option<String>,
}

impl Divider {
    /// Creates `Divider` with default theme-driven styling and no optional callbacks attached.
    pub fn new() -> Self {
        Self {
            vertical: false,
            label: None,
        }
    }

    /// Uses vertical orientation or gradient direction.
    pub fn vertical(mut self) -> Self {
        self.vertical = true;
        self
    }

    /// Returns the stable user-facing label for this value.
    pub fn label(mut self, text: impl Into<String>) -> Self {
        self.label = Some(text.into());
        self
    }
}

impl RenderOnce for Divider {
    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
        let theme = &cx.global::<liora_core::Config>().theme;

        if self.vertical {
            gpui::div().w(px(1.0)).h_full().bg(theme.neutral.border)
        } else if let Some(text) = self.label {
            gpui::div()
                .flex()
                .flex_row()
                .items_center()
                .gap_2()
                .w_full()
                .child(gpui::div().flex_1().h(px(1.0)).bg(theme.neutral.border))
                .child(
                    gpui::div()
                        .text_size(px(theme.font_size.sm))
                        .text_color(theme.neutral.text_3)
                        .child(text),
                )
                .child(gpui::div().flex_1().h(px(1.0)).bg(theme.neutral.border))
        } else {
            gpui::div().w_full().h(px(1.0)).bg(theme.neutral.border)
        }
    }
}

impl IntoElement for Divider {
    type Element = Component<Self>;
    fn into_element(self) -> Self::Element {
        Component::new(self)
    }
}