cronixui 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +71 -71
- package/packages/flutter/.qwen/settings.json +7 -0
- package/packages/flutter/pubspec.yaml +20 -20
- package/packages/go/cronixui/cronixui.go +926 -926
- package/packages/python/README.md +142 -0
- package/packages/python/cronixui/__init__.py +15 -6
- package/packages/python/cronixui/__pycache__/__init__.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/accordion.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/alert.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/avatar.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/badge.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/button.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/card.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/command_palette.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/core.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/dropdown.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/form.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/layout.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/list.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/loading.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/modal.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/nav.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/pagination.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/progress.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/search.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/table.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/tabs.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/toast.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/toggle.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/tokens.cpython-314.pyc +0 -0
- package/packages/python/cronixui/__pycache__/tooltip.cpython-314.pyc +0 -0
- package/packages/python/cronixui/alert.py +119 -36
- package/packages/python/cronixui/avatar.py +129 -22
- package/packages/python/cronixui/badge.py +161 -24
- package/packages/python/cronixui/button.py +96 -27
- package/packages/python/cronixui/card.py +206 -33
- package/packages/python/cronixui/core.py +212 -23
- package/packages/python/cronixui/form.py +552 -141
- package/packages/python/cronixui/layout.py +358 -96
- package/packages/python/cronixui/list.py +140 -37
- package/packages/python/cronixui/loading.py +107 -17
- package/packages/python/cronixui/progress.py +189 -47
- package/packages/python/cronixui/table.py +118 -31
- package/packages/python/cronixui/tooltip.py +117 -15
- package/packages/react/src/components/Accordion.tsx +82 -82
- package/packages/react/src/components/Button.tsx +47 -47
- package/packages/react/src/components/Card.tsx +69 -69
- package/packages/react/src/components/CommandPalette.tsx +131 -131
- package/packages/react/src/components/Dropdown.tsx +88 -88
- package/packages/react/src/components/FileInput.tsx +86 -86
- package/packages/react/src/components/FormGroup.tsx +36 -36
- package/packages/react/src/components/List.tsx +55 -55
- package/packages/react/src/components/Pagination.tsx +107 -107
- package/packages/react/src/components/Progress.tsx +49 -49
- package/packages/react/src/components/Search.tsx +95 -95
- package/packages/react/src/components/Sidebar.tsx +64 -64
- package/packages/react/src/components/Stack.tsx +69 -69
- package/packages/react/src/components/Table.tsx +90 -90
- package/packages/react/src/components/Toast.tsx +134 -134
- package/packages/react/src/components/Typography.tsx +66 -66
- package/packages/react/src/index.ts +40 -40
- package/packages/react/src/styles.css +2039 -2039
- package/packages/rust/cronixui/src/components/avatar.rs +85 -85
- package/packages/rust/cronixui/src/components/breadcrumb.rs +58 -58
- package/packages/rust/cronixui/src/components/card.rs +259 -259
- package/packages/rust/cronixui/src/components/command_palette.rs +254 -254
- package/packages/rust/cronixui/src/components/dropdown.rs +179 -179
- package/packages/rust/cronixui/src/components/file_input.rs +74 -74
- package/packages/rust/cronixui/src/components/mod.rs +51 -51
- package/packages/rust/cronixui/src/components/search.rs +185 -185
- package/packages/rust/cronixui/src/components/skeleton.rs +63 -63
- package/packages/rust/cronixui/src/components/table.rs +56 -56
- package/packages/rust/cronixui/src/lib.rs +128 -128
- package/packages/web/dist/cronixui.css +97 -93
- package/packages/web/dist/cronixui.min.css +1 -1
|
@@ -1,259 +1,259 @@
|
|
|
1
|
-
//! Card component
|
|
2
|
-
|
|
3
|
-
use egui::*;
|
|
4
|
-
use crate::{colors::*, tokens::*};
|
|
5
|
-
|
|
6
|
-
/// Icon component for Card header
|
|
7
|
-
pub struct CardIcon {
|
|
8
|
-
pub icon: String,
|
|
9
|
-
pub size: f32,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
impl CardIcon {
|
|
13
|
-
pub fn new(icon: impl Into<String>) -> Self {
|
|
14
|
-
Self { icon: icon.into(), size: tokens::FONT_SIZE_LG }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
pub fn size(mut self, size: f32) -> Self {
|
|
18
|
-
self.size = size;
|
|
19
|
-
self
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub fn show(&self, ui: &mut Ui) {
|
|
23
|
-
let colors = Colors::default();
|
|
24
|
-
ui.label(
|
|
25
|
-
RichText::new(&self.icon)
|
|
26
|
-
.size(self.size)
|
|
27
|
-
.color(colors.text_muted),
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/// Title component
|
|
33
|
-
pub struct CardTitle {
|
|
34
|
-
pub text: String,
|
|
35
|
-
pub size: f32,
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
impl CardTitle {
|
|
39
|
-
pub fn new(text: impl Into<String>) -> Self {
|
|
40
|
-
Self { text: text.into(), size: tokens::FONT_SIZE_MD }
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
pub fn size(mut self, size: f32) -> Self {
|
|
44
|
-
self.size = size;
|
|
45
|
-
self
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
pub fn show(&self, ui: &mut Ui) {
|
|
49
|
-
let colors = Colors::default();
|
|
50
|
-
ui.label(
|
|
51
|
-
RichText::new(&self.text)
|
|
52
|
-
.size(self.size)
|
|
53
|
-
.color(colors.text)
|
|
54
|
-
.strong(),
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/// Subtitle component
|
|
60
|
-
pub struct CardSubtitle {
|
|
61
|
-
pub text: String,
|
|
62
|
-
pub size: f32,
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
impl CardSubtitle {
|
|
66
|
-
pub fn new(text: impl Into<String>) -> Self {
|
|
67
|
-
Self { text: text.into(), size: tokens::FONT_SIZE_SM }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
pub fn size(mut self, size: f32) -> Self {
|
|
71
|
-
self.size = size;
|
|
72
|
-
self
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
pub fn show(&self, ui: &mut Ui) {
|
|
76
|
-
let colors = Colors::default();
|
|
77
|
-
ui.label(
|
|
78
|
-
RichText::new(&self.text)
|
|
79
|
-
.size(self.size)
|
|
80
|
-
.color(colors.text_muted),
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/// Card header component (combines icon, title, subtitle)
|
|
86
|
-
pub struct CardHeader {
|
|
87
|
-
pub icon: Option<CardIcon>,
|
|
88
|
-
pub title: Option<CardTitle>,
|
|
89
|
-
pub subtitle: Option<CardSubtitle>,
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
impl CardHeader {
|
|
93
|
-
pub fn new() -> Self {
|
|
94
|
-
Self { icon: None, title: None, subtitle: None }
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
pub fn icon(mut self, icon: CardIcon) -> Self {
|
|
98
|
-
self.icon = Some(icon);
|
|
99
|
-
self
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
pub fn title(mut self, title: CardTitle) -> Self {
|
|
103
|
-
self.title = Some(title);
|
|
104
|
-
self
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
pub fn subtitle(mut self, subtitle: CardSubtitle) -> Self {
|
|
108
|
-
self.subtitle = Some(subtitle);
|
|
109
|
-
self
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
pub fn show(&self, ui: &mut Ui) {
|
|
113
|
-
ui.horizontal(|ui| {
|
|
114
|
-
if let Some(icon) = &self.icon {
|
|
115
|
-
icon.show(ui);
|
|
116
|
-
ui.add_space(tokens::SPACE_2);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
ui.vertical(|ui| {
|
|
120
|
-
if let Some(title) = &self.title {
|
|
121
|
-
title.show(ui);
|
|
122
|
-
}
|
|
123
|
-
if let Some(subtitle) = &self.subtitle {
|
|
124
|
-
subtitle.show(ui);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
impl Default for CardHeader {
|
|
132
|
-
fn default() -> Self {
|
|
133
|
-
Self::new()
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/// Card body component
|
|
138
|
-
pub struct CardBody;
|
|
139
|
-
|
|
140
|
-
impl CardBody {
|
|
141
|
-
pub fn new() -> Self {
|
|
142
|
-
Self
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
pub fn show<R>(&self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) {
|
|
146
|
-
add_contents(ui);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
impl Default for CardBody {
|
|
151
|
-
fn default() -> Self {
|
|
152
|
-
Self::new()
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/// Card footer component
|
|
157
|
-
pub struct CardFooter {
|
|
158
|
-
pub separator: bool,
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
impl CardFooter {
|
|
162
|
-
pub fn new() -> Self {
|
|
163
|
-
Self { separator: true }
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
pub fn separator(mut self, separator: bool) -> Self {
|
|
167
|
-
self.separator = separator;
|
|
168
|
-
self
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
pub fn show<R>(&self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) {
|
|
172
|
-
if self.separator {
|
|
173
|
-
ui.separator();
|
|
174
|
-
ui.add_space(tokens::SPACE_2);
|
|
175
|
-
}
|
|
176
|
-
add_contents(ui);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
impl Default for CardFooter {
|
|
181
|
-
fn default() -> Self {
|
|
182
|
-
Self::new()
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/// Main Card component with builder pattern
|
|
187
|
-
pub struct Card {
|
|
188
|
-
pub header: Option<CardHeader>,
|
|
189
|
-
pub clickable: bool,
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
impl Card {
|
|
193
|
-
pub fn new() -> Self {
|
|
194
|
-
Self { header: None, clickable: false }
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
pub fn title(mut self, title: impl Into<String>) -> Self {
|
|
198
|
-
let title_comp = CardTitle::new(title);
|
|
199
|
-
self.header = Some(
|
|
200
|
-
self.header.unwrap_or_else(CardHeader::new).title(title_comp),
|
|
201
|
-
);
|
|
202
|
-
self
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
pub fn subtitle(mut self, subtitle: impl Into<String>) -> Self {
|
|
206
|
-
let subtitle_comp = CardSubtitle::new(subtitle);
|
|
207
|
-
self.header = Some(
|
|
208
|
-
self.header.unwrap_or_else(CardHeader::new).subtitle(subtitle_comp),
|
|
209
|
-
);
|
|
210
|
-
self
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
pub fn icon(mut self, icon: impl Into<String>) -> Self {
|
|
214
|
-
let icon_comp = CardIcon::new(icon);
|
|
215
|
-
self.header = Some(
|
|
216
|
-
self.header.unwrap_or_else(CardHeader::new).icon(icon_comp),
|
|
217
|
-
);
|
|
218
|
-
self
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
pub fn header(mut self, header: CardHeader) -> Self {
|
|
222
|
-
self.header = Some(header);
|
|
223
|
-
self
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
pub fn clickable(mut self, clickable: bool) -> Self {
|
|
227
|
-
self.clickable = clickable;
|
|
228
|
-
self
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
pub fn show<R>(&self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Response {
|
|
232
|
-
let colors = Colors::default();
|
|
233
|
-
|
|
234
|
-
let frame = egui::Frame::none()
|
|
235
|
-
.fill(colors.surface)
|
|
236
|
-
.stroke(Stroke::new(1.0, colors.border))
|
|
237
|
-
.rounding(Rounding::same(RADIUS_LG))
|
|
238
|
-
.inner_margin(SPACE_5);
|
|
239
|
-
|
|
240
|
-
let inner_response = frame.show(ui, |ui| {
|
|
241
|
-
// Render header if present
|
|
242
|
-
if let Some(header) = &self.header {
|
|
243
|
-
header.show(ui);
|
|
244
|
-
ui.add_space(SPACE_4);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Render body
|
|
248
|
-
add_contents(ui)
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
inner_response.response
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
impl Default for Card {
|
|
256
|
-
fn default() -> Self {
|
|
257
|
-
Self::new()
|
|
258
|
-
}
|
|
259
|
-
}
|
|
1
|
+
//! Card component
|
|
2
|
+
|
|
3
|
+
use egui::*;
|
|
4
|
+
use crate::{colors::*, tokens::*};
|
|
5
|
+
|
|
6
|
+
/// Icon component for Card header
|
|
7
|
+
pub struct CardIcon {
|
|
8
|
+
pub icon: String,
|
|
9
|
+
pub size: f32,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
impl CardIcon {
|
|
13
|
+
pub fn new(icon: impl Into<String>) -> Self {
|
|
14
|
+
Self { icon: icon.into(), size: tokens::FONT_SIZE_LG }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
pub fn size(mut self, size: f32) -> Self {
|
|
18
|
+
self.size = size;
|
|
19
|
+
self
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub fn show(&self, ui: &mut Ui) {
|
|
23
|
+
let colors = Colors::default();
|
|
24
|
+
ui.label(
|
|
25
|
+
RichText::new(&self.icon)
|
|
26
|
+
.size(self.size)
|
|
27
|
+
.color(colors.text_muted),
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Title component
|
|
33
|
+
pub struct CardTitle {
|
|
34
|
+
pub text: String,
|
|
35
|
+
pub size: f32,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
impl CardTitle {
|
|
39
|
+
pub fn new(text: impl Into<String>) -> Self {
|
|
40
|
+
Self { text: text.into(), size: tokens::FONT_SIZE_MD }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
pub fn size(mut self, size: f32) -> Self {
|
|
44
|
+
self.size = size;
|
|
45
|
+
self
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
pub fn show(&self, ui: &mut Ui) {
|
|
49
|
+
let colors = Colors::default();
|
|
50
|
+
ui.label(
|
|
51
|
+
RichText::new(&self.text)
|
|
52
|
+
.size(self.size)
|
|
53
|
+
.color(colors.text)
|
|
54
|
+
.strong(),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// Subtitle component
|
|
60
|
+
pub struct CardSubtitle {
|
|
61
|
+
pub text: String,
|
|
62
|
+
pub size: f32,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
impl CardSubtitle {
|
|
66
|
+
pub fn new(text: impl Into<String>) -> Self {
|
|
67
|
+
Self { text: text.into(), size: tokens::FONT_SIZE_SM }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
pub fn size(mut self, size: f32) -> Self {
|
|
71
|
+
self.size = size;
|
|
72
|
+
self
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
pub fn show(&self, ui: &mut Ui) {
|
|
76
|
+
let colors = Colors::default();
|
|
77
|
+
ui.label(
|
|
78
|
+
RichText::new(&self.text)
|
|
79
|
+
.size(self.size)
|
|
80
|
+
.color(colors.text_muted),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/// Card header component (combines icon, title, subtitle)
|
|
86
|
+
pub struct CardHeader {
|
|
87
|
+
pub icon: Option<CardIcon>,
|
|
88
|
+
pub title: Option<CardTitle>,
|
|
89
|
+
pub subtitle: Option<CardSubtitle>,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
impl CardHeader {
|
|
93
|
+
pub fn new() -> Self {
|
|
94
|
+
Self { icon: None, title: None, subtitle: None }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
pub fn icon(mut self, icon: CardIcon) -> Self {
|
|
98
|
+
self.icon = Some(icon);
|
|
99
|
+
self
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
pub fn title(mut self, title: CardTitle) -> Self {
|
|
103
|
+
self.title = Some(title);
|
|
104
|
+
self
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
pub fn subtitle(mut self, subtitle: CardSubtitle) -> Self {
|
|
108
|
+
self.subtitle = Some(subtitle);
|
|
109
|
+
self
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
pub fn show(&self, ui: &mut Ui) {
|
|
113
|
+
ui.horizontal(|ui| {
|
|
114
|
+
if let Some(icon) = &self.icon {
|
|
115
|
+
icon.show(ui);
|
|
116
|
+
ui.add_space(tokens::SPACE_2);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
ui.vertical(|ui| {
|
|
120
|
+
if let Some(title) = &self.title {
|
|
121
|
+
title.show(ui);
|
|
122
|
+
}
|
|
123
|
+
if let Some(subtitle) = &self.subtitle {
|
|
124
|
+
subtitle.show(ui);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
impl Default for CardHeader {
|
|
132
|
+
fn default() -> Self {
|
|
133
|
+
Self::new()
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/// Card body component
|
|
138
|
+
pub struct CardBody;
|
|
139
|
+
|
|
140
|
+
impl CardBody {
|
|
141
|
+
pub fn new() -> Self {
|
|
142
|
+
Self
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
pub fn show<R>(&self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) {
|
|
146
|
+
add_contents(ui);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
impl Default for CardBody {
|
|
151
|
+
fn default() -> Self {
|
|
152
|
+
Self::new()
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/// Card footer component
|
|
157
|
+
pub struct CardFooter {
|
|
158
|
+
pub separator: bool,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
impl CardFooter {
|
|
162
|
+
pub fn new() -> Self {
|
|
163
|
+
Self { separator: true }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
pub fn separator(mut self, separator: bool) -> Self {
|
|
167
|
+
self.separator = separator;
|
|
168
|
+
self
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
pub fn show<R>(&self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) {
|
|
172
|
+
if self.separator {
|
|
173
|
+
ui.separator();
|
|
174
|
+
ui.add_space(tokens::SPACE_2);
|
|
175
|
+
}
|
|
176
|
+
add_contents(ui);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
impl Default for CardFooter {
|
|
181
|
+
fn default() -> Self {
|
|
182
|
+
Self::new()
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/// Main Card component with builder pattern
|
|
187
|
+
pub struct Card {
|
|
188
|
+
pub header: Option<CardHeader>,
|
|
189
|
+
pub clickable: bool,
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
impl Card {
|
|
193
|
+
pub fn new() -> Self {
|
|
194
|
+
Self { header: None, clickable: false }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
pub fn title(mut self, title: impl Into<String>) -> Self {
|
|
198
|
+
let title_comp = CardTitle::new(title);
|
|
199
|
+
self.header = Some(
|
|
200
|
+
self.header.unwrap_or_else(CardHeader::new).title(title_comp),
|
|
201
|
+
);
|
|
202
|
+
self
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
pub fn subtitle(mut self, subtitle: impl Into<String>) -> Self {
|
|
206
|
+
let subtitle_comp = CardSubtitle::new(subtitle);
|
|
207
|
+
self.header = Some(
|
|
208
|
+
self.header.unwrap_or_else(CardHeader::new).subtitle(subtitle_comp),
|
|
209
|
+
);
|
|
210
|
+
self
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
pub fn icon(mut self, icon: impl Into<String>) -> Self {
|
|
214
|
+
let icon_comp = CardIcon::new(icon);
|
|
215
|
+
self.header = Some(
|
|
216
|
+
self.header.unwrap_or_else(CardHeader::new).icon(icon_comp),
|
|
217
|
+
);
|
|
218
|
+
self
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
pub fn header(mut self, header: CardHeader) -> Self {
|
|
222
|
+
self.header = Some(header);
|
|
223
|
+
self
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
pub fn clickable(mut self, clickable: bool) -> Self {
|
|
227
|
+
self.clickable = clickable;
|
|
228
|
+
self
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
pub fn show<R>(&self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Response {
|
|
232
|
+
let colors = Colors::default();
|
|
233
|
+
|
|
234
|
+
let frame = egui::Frame::none()
|
|
235
|
+
.fill(colors.surface)
|
|
236
|
+
.stroke(Stroke::new(1.0, colors.border))
|
|
237
|
+
.rounding(Rounding::same(RADIUS_LG))
|
|
238
|
+
.inner_margin(SPACE_5);
|
|
239
|
+
|
|
240
|
+
let inner_response = frame.show(ui, |ui| {
|
|
241
|
+
// Render header if present
|
|
242
|
+
if let Some(header) = &self.header {
|
|
243
|
+
header.show(ui);
|
|
244
|
+
ui.add_space(SPACE_4);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Render body
|
|
248
|
+
add_contents(ui)
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
inner_response.response
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
impl Default for Card {
|
|
256
|
+
fn default() -> Self {
|
|
257
|
+
Self::new()
|
|
258
|
+
}
|
|
259
|
+
}
|