layoutcss_parser/components/
sidebar.rs1use indoc::formatdoc;
2use crate::harmonic::get_harmonic;
3
4use std::collections::HashSet;
5const SIDEBAR_STYLE: &str = r#"
6 sidebar-l{
7 display: flex;
8 flex-wrap: wrap;
9 }
10"#;
11
12const SIDEBAR_REVERSE_STYLE: &str = r#"
13 sidebar-l[layout~=reverse]{
14 flex-wrap: wrap-reverse;
15 }
16"#;
17
18fn sidebar_shrink_style(reverse: bool) -> String {
19 formatdoc!(
20 r#"
21 sidebar-l[layout~=shrink]{{
22 align-items: flex-{};
23 }}
24 "#,
25 if reverse { "end" } else { "start" }
26 )
27}
28
29fn sidebar_gap_style(value: &str, harmonic: String) -> String {
30 formatdoc!(
31 r#"
32 sidebar-l[layout~="gap:{value}"]{{
33 gap: {harmonic};
34 }}
35 "#,
36 )
37}
38
39fn sidebar_gap_x_style(value: &str, harmonic: String) -> String {
40 formatdoc!(
41 r#"
42 sidebar-l[layout~="gap-x:{value}"]{{
43 column-gap: {harmonic};
44 }}
45 "#,
46 )
47}
48
49fn sidebar_gap_y_style(value: &str, harmonic: String) -> String {
50 formatdoc!(
51 r#"
52 sidebar-l[layout~="gap-y:{value}"]{{
53 row-gap: {harmonic};
54 }}
55 "#,
56 )
57}
58
59fn sidebar_group_style(
60 side_selector: String,
63 side_width_selector: String,
64 content_min_selector: String,
65 selector_one: &str,
66 selector_two: &str,
67 side_width: &str,
68 content_min: &str,
69) -> String {
70 formatdoc!(
71 r#"
72 sidebar-l{side_selector}{side_width_selector}{content_min_selector} > {selector_one}:not(outsider-l[layout~="disinherit"]) {{
73 flex-basis: {side_width};
74 flex-grow: 1;
75 min-inline-size: initial;
76 min-width:0;
77 min-height:0;
78 }}
79
80 sidebar-l{side_selector}{side_width_selector}{content_min_selector} > {selector_two}:not(outsider-l[layout~="disinherit"]) {{
81 flex-basis: 0;
82 flex-grow: 999;
83 min-inline-size: {content_min};
84 }}
85 "#,
86 )
87}
88
89pub fn sidebar_css(
90 reverse: bool,
91 shrink: bool,
92 side: Option<&str>,
93 side_width: Option<&str>,
94 content_min: Option<&str>,
95 gap: Option<&str>,
96 gap_x: Option<&str>,
97 gap_y: Option<&str>,
98 harmonic_ratio: f64,
99 set: &mut HashSet<String>,
100) {
101 set.insert(SIDEBAR_STYLE.to_string());
102 if reverse {
103 set.insert(SIDEBAR_REVERSE_STYLE.to_string());
104 }
105 if shrink {
106 set.insert(sidebar_shrink_style(reverse));
107 }
108 if let Some(value) = gap {
109 let harmonic_value = get_harmonic(&value, harmonic_ratio);
110 set.insert(sidebar_gap_style(value, harmonic_value));
111 }
112 if let Some(ref value) = gap_x {
113 let harmonic_value = get_harmonic(&value, harmonic_ratio);
114 set.insert(sidebar_gap_x_style(value, harmonic_value));
115 }
116 if let Some(ref value) = gap_y {
117 let harmonic_value = get_harmonic(&value, harmonic_ratio);
118 set.insert(sidebar_gap_y_style(value, harmonic_value));
119 }
120 if side.is_some() || side_width.is_some() || content_min.is_some() {
121 let side_width_selector = if let Some(ref val) = side_width {
122 formatdoc!(r#"[layout*="side-width:{}"]"#, val)
123 } else {
124 "".to_string()
125 };
126 let content_min_selector = if let Some(ref val) = content_min {
127 formatdoc!(r#"[layout*="content-min:{}"]"#, val)
128 } else {
129 "".to_string()
130 };
131 let side_selector = if let Some(ref val) = side {
132 formatdoc!(r#"[layout*="side:{}"]"#, val)
133 } else {
134 "".to_string()
135 };
136
137 let selector_one = match side {
138 None => ":first-child",
139 Some(val) if val == "left" => ":first-child",
140 _ => ":last-child",
141 };
142 let selector_two = if selector_one == ":first-child" {
143 ":last-child"
144 } else {
145 ":first-child"
146 };
147 let content_min = if let Some(val) = content_min {
148 val
149 } else {
150 "50%"
151 };
152 let side_width = if let Some(val) = side_width {
153 val
154 } else {
155 "auto"
156 };
157
158 set.insert(sidebar_group_style(
159 side_selector,
160 side_width_selector,
161 content_min_selector,
162 selector_one,
163 selector_two,
164 side_width,
165 content_min,
166 ));
167 }
168}