rustyle_css/components/
pagination.rs

1//! Pagination component styles
2//!
3//! Provides type-safe pagination styling with variants and sizes.
4
5use super::{ComponentStyle, Size, Variant};
6use crate::css::{Color, Radius, Spacing};
7use crate::tokens::{BorderTokens, ColorTokens, SpacingTokens};
8
9/// Pagination style configuration
10#[derive(Clone, Debug)]
11pub struct PaginationStyle {
12    pub variant: Variant,
13    pub size: Size,
14    pub tokens: Option<PaginationTokens>,
15}
16
17/// Pagination design tokens
18#[derive(Clone, Debug)]
19pub struct PaginationTokens {
20    pub colors: ColorTokens,
21    pub spacing: SpacingTokens,
22    pub borders: BorderTokens,
23}
24
25impl PaginationStyle {
26    /// Create a new pagination style
27    pub fn new(variant: Variant, size: Size) -> Self {
28        Self {
29            variant,
30            size,
31            tokens: None,
32        }
33    }
34
35    /// Set custom tokens
36    pub fn tokens(mut self, tokens: PaginationTokens) -> Self {
37        self.tokens = Some(tokens);
38        self
39    }
40
41    fn active_color(&self) -> Color {
42        let default_colors = ColorTokens::default();
43        let colors = self
44            .tokens
45            .as_ref()
46            .map(|t| &t.colors)
47            .unwrap_or(&default_colors);
48
49        match &self.variant {
50            Variant::Primary => colors.primary.c600.clone(),
51            Variant::Secondary => colors.secondary.c600.clone(),
52            Variant::Success => colors.semantic.success.clone(),
53            Variant::Error => colors.semantic.error.clone(),
54            Variant::Warning => colors.semantic.warning.clone(),
55            Variant::Info => colors.semantic.info.clone(),
56        }
57    }
58
59    fn padding(&self) -> Spacing {
60        let default_spacing = SpacingTokens::default();
61        let spacing = self
62            .tokens
63            .as_ref()
64            .map(|t| &t.spacing)
65            .unwrap_or(&default_spacing);
66
67        match &self.size {
68            Size::Small => Spacing::all(spacing.xs.clone()),
69            Size::Medium => Spacing::all(spacing.sm.clone()),
70            Size::Large => Spacing::all(spacing.md.clone()),
71            Size::ExtraLarge => Spacing::all(spacing.lg.clone()),
72        }
73    }
74
75    fn border_radius(&self) -> Radius {
76        let default_borders = BorderTokens::default();
77        let borders = self
78            .tokens
79            .as_ref()
80            .map(|t| &t.borders)
81            .unwrap_or(&default_borders);
82
83        Radius::all(borders.radius.base.clone())
84    }
85}
86
87impl ComponentStyle for PaginationStyle {
88    fn to_css(&self) -> String {
89        let mut css = String::new();
90
91        css.push_str("display: flex; ");
92        css.push_str("gap: 0.5rem; ");
93        css.push_str("align-items: center; ");
94
95        let padding = self.padding();
96        let active_color = self.active_color();
97        let radius = self.border_radius();
98
99        css.push_str(&format!(
100            ".rustyle-pagination-item {{ padding: {}; border-radius: {}; border: 1px solid #e5e7eb; cursor: pointer; }} ",
101            padding.to_css(),
102            radius.to_css()
103        ));
104
105        css.push_str(&format!(
106            ".rustyle-pagination-item.active {{ background-color: {}; color: white; border-color: {}; }} ",
107            active_color.to_css(),
108            active_color.to_css()
109        ));
110
111        css
112    }
113
114    fn class_name(&self) -> &str {
115        "rustyle-pagination"
116    }
117}
118
119impl Default for PaginationStyle {
120    fn default() -> Self {
121        Self::new(Variant::Primary, Size::Medium)
122    }
123}