encre_css/plugins/layout/container/
mod.rs1#![doc = include_str!("README.md")]
2#![doc(alias = "layout")]
3use crate::{config::BUILTIN_SCREENS, prelude::build_plugin::*};
4
5use std::{borrow::Cow, cmp::Ordering};
6
7pub(crate) const PLUGIN: StaticPlugin = Plugin::Functional(Functional {
8 namespace: "container",
9 can_handle: |context| matches!(context.modifier, Modifier::Builtin { value: "", .. }),
10 handle: |context| {
11 if let Modifier::Builtin { .. } = context.modifier {
12 generate_wrapper(context, |context| {
13 context.buffer.line("width: 100%;");
14 });
15
16 context.buffer.raw("\n\n");
17
18 let mut first_child = true;
19
20 generate_at_rules(context, |context| {
21 let mut screens = context
22 .config
23 .theme
24 .screens
25 .iter()
26 .map(|(a, b)| (a.clone(), b.clone()))
27 .chain(
28 BUILTIN_SCREENS
29 .iter()
30 .map(|(a, b)| (Cow::from(*a), Cow::from(*b))),
31 )
32 .collect::<Vec<(Cow<str>, Cow<str>)>>();
33
34 screens.sort_by(|a, b| a.0.cmp(&b.0));
36 screens.dedup_by(|a, b| a.0.eq(&b.0));
37
38 screens.sort_by(|a, b| {
40 let a = if let Some(first_char_a) = a.1.chars().position(char::is_alphabetic) {
41 a.1[..first_char_a].parse::<usize>().ok()
42 } else {
43 a.1.parse::<usize>().ok()
44 };
45
46 let b = if let Some(first_char_b) = b.1.chars().position(char::is_alphabetic) {
47 b.1[..first_char_b].parse::<usize>().ok()
48 } else {
49 b.1.parse::<usize>().ok()
50 };
51
52 if let Some(a) = a {
53 if let Some(b) = b {
54 a.cmp(&b)
55 } else {
56 Ordering::Less
57 }
58 } else {
59 Ordering::Greater
60 }
61 });
62
63 for (_, screen) in &screens {
64 if first_child {
65 first_child = false;
66 } else if context.buffer.is_unindented() {
67 context.buffer.raw("\n\n");
68 } else {
69 context.buffer.raw("\n");
70 }
71
72 context
73 .buffer
74 .line(format_args!("@media (width >= {screen}) {{"));
75 context.buffer.indent();
76
77 generate_class(
78 context,
79 |context| {
80 context.buffer.line(format_args!("max-width: {screen};"));
81 },
82 "",
83 );
84
85 context.buffer.unindent();
86 if context.buffer.is_unindented() {
87 context.buffer.raw("}");
88 } else {
89 context.buffer.line("}");
90 }
91 }
92
93 while !context.buffer.is_unindented() {
95 context.buffer.unindent();
96
97 if context.buffer.is_unindented() {
98 context.buffer.raw("}");
99 } else {
100 context.buffer.line("}");
101 }
102 }
103 });
104 }
105 },
106 ..Functional::default()
107});