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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! Typography component — text utility components for consistent typographic styling.
use maud::{html, Markup};
/// Heading 1 (2rem, bold)
pub fn h1(text: &str) -> Markup {
html! { h1.mui-h1 { (text) } }
}
/// Heading 2 (1.5rem, semi-bold)
pub fn h2(text: &str) -> Markup {
html! { h2.mui-h2 { (text) } }
}
/// Heading 3 (1.25rem, semi-bold)
pub fn h3(text: &str) -> Markup {
html! { h3.mui-h3 { (text) } }
}
/// Heading 4 (1.125rem, semi-bold)
pub fn h4(text: &str) -> Markup {
html! { h4.mui-h4 { (text) } }
}
/// Paragraph (0.875rem, standard)
pub fn p(text: &str) -> Markup {
html! { p.mui-p { (text) } }
}
/// Lead text (large intro, 1.125rem, muted)
pub fn lead(text: &str) -> Markup {
html! { p.mui-lead { (text) } }
}
/// Muted text (0.875rem, muted color)
pub fn muted(text: &str) -> Markup {
html! { span.mui-muted { (text) } }
}
/// Inline code (monospace, small)
pub fn code_inline(text: &str) -> Markup {
html! { code.mui-code { (text) } }
}
/// Blockquote (italic, muted, left border)
pub fn blockquote(text: &str) -> Markup {
html! { blockquote.mui-blockquote { (text) } }
}
/// Unordered list (disc markers, 1.5rem indent)
pub fn list_ul(items: Vec<Markup>) -> Markup {
html! {
ul.mui-typography-list."mui-typography-list--ul" {
@for item in &items {
li { (item) }
}
}
}
}
/// Ordered list (decimal markers, 1.5rem indent)
pub fn list_ol(items: Vec<Markup>) -> Markup {
html! {
ol.mui-typography-list."mui-typography-list--ol" {
@for item in &items {
li { (item) }
}
}
}
}
/// Large text (1.125rem, semibold) — shadcn `<div class="text-lg font-semibold">` equivalent
pub fn large(text: &str) -> Markup {
html! { div.mui-typography-large { (text) } }
}
/// Small text (0.75rem, medium) — shadcn `<small>` equivalent
pub fn small(text: &str) -> Markup {
html! { small.mui-typography-small { (text) } }
}
/// Table wrapper (horizontal scroll for narrow viewports) — wrap a `<table>` in this
pub fn table(children: Markup) -> Markup {
html! {
div.mui-typography-table-wrapper { (children) }
}
}
/// Showcase all typography elements
pub fn showcase() -> Markup {
html! {
div.mui-showcase__grid {
div {
p.mui-showcase__caption { "Headings" }
div.mui-showcase__column style="gap:0.5rem" {
(h1("The quick brown fox"))
(h2("The quick brown fox"))
(h3("The quick brown fox"))
(h4("The quick brown fox"))
}
}
div {
p.mui-showcase__caption { "Body text" }
div.mui-showcase__column style="gap:0.75rem" {
(lead("A lead paragraph is great for intros. It's visually larger and lighter than body text, drawing the eye without shouting."))
(p("Regular paragraph text. This is the standard body copy size used throughout the interface for readable content at comfortable line lengths."))
(large("Large text for emphasis or section intros."))
(muted("Muted text for secondary information, timestamps, or helper copy."))
(small("Small text for fine print, captions, or metadata."))
}
}
div {
p.mui-showcase__caption { "Lists" }
div.mui-showcase__column style="gap:0.75rem" {
(list_ul(vec![
html! { "First bullet item" },
html! { "Second bullet item" },
html! { "Third bullet item" },
]))
(list_ol(vec![
html! { "Step one" },
html! { "Step two" },
html! { "Step three" },
]))
}
}
div {
p.mui-showcase__caption { "Code" }
div.mui-showcase__column style="gap:0.75rem" {
p.mui-p {
"Install dependencies with " (code_inline("bun install")) " then run " (code_inline("bun dev")) " to start."
}
}
}
div {
p.mui-showcase__caption { "Blockquote" }
(blockquote("Design is not just what it looks like and feels like. Design is how it works."))
}
div {
p.mui-showcase__caption { "Table" }
(table(html! {
table style="border-collapse:collapse;width:100%" {
thead {
tr {
th style="text-align:left;padding:0.5rem;border-bottom:1px solid var(--mui-border)" { "Name" }
th style="text-align:left;padding:0.5rem;border-bottom:1px solid var(--mui-border)" { "Role" }
th style="text-align:left;padding:0.5rem;border-bottom:1px solid var(--mui-border)" { "Status" }
}
}
tbody {
tr {
td style="padding:0.5rem" { "Ada Lovelace" }
td style="padding:0.5rem" { "Mathematician" }
td style="padding:0.5rem" { "Active" }
}
tr {
td style="padding:0.5rem" { "Alan Turing" }
td style="padding:0.5rem" { "Cryptanalyst" }
td style="padding:0.5rem" { "Active" }
}
}
}
}))
}
}
}
}