pub fn button(label: impl Into<String>) -> ElExamples found in repository?
examples/custom_shader.rs (line 23)
22fn gradient_button(label: &str, top: Color, bottom: Color, radius: f32) -> El {
23 button(label).text_color(tokens::PRIMARY_FOREGROUND).shader(
24 ShaderBinding::custom("gradient")
25 .color("vec_a", top)
26 .color("vec_b", bottom)
27 .f32("vec_c", radius),
28 )
29}
30
31fn fixture() -> El {
32 column([
33 h1("Custom shader demo"),
34 paragraph(
35 "Three buttons below paint via a registered custom shader \
36 (gradient.wgsl). The right-hand button is a stock rounded_rect \
37 for contrast.",
38 )
39 .muted(),
40 titled_card(
41 "gradient.wgsl — vertical linear gradient",
42 [row([
43 gradient_button(
44 "Sunrise",
45 Color::rgb(255, 200, 90),
46 Color::rgb(245, 95, 110),
47 tokens::RADIUS_MD,
48 ),
49 gradient_button(
50 "Ocean",
51 Color::rgb(120, 200, 255),
52 Color::rgb(40, 90, 200),
53 tokens::RADIUS_MD,
54 ),
55 gradient_button(
56 "Forest",
57 Color::rgb(180, 230, 140),
58 Color::rgb(40, 110, 80),
59 tokens::RADIUS_MD,
60 ),
61 spacer(),
62 button("Stock").secondary(),
63 ])
64 .gap(tokens::SPACE_3)],
65 ),
66 ])
67 .gap(tokens::SPACE_4)
68 .padding(tokens::SPACE_7)
69}More examples
examples/settings_calibration.rs (line 103)
97fn settings_header() -> El {
98 row([
99 icon_button("menu").ghost(),
100 divider().width(Size::Fixed(1.0)).height(Size::Fixed(22.0)),
101 h3("Settings").key("metric:page.title"),
102 spacer(),
103 button("Reset").secondary(),
104 button("Save changes").primary(),
105 ])
106 .key("metric:header")
107 .gap(tokens::SPACE_3)
108 .height(Size::Fixed(56.0))
109 .padding(Sides::xy(tokens::SPACE_4, 0.0))
110 .align(Align::Center)
111 .stroke(tokens::BORDER)
112}
113
114fn settings_nav_card() -> El {
115 column([
116 settings_nav_item("Account", true),
117 settings_nav_item("Security", false),
118 settings_nav_item("Notifications", false),
119 settings_nav_item("Appearance", false),
120 settings_nav_item("Billing", false),
121 ])
122 .gap(tokens::SPACE_1)
123 .padding(tokens::SPACE_1)
124 .width(Size::Fixed(220.0))
125 .height(Size::Fill(1.0))
126 .style_profile(StyleProfile::Surface)
127 .surface_role(SurfaceRole::Panel)
128 .fill(tokens::CARD)
129 .stroke(tokens::BORDER)
130 .radius(tokens::RADIUS_MD)
131 .shadow(tokens::SHADOW_MD)
132}
133
134fn settings_nav_item(label: &'static str, selected: bool) -> El {
135 let mut item = row([
136 El::new(Kind::Custom("nav-dot"))
137 .fill(tokens::MUTED_FOREGROUND)
138 .radius(tokens::RADIUS_PILL)
139 .width(Size::Fixed(6.0))
140 .height(Size::Fixed(6.0)),
141 text(label)
142 .font_weight(FontWeight::Medium)
143 .ellipsis()
144 .width(Size::Fill(1.0)),
145 ])
146 .key(if selected {
147 "metric:settings.nav.row".to_string()
148 } else {
149 format!("settings-nav-{label}")
150 })
151 .metrics_role(MetricsRole::ListItem)
152 .align(Align::Center)
153 .focusable();
154
155 if selected {
156 item = item.current();
157 } else {
158 item = item.color(tokens::MUTED_FOREGROUND);
159 }
160
161 item
162}
163
164fn settings_body() -> El {
165 column([
166 column([
167 h1("Account").heading().key("metric:section.title"),
168 text("Manage identity, workspace defaults, and security preferences.")
169 .muted()
170 .wrap_text()
171 .key("metric:page.subtitle"),
172 ])
173 .gap(tokens::SPACE_1)
174 .height(Size::Hug),
175 scroll([profile_card(), preferences_card()])
176 .key("settings-body-scroll")
177 .gap(tokens::SPACE_4)
178 .width(Size::Fill(1.0))
179 .height(Size::Fill(1.0)),
180 ])
181 .gap(tokens::SPACE_4)
182 .width(Size::Fill(1.0))
183 .height(Size::Fill(1.0))
184}
185
186fn profile_card() -> El {
187 card([
188 card_header([
189 card_title("Profile"),
190 card_description("This information appears in audit logs and shared documents."),
191 ]),
192 card_content([form([
193 row([
194 setting_field("Display name", "Alicia Koch", "display-name"),
195 setting_field("Email", "alicia@acme.co", "email"),
196 ])
197 .gap(tokens::SPACE_3),
198 row([
199 setting_select("Role", "Workspace admin", "role"),
200 setting_select("Region", "US East", "region"),
201 ])
202 .gap(tokens::SPACE_3),
203 ])]),
204 ])
205 .key("metric:profile.card")
206}
207
208fn setting_field(label: &'static str, value: &'static str, key: &'static str) -> El {
209 form_item([
210 form_label(label),
211 form_control(
212 text_input(value, &Selection::caret(key, value.len()), key).key(
213 if key == "display-name" {
214 "metric:form.input"
215 } else {
216 key
217 },
218 ),
219 ),
220 ])
221 .width(Size::Fill(1.0))
222}
223
224fn setting_select(label: &'static str, value: &'static str, key: &'static str) -> El {
225 form_item([form_label(label), form_control(select_trigger(key, value))]).width(Size::Fill(1.0))
226}
227
228fn preferences_card() -> El {
229 card([
230 card_header([
231 card_title("Preferences"),
232 card_description("Defaults used when creating new dashboards and exports."),
233 ]),
234 card_content([column([
235 preference_row(
236 "Compact navigation",
237 "Use tighter rows in the sidebar and command menus.",
238 switch(true).key("compact-navigation"),
239 ),
240 divider(),
241 preference_row(
242 "Email summaries",
243 "Send a daily digest when documents change.",
244 switch(false).key("email-summaries"),
245 ),
246 divider(),
247 preference_row(
248 "Require approval",
249 "Route external sharing through an owner review.",
250 checkbox(true).key("approval-required"),
251 ),
252 ])
253 .gap(0.0)
254 .width(Size::Fill(1.0))])
255 .padding(0.0),
256 ])
257 .key("metric:preferences.card")
258}
259
260fn preference_row(title: &'static str, description: &'static str, control: El) -> El {
261 row([
262 column([
263 text(title).semibold().ellipsis().width(Size::Fill(1.0)),
264 text(description)
265 .caption()
266 .ellipsis()
267 .width(Size::Fill(1.0)),
268 ])
269 .gap(2.0)
270 .width(Size::Fill(1.0))
271 .height(Size::Hug),
272 control,
273 ])
274 .key(if title == "Compact navigation" {
275 "metric:preference.row".to_string()
276 } else {
277 format!("preference-{title}")
278 })
279 .metrics_role(MetricsRole::PreferenceRow)
280 .gap(tokens::SPACE_4)
281 .padding(Sides::xy(tokens::SPACE_4, tokens::SPACE_3))
282 .align(Align::Center)
283}
284
285fn settings_aside() -> El {
286 column([security_card(), scale_card()])
287 .gap(tokens::SPACE_4)
288 .width(Size::Fixed(300.0))
289 .height(Size::Fill(1.0))
290}
291
292fn security_card() -> El {
293 card([
294 card_header([
295 card_title("Security"),
296 card_description("Two-factor authentication is enabled for all privileged users."),
297 ]),
298 card_content([
299 compact_stat("Passkeys", "2 registered", badge("On").success()),
300 compact_stat("Sessions", "3 active", button("Review").secondary()),
301 ]),
302 ])
303 .width(Size::Fill(1.0))
304}examples/circular_layout.rs (line 63)
48fn fixture() -> El {
49 let centre = h2("Compass").center_text();
50 let dirs = [
51 ("North", "n"),
52 ("NE", "ne"),
53 ("East", "e"),
54 ("SE", "se"),
55 ("South", "s"),
56 ("SW", "sw"),
57 ("West", "w"),
58 ("NW", "nw"),
59 ];
60
61 let mut children: Vec<El> = vec![centre];
62 for (label, k) in dirs {
63 children.push(button(label).key(k).primary());
64 }
65
66 column([
67 h1("Custom layout — circular"),
68 paragraph(
69 "Eight buttons positioned on a circle by an author-supplied \
70 LayoutFn. Stock paint, automatic hover/press, and hit-test \
71 all keep working — only the rect distribution changed.",
72 )
73 .muted(),
74 stack(children)
75 .key("compass")
76 .layout(circular)
77 .width(Size::Fill(1.0))
78 .height(Size::Fixed(360.0)),
79 ])
80 .gap(tokens::SPACE_4)
81 .padding(tokens::SPACE_7)
82}examples/toast.rs (line 46)
31fn fixture() -> El {
32 // Apps wrap their main view in `overlays(main, [])` so the
33 // runtime can append the synthesized toast layer as an overlay
34 // sibling — same convention as for popovers and modals.
35 overlays(
36 column([
37 h2("Toasts"),
38 paragraph(
39 "Apps queue toasts by returning ToastSpec values from \
40 App::drain_toasts. The runtime stamps each with a TTL, \
41 stacks them at the bottom-right corner, and dismisses \
42 them on click or auto-expiry.",
43 )
44 .muted(),
45 row([
46 button("Save changes").key("save"),
47 button("Trigger error").key("err"),
48 button("Show info").key("info"),
49 ])
50 .gap(tokens::SPACE_2),
51 ])
52 .gap(tokens::SPACE_4)
53 .padding(tokens::SPACE_7)
54 .width(Size::Fill(1.0))
55 .height(Size::Fill(1.0)),
56 [],
57 )
58}examples/polish_calibration.rs (line 344)
317fn form_probe() -> El {
318 form([
319 form_item([
320 form_label("Valid input"),
321 form_control(
322 text_input(
323 "Valid input",
324 &Selection::caret("valid-input", 11),
325 "valid-input",
326 )
327 .key("metric:form.input"),
328 ),
329 form_description("Default field spacing and helper text."),
330 ]),
331 form_item([
332 form_label("Invalid input"),
333 form_control(
334 text_input(
335 "Invalid input",
336 &Selection::caret("invalid-input", 13),
337 "invalid-input",
338 )
339 .invalid(),
340 ),
341 form_message("This field needs attention."),
342 ]),
343 row([
344 button("Disabled").secondary().disabled(),
345 button("Loading").primary().loading(),
346 spacer(),
347 ]),
348 ])
349 .padding(tokens::SPACE_3)
350 .fill(tokens::MUTED)
351 .stroke(tokens::BORDER)
352 .radius(tokens::RADIUS_MD)
353}examples/modal.rs (line 33)
9fn modal_fixture() -> El {
10 stack([
11 column([
12 h1("Account"),
13 titled_card(
14 "Profile",
15 [
16 row([text("Email"), spacer(), text("user@example.com").muted()]),
17 row([text("Plan"), spacer(), badge("Pro").info()]),
18 ],
19 ),
20 titled_card(
21 "Danger zone",
22 [row([
23 column([
24 text("Delete account").bold(),
25 text("Remove this account and all associated data.")
26 .muted()
27 .small(),
28 ])
29 .gap(tokens::SPACE_1)
30 .align(Align::Start)
31 .width(Size::Hug),
32 spacer(),
33 button("Delete").destructive().key("open-delete"),
34 ])],
35 ),
36 ])
37 .gap(tokens::SPACE_4)
38 .padding(tokens::SPACE_7),
39 modal(
40 "delete-account",
41 "Delete account?",
42 [
43 text("Permanent action. Export data first.").muted(),
44 row([
45 spacer(),
46 button("Cancel").ghost().key("cancel-delete"),
47 button("Delete").destructive().key("confirm-delete"),
48 ])
49 .gap(tokens::SPACE_2),
50 ],
51 ),
52 ])
53}Additional examples can be found in: