Skip to main content

card_rs/
common.rs

1// Copyright 2026 Open SASS Core Maintainers.
2//
3// Licensed under the MIT license
4// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
5// option. This file may not be copied, modified, or distributed
6// except according to those terms.
7
8/// Semantic prominence level of a [`Card`] component.
9///
10/// Each variant maps to a distinct background-color class so that themes can
11/// interpret "prominence" differently without hard-coding specific palettes
12/// into component logic.
13///
14/// # Default
15///
16/// [`Variant::Default`] is the default variant.
17///
18/// # Examples
19///
20/// ```rust
21/// use card_rs::Variant;
22///
23/// let cls = Variant::Tertiary.to_class();
24/// assert_eq!(cls, "card--tertiary");
25///
26/// let style = Variant::Transparent.to_style();
27/// assert!(style.contains("transparent"));
28/// ```
29#[derive(Debug, Clone, PartialEq, Default, Copy)]
30pub enum Variant {
31    /// Minimal prominence, transparent background.
32    ///
33    /// Use for less important content or for cards nested inside other cards.
34    Transparent,
35
36    /// Standard card appearance (`bg-surface`). This is the default.
37    ///
38    /// Suitable for most use cases.
39    #[default]
40    Default,
41
42    /// Medium prominence (`bg-surface-secondary`).
43    ///
44    /// Use to draw moderate attention.
45    Secondary,
46
47    /// Higher prominence (`bg-surface-tertiary`).
48    ///
49    /// Use for primary or featured content.
50    Tertiary,
51
52    /// Arbitrary inline CSS styling for the variant.
53    ///
54    /// E.g. `"background: linear-gradient(...);"`.
55    Custom(&'static str),
56}
57
58impl Variant {
59    /// Returns the BEM modifier CSS class for this variant.
60    ///
61    /// # Returns
62    ///
63    /// One of `"card--transparent"`, `"card--default"`, `"card--secondary"`,
64    /// or `"card--tertiary"`.
65    pub fn to_class(self) -> &'static str {
66        match self {
67            Self::Transparent => "card--transparent",
68            Self::Default => "card--default",
69            Self::Secondary => "card--secondary",
70            Self::Tertiary => "card--tertiary",
71            Self::Custom(_) => "card--custom",
72        }
73    }
74
75    /// Returns the inline CSS background/border style for this variant.
76    ///
77    /// These values mirror the HeroUI design token mapping:
78    /// - `transparent` → no background
79    /// - `default` → `#ffffff` surface with a subtle border
80    /// - `secondary` → light gray surface
81    /// - `tertiary` → slightly warmer surface
82    pub fn to_style(self) -> &'static str {
83        match self {
84            Self::Transparent => "background: transparent;",
85            Self::Default => "background: #ffffff; border: 1px solid #e5e7eb;",
86            Self::Secondary => "background: #f9fafb; border: 1px solid #e5e7eb;",
87            Self::Tertiary => "background: #f3f4f6; border: 1px solid #d1d5db;",
88            Self::Custom(s) => s,
89        }
90    }
91}
92
93/// Returns the base inline CSS applied to every [`Card`] container element.
94///
95/// Sets `position: relative`, flex column layout, padding, border-radius,
96/// and `box-sizing` so child elements inherit a predictable layout model.
97pub fn base_card_style() -> &'static str {
98    "position: relative; display: flex; flex-direction: column; border-radius: 0.75rem; padding: 1rem; box-sizing: border-box; overflow: hidden;"
99}
100
101/// Returns the base inline CSS applied to every [`Header`] element.
102///
103/// Sets a flex column layout with a small gap between title and description.
104pub fn base_header_style() -> &'static str {
105    "display: flex; flex-direction: column; gap: 0.25rem;"
106}
107
108/// Returns the base inline CSS applied to every [`Title`] element.
109///
110/// Sets a medium font weight and a comfortable font size.
111pub fn base_title_style() -> &'static str {
112    "font-size: 1rem; font-weight: 600; line-height: 1.5; margin: 0;"
113}
114
115/// Returns the base inline CSS applied to every [`Description`] element.
116///
117/// Uses a muted text color and a slightly smaller font size.
118pub fn base_description_style() -> &'static str {
119    "font-size: 0.875rem; color: #6b7280; line-height: 1.5; margin: 0;"
120}
121
122/// Returns the base inline CSS applied to every [`Content`] element.
123///
124/// A simple flex column container with a small top gap.
125pub fn base_content_style() -> &'static str {
126    "display: flex; flex-direction: column; gap: 0.5rem;"
127}
128
129/// Returns the base inline CSS applied to every [`Footer`] element.
130///
131/// Lays children out in a horizontal row with a small gap.
132pub fn base_footer_style() -> &'static str {
133    "display: flex; flex-direction: row; align-items: center; gap: 0.5rem;"
134}
135
136// Copyright 2026 Open SASS Core Maintainers.
137//
138// Licensed under the MIT license
139// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
140// option. This file may not be copied, modified, or distributed
141// except according to those terms.