-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
aside.gleam
138 lines (121 loc) · 4.6 KB
/
aside.gleam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// IMPORTS ---------------------------------------------------------------------
import gleam/int
import lustre/attribute.{type Attribute, attribute}
import lustre/element.{type Element}
import lustre/element/html
// ELEMENTS --------------------------------------------------------------------
/// A two-column layout with a side column and a main column. When laid out
/// side-by-side, the main column always occupies at least 60% of the width of
/// the container by default. When the width of the side column makes this
/// impossible, the layout switches to a stack with the side column displayed
/// first.
///
/// It is possible to flip the layout so that the main column is displayed first
/// by using the `content_first` attribute. You can switch back to the default
/// behaviour with the `content_last` attribute.
///
pub fn aside(
attributes: List(Attribute(msg)),
side: Element(msg),
main: Element(msg),
) -> Element(msg) {
of(html.div, attributes, side, main)
}
/// The default `aside` element uses a `<div />` as the underling container. You
/// can use this function if you want to use a different container such as a
/// `<section />` or `<article />`.
///
pub fn of(
element: fn(List(Attribute(msg)), List(Element(msg))) -> Element(msg),
attributes: List(Attribute(msg)),
side: Element(msg),
main: Element(msg),
) -> Element(msg) {
element([attribute.class("lustre-ui-aside"), ..attributes], [side, main])
}
// ATTRIBUTES ------------------------------------------------------------------
/// Visually places the main content first in the layout. Note that this doesn't
/// change the markup: the side content is always the first child of the aside
/// container.
///
pub fn content_first() -> Attribute(msg) {
attribute.class("content-first")
}
/// Visually places the main content last in the layout. Note that this doesn't
/// change the markup: the side content is always the first child of the aside
/// container.
///
pub fn content_last() -> Attribute(msg) {
attribute.class("content-last")
}
/// When the main content is taller than the side content, the align_start
/// attribute tells the side content to align itself to the top of the container.
///
pub fn align_start() -> Attribute(msg) {
attribute.class("align-start")
}
/// When the main content is taller than the side content, the align_centre
/// attribute tells the side content to align itself to the middle of the
/// container.
///
pub fn align_centre() -> Attribute(msg) {
attribute.class("align-centre")
}
/// When the main content is taller than the side content, the align_end attribute
/// tells the side content to align itself to the bottom of the container.
///
pub fn align_end() -> Attribute(msg) {
attribute.class("align-end")
}
/// The stretch attribute tells the side content to grow to match the height of
/// the main content. This is useful if you have a side column with a background
/// you want to fill or an image you want to stretch to the full height of the
/// container.
///
pub fn stretch() -> Attribute(msg) {
attribute.class("stretch")
}
/// Packed spacing has no gap between each child element.
///
pub fn packed() -> Attribute(msg) {
attribute.class("packed")
}
/// Tight spacing has a small gap between each child element.
///
pub fn tight() -> Attribute(msg) {
attribute.class("tight")
}
/// Relaxed spacing has a medium-sized gap between each child element. This is
/// the default gap but is provided as an attribute in case you want to toggle
/// between different spaces.
///
pub fn relaxed() -> Attribute(msg) {
attribute.class("relaxed")
}
/// Loose spacing has a large gap between each child element.
///
pub fn loose() -> Attribute(msg) {
attribute.class("loose")
}
/// Use this function to set a custom gap between each child element. You'll need
/// to use this function if you want a larger gap than `loose` or a smaller one
/// than `tight`.
///
/// You can pass any valid CSS length value to this function such as `1rem` or
/// `10px`, or you can use CSS variables such as `var(--space-xs)` to use the
/// space scale from the theme.
///
pub fn space(gap: String) -> Attribute(msg) {
attribute.style([#("--gap", gap)])
}
/// This attribute specifies the minimum width of the main content before forcing
/// the layout to stack. Values represent a percentage of the container width, and
/// are clamped between 10% and 90%.
///
pub fn min_width(width: Int) -> Attribute(msg) {
case width < 10, width > 90 {
True, _ -> attribute.style([#("--min", "10%")])
False, False -> attribute.style([#("--min", int.to_string(width) <> "%")])
_, True -> attribute.style([#("--min", "90%")])
}
}