Separator source

Inspect and copy the reviewed source included with this Free component.

Free source · 4 files

recipe.rs

// SPDX-FileCopyrightText: 2026 Proa Labs, Inc.
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Separator recipe - type-safe styling system for Separator component
//!
//! Provides orientation-based styling for the Separator component.

use crate::tw_join;
use proa_core::shared::attr_value::AttrValue;
use proa_core::{DataLoader, WebContext, WriteBuf, WriteError};

/// Base styles for the separator
mod base {
    use super::*;

    pub const SEPARATOR_BASE: &str = tw_join!("shrink-0", "bg-border");
}

/// Orientation styles for the separator
mod orientations {
    use super::*;

    pub const SEPARATOR_HORIZONTAL: &str = tw_join!("h-px", "w-full");

    pub const SEPARATOR_VERTICAL: &str = tw_join!("h-full", "w-px");
}

/// Orientation options for the separator
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, proa_macros::ProaVariant)]
#[variant(name = "orientation")]
pub enum SeparatorOrientation {
    /// Horizontal separator (default)
    #[default]
    Horizontal,
    /// Vertical separator
    Vertical,
}

impl SeparatorOrientation {
    /// Get the Tailwind classes for this orientation
    pub const fn classes(self) -> &'static str {
        match self {
            SeparatorOrientation::Horizontal => orientations::SEPARATOR_HORIZONTAL,
            SeparatorOrientation::Vertical => orientations::SEPARATOR_VERTICAL,
        }
    }

    /// Get the data attribute value
    pub const fn as_str(self) -> &'static str {
        match self {
            SeparatorOrientation::Horizontal => "horizontal",
            SeparatorOrientation::Vertical => "vertical",
        }
    }
}

/// Optional inputs accepted by [`SeparatorRecipe::resolve`].
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct SeparatorRecipeProps {
    pub orientation: Option<SeparatorOrientation>,
}

/// Compile-time Separator recipe.
#[derive(Debug, Clone, Copy)]
pub struct SeparatorRecipe {
    root: &'static str,
    orientation_default: SeparatorOrientation,
}

impl SeparatorRecipe {
    pub const fn resolve(&'static self, props: SeparatorRecipeProps) -> SeparatorStyle {
        let orientation = match props.orientation {
            Some(orientation) => orientation,
            None => self.orientation_default,
        };

        SeparatorStyle {
            recipe: self,
            orientation,
        }
    }
}

/// Fully resolved, streamable Separator style.
#[must_use]
#[derive(Debug, Clone, Copy)]
pub struct SeparatorStyle {
    recipe: &'static SeparatorRecipe,
    orientation: SeparatorOrientation,
}

impl SeparatorStyle {
    pub const fn orientation(self) -> SeparatorOrientation {
        self.orientation
    }
}

impl AttrValue for SeparatorStyle {
    #[inline(always)]
    fn should_render(&self) -> bool {
        true
    }

    #[inline(always)]
    fn render_attr_value<B: WriteBuf, L: DataLoader>(
        &self,
        cx: &mut WebContext<L, B>,
    ) -> Result<(), WriteError> {
        cx.out.extend_static(self.recipe.root.as_bytes())?;
        cx.out.extend_static(b" ")?;
        cx.out.extend_static(self.orientation.classes().as_bytes())
    }
}

pub const SEPARATOR_RECIPE: SeparatorRecipe = SeparatorRecipe {
    root: base::SEPARATOR_BASE,
    orientation_default: SeparatorOrientation::Horizontal,
};

pub const fn separator_recipe() -> &'static SeparatorRecipe {
    &SEPARATOR_RECIPE
}

/// Compatibility resolver for callers of the former helper.
pub const fn separator_classes(orientation: SeparatorOrientation) -> SeparatorStyle {
    SEPARATOR_RECIPE.resolve(SeparatorRecipeProps {
        orientation: Some(orientation),
    })
}

impl crate::variant_spec::ComponentSpec for SeparatorRecipe {
    const NAME: &'static str = "Separator";

    fn base_classes(&self) -> &'static str {
        self.root
    }

    fn variant_metadata(&self) -> Vec<crate::variant_spec::VariantMetadata> {
        vec![crate::variant_spec::variant_metadata::<SeparatorOrientation>()]
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn separator_horizontal_has_correct_classes() {
        let base = base::SEPARATOR_BASE;
        let orientation = SeparatorOrientation::Horizontal.classes();
        assert!(base.contains("shrink-0"));
        assert!(base.contains("bg-border"));
        assert!(orientation.contains("h-px"));
        assert!(orientation.contains("w-full"));
    }

    #[test]
    fn separator_vertical_has_correct_classes() {
        let base = base::SEPARATOR_BASE;
        let orientation = SeparatorOrientation::Vertical.classes();
        assert!(base.contains("shrink-0"));
        assert!(base.contains("bg-border"));
        assert!(orientation.contains("h-full"));
        assert!(orientation.contains("w-px"));
    }

    #[test]
    fn separator_orientation_as_str() {
        assert_eq!(SeparatorOrientation::Horizontal.as_str(), "horizontal");
        assert_eq!(SeparatorOrientation::Vertical.as_str(), "vertical");
    }

    #[test]
    fn separator_orientation_default_is_horizontal() {
        assert_eq!(
            SeparatorOrientation::default(),
            SeparatorOrientation::Horizontal
        );
    }

    #[test]
    fn recipe_resolves_defaults_and_overrides() {
        let default = separator_recipe().resolve(SeparatorRecipeProps::default());
        assert_eq!(default.orientation(), SeparatorOrientation::Horizontal);

        let vertical = separator_recipe().resolve(SeparatorRecipeProps {
            orientation: Some(SeparatorOrientation::Vertical),
        });
        assert_eq!(vertical.orientation(), SeparatorOrientation::Vertical);
        assert!(vertical.orientation().classes().contains("w-px"));
    }
}

Copy this source with the Free Proa UI components it imports; those component files remain available from their own source pages.

Licensed under MIT OR Apache-2.0. Third-party notices remain attached to the installed payload.

Open Markdown
FreeSeparator

Visual dividers.

Install with the Proa CLI
proa ui add separator

Installs the reviewed component source, dependencies, shared support files, and required legal notices.

CLI and registry setup
recipe.rs
// SPDX-FileCopyrightText: 2026 Proa Labs, Inc.
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Separator recipe - type-safe styling system for Separator component
//!
//! Provides orientation-based styling for the Separator component.

use crate::tw_join;
use proa_core::shared::attr_value::AttrValue;
use proa_core::{DataLoader, WebContext, WriteBuf, WriteError};

/// Base styles for the separator
mod base {
    use super::*;

    pub const SEPARATOR_BASE: &str = tw_join!("shrink-0", "bg-border");
}

/// Orientation styles for the separator
mod orientations {
    use super::*;

Search

Type at least 2 characters

Customize

Make it yours

Palette

Radius

Overview
Components
Settings

Build your own

Themed Proa UI surface

Preview
Components52
RecipesTyped
customer-portal