cronixui 1.1.1 → 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 +12 -8
- 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,179 +1,179 @@
|
|
|
1
|
-
//! Dropdown component
|
|
2
|
-
|
|
3
|
-
use egui::*;
|
|
4
|
-
use crate::{colors::*, tokens::*};
|
|
5
|
-
|
|
6
|
-
/// Dropdown component with full rendering
|
|
7
|
-
pub struct Dropdown {
|
|
8
|
-
pub items: Vec<String>,
|
|
9
|
-
pub selected: Option<usize>,
|
|
10
|
-
pub open: bool,
|
|
11
|
-
id: Id,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
impl Dropdown {
|
|
15
|
-
pub fn new(id: impl Into<Id>, items: impl IntoIterator<Item = impl Into<String>>) -> Self {
|
|
16
|
-
Self {
|
|
17
|
-
id: id.into(),
|
|
18
|
-
items: items.into_iter().map(|s| s.into()).collect(),
|
|
19
|
-
selected: None,
|
|
20
|
-
open: false,
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
pub fn selected(mut self, index: usize) -> Self {
|
|
25
|
-
if index < self.items.len() {
|
|
26
|
-
self.selected = Some(index);
|
|
27
|
-
}
|
|
28
|
-
self
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
pub fn select(&mut self, index: usize) {
|
|
32
|
-
if index < self.items.len() {
|
|
33
|
-
self.selected = Some(index);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
pub fn toggle(&mut self) {
|
|
38
|
-
self.open = !self.open;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
pub fn close(&mut self) {
|
|
42
|
-
self.open = false;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
pub fn selected_text(&self) -> Option<&str> {
|
|
46
|
-
self.selected.map(|i| self.items[i].as_str())
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/// Render the dropdown trigger button and popup.
|
|
50
|
-
/// Returns Some(index) when an item is selected.
|
|
51
|
-
pub fn show(&mut self, ui: &mut Ui) -> Option<usize> {
|
|
52
|
-
let colors = Colors::default();
|
|
53
|
-
let label = self.selected_text().unwrap_or("Select an option...");
|
|
54
|
-
|
|
55
|
-
let response = ui.add_sized(
|
|
56
|
-
[ui.available_width(), 28.0],
|
|
57
|
-
egui::Button::new(label)
|
|
58
|
-
.fill(colors.surface_2)
|
|
59
|
-
.stroke(egui::Stroke::new(1.0, colors.border))
|
|
60
|
-
.rounding(Rounding::same(tokens::RADIUS)),
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
if response.clicked() {
|
|
64
|
-
self.open = !self.open;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Sync open state with egui memory
|
|
68
|
-
if self.open {
|
|
69
|
-
ui.memory_mut(|mem| mem.open_popup(self.id));
|
|
70
|
-
} else {
|
|
71
|
-
ui.memory_mut(|mem| mem.close_popup());
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if !self.open {
|
|
75
|
-
return None;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
let items = &self.items;
|
|
79
|
-
let selected = self.selected;
|
|
80
|
-
let popup_id = self.id;
|
|
81
|
-
|
|
82
|
-
egui::popup::popup_below_widget(ui, popup_id, &response, |ui| {
|
|
83
|
-
// popup_below_widget already wraps in Frame::popup
|
|
84
|
-
// Customize the style colors for our theme
|
|
85
|
-
for (i, item) in items.iter().enumerate() {
|
|
86
|
-
let is_selected = selected == Some(i);
|
|
87
|
-
let text = if is_selected {
|
|
88
|
-
format!("✓ {}", item)
|
|
89
|
-
} else {
|
|
90
|
-
item.clone()
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
if ui.selectable_label(is_selected, text).clicked() {
|
|
94
|
-
ui.memory_mut(|m| {
|
|
95
|
-
m.data.insert_temp(popup_id.with("chosen"), Some(i));
|
|
96
|
-
m.close_popup();
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Check if popup is still open
|
|
103
|
-
let still_open = ui.memory(|mem| mem.is_popup_open(popup_id));
|
|
104
|
-
if !still_open {
|
|
105
|
-
self.open = false;
|
|
106
|
-
let chosen = ui.memory_mut(|m| m.data.get_temp::<usize>(popup_id.with("chosen")));
|
|
107
|
-
if let Some(idx) = chosen {
|
|
108
|
-
self.selected = Some(idx);
|
|
109
|
-
ui.memory_mut(|m| m.data.remove::<usize>(popup_id.with("chosen")));
|
|
110
|
-
return Some(idx);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Also check result for chosen item stored in memory
|
|
115
|
-
let chosen = ui.memory_mut(|m| m.data.get_temp::<usize>(popup_id.with("chosen")));
|
|
116
|
-
if let Some(idx) = chosen {
|
|
117
|
-
self.selected = Some(idx);
|
|
118
|
-
self.open = false;
|
|
119
|
-
ui.memory_mut(|m| m.data.remove::<usize>(popup_id.with("chosen")));
|
|
120
|
-
return Some(idx);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
None
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/// Functional dropdown helper
|
|
128
|
-
pub fn dropdown(ui: &mut Ui, id: impl Into<Id>, items: &[String], selected: &mut Option<usize>) {
|
|
129
|
-
let colors = Colors::default();
|
|
130
|
-
let popup_id = id.into();
|
|
131
|
-
|
|
132
|
-
let label = selected
|
|
133
|
-
.and_then(|i| items.get(i))
|
|
134
|
-
.map(|s| s.as_str())
|
|
135
|
-
.unwrap_or("Select an option...");
|
|
136
|
-
|
|
137
|
-
let response = ui.add_sized(
|
|
138
|
-
[ui.available_width(), 28.0],
|
|
139
|
-
egui::Button::new(label)
|
|
140
|
-
.fill(colors.surface_2)
|
|
141
|
-
.stroke(egui::Stroke::new(1.0, colors.border))
|
|
142
|
-
.rounding(Rounding::same(tokens::RADIUS)),
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
if response.clicked() {
|
|
146
|
-
ui.memory_mut(|mem| {
|
|
147
|
-
if mem.is_popup_open(popup_id) {
|
|
148
|
-
mem.close_popup();
|
|
149
|
-
} else {
|
|
150
|
-
mem.open_popup(popup_id);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
let is_open = ui.memory(|mem| mem.is_popup_open(popup_id));
|
|
156
|
-
|
|
157
|
-
if is_open {
|
|
158
|
-
let current_selected = *selected;
|
|
159
|
-
egui::popup::popup_below_widget(ui, popup_id, &response, |ui| {
|
|
160
|
-
for (i, item) in items.iter().enumerate() {
|
|
161
|
-
let is_sel = current_selected == Some(i);
|
|
162
|
-
let text = if is_sel { format!("✓ {}", item) } else { item.clone() };
|
|
163
|
-
if ui.selectable_label(is_sel, text).clicked() {
|
|
164
|
-
ui.memory_mut(|m| {
|
|
165
|
-
m.data.insert_temp(popup_id.with("result"), i);
|
|
166
|
-
m.close_popup();
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// Check result
|
|
173
|
-
let result = ui.memory_mut(|m| m.data.get_temp::<usize>(popup_id.with("result")));
|
|
174
|
-
if let Some(idx) = result {
|
|
175
|
-
*selected = Some(idx);
|
|
176
|
-
ui.memory_mut(|m| m.data.remove::<usize>(popup_id.with("result")));
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
1
|
+
//! Dropdown component
|
|
2
|
+
|
|
3
|
+
use egui::*;
|
|
4
|
+
use crate::{colors::*, tokens::*};
|
|
5
|
+
|
|
6
|
+
/// Dropdown component with full rendering
|
|
7
|
+
pub struct Dropdown {
|
|
8
|
+
pub items: Vec<String>,
|
|
9
|
+
pub selected: Option<usize>,
|
|
10
|
+
pub open: bool,
|
|
11
|
+
id: Id,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
impl Dropdown {
|
|
15
|
+
pub fn new(id: impl Into<Id>, items: impl IntoIterator<Item = impl Into<String>>) -> Self {
|
|
16
|
+
Self {
|
|
17
|
+
id: id.into(),
|
|
18
|
+
items: items.into_iter().map(|s| s.into()).collect(),
|
|
19
|
+
selected: None,
|
|
20
|
+
open: false,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pub fn selected(mut self, index: usize) -> Self {
|
|
25
|
+
if index < self.items.len() {
|
|
26
|
+
self.selected = Some(index);
|
|
27
|
+
}
|
|
28
|
+
self
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
pub fn select(&mut self, index: usize) {
|
|
32
|
+
if index < self.items.len() {
|
|
33
|
+
self.selected = Some(index);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
pub fn toggle(&mut self) {
|
|
38
|
+
self.open = !self.open;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
pub fn close(&mut self) {
|
|
42
|
+
self.open = false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pub fn selected_text(&self) -> Option<&str> {
|
|
46
|
+
self.selected.map(|i| self.items[i].as_str())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Render the dropdown trigger button and popup.
|
|
50
|
+
/// Returns Some(index) when an item is selected.
|
|
51
|
+
pub fn show(&mut self, ui: &mut Ui) -> Option<usize> {
|
|
52
|
+
let colors = Colors::default();
|
|
53
|
+
let label = self.selected_text().unwrap_or("Select an option...");
|
|
54
|
+
|
|
55
|
+
let response = ui.add_sized(
|
|
56
|
+
[ui.available_width(), 28.0],
|
|
57
|
+
egui::Button::new(label)
|
|
58
|
+
.fill(colors.surface_2)
|
|
59
|
+
.stroke(egui::Stroke::new(1.0, colors.border))
|
|
60
|
+
.rounding(Rounding::same(tokens::RADIUS)),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
if response.clicked() {
|
|
64
|
+
self.open = !self.open;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Sync open state with egui memory
|
|
68
|
+
if self.open {
|
|
69
|
+
ui.memory_mut(|mem| mem.open_popup(self.id));
|
|
70
|
+
} else {
|
|
71
|
+
ui.memory_mut(|mem| mem.close_popup());
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if !self.open {
|
|
75
|
+
return None;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let items = &self.items;
|
|
79
|
+
let selected = self.selected;
|
|
80
|
+
let popup_id = self.id;
|
|
81
|
+
|
|
82
|
+
egui::popup::popup_below_widget(ui, popup_id, &response, |ui| {
|
|
83
|
+
// popup_below_widget already wraps in Frame::popup
|
|
84
|
+
// Customize the style colors for our theme
|
|
85
|
+
for (i, item) in items.iter().enumerate() {
|
|
86
|
+
let is_selected = selected == Some(i);
|
|
87
|
+
let text = if is_selected {
|
|
88
|
+
format!("✓ {}", item)
|
|
89
|
+
} else {
|
|
90
|
+
item.clone()
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
if ui.selectable_label(is_selected, text).clicked() {
|
|
94
|
+
ui.memory_mut(|m| {
|
|
95
|
+
m.data.insert_temp(popup_id.with("chosen"), Some(i));
|
|
96
|
+
m.close_popup();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Check if popup is still open
|
|
103
|
+
let still_open = ui.memory(|mem| mem.is_popup_open(popup_id));
|
|
104
|
+
if !still_open {
|
|
105
|
+
self.open = false;
|
|
106
|
+
let chosen = ui.memory_mut(|m| m.data.get_temp::<usize>(popup_id.with("chosen")));
|
|
107
|
+
if let Some(idx) = chosen {
|
|
108
|
+
self.selected = Some(idx);
|
|
109
|
+
ui.memory_mut(|m| m.data.remove::<usize>(popup_id.with("chosen")));
|
|
110
|
+
return Some(idx);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Also check result for chosen item stored in memory
|
|
115
|
+
let chosen = ui.memory_mut(|m| m.data.get_temp::<usize>(popup_id.with("chosen")));
|
|
116
|
+
if let Some(idx) = chosen {
|
|
117
|
+
self.selected = Some(idx);
|
|
118
|
+
self.open = false;
|
|
119
|
+
ui.memory_mut(|m| m.data.remove::<usize>(popup_id.with("chosen")));
|
|
120
|
+
return Some(idx);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
None
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// Functional dropdown helper
|
|
128
|
+
pub fn dropdown(ui: &mut Ui, id: impl Into<Id>, items: &[String], selected: &mut Option<usize>) {
|
|
129
|
+
let colors = Colors::default();
|
|
130
|
+
let popup_id = id.into();
|
|
131
|
+
|
|
132
|
+
let label = selected
|
|
133
|
+
.and_then(|i| items.get(i))
|
|
134
|
+
.map(|s| s.as_str())
|
|
135
|
+
.unwrap_or("Select an option...");
|
|
136
|
+
|
|
137
|
+
let response = ui.add_sized(
|
|
138
|
+
[ui.available_width(), 28.0],
|
|
139
|
+
egui::Button::new(label)
|
|
140
|
+
.fill(colors.surface_2)
|
|
141
|
+
.stroke(egui::Stroke::new(1.0, colors.border))
|
|
142
|
+
.rounding(Rounding::same(tokens::RADIUS)),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
if response.clicked() {
|
|
146
|
+
ui.memory_mut(|mem| {
|
|
147
|
+
if mem.is_popup_open(popup_id) {
|
|
148
|
+
mem.close_popup();
|
|
149
|
+
} else {
|
|
150
|
+
mem.open_popup(popup_id);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let is_open = ui.memory(|mem| mem.is_popup_open(popup_id));
|
|
156
|
+
|
|
157
|
+
if is_open {
|
|
158
|
+
let current_selected = *selected;
|
|
159
|
+
egui::popup::popup_below_widget(ui, popup_id, &response, |ui| {
|
|
160
|
+
for (i, item) in items.iter().enumerate() {
|
|
161
|
+
let is_sel = current_selected == Some(i);
|
|
162
|
+
let text = if is_sel { format!("✓ {}", item) } else { item.clone() };
|
|
163
|
+
if ui.selectable_label(is_sel, text).clicked() {
|
|
164
|
+
ui.memory_mut(|m| {
|
|
165
|
+
m.data.insert_temp(popup_id.with("result"), i);
|
|
166
|
+
m.close_popup();
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Check result
|
|
173
|
+
let result = ui.memory_mut(|m| m.data.get_temp::<usize>(popup_id.with("result")));
|
|
174
|
+
if let Some(idx) = result {
|
|
175
|
+
*selected = Some(idx);
|
|
176
|
+
ui.memory_mut(|m| m.data.remove::<usize>(popup_id.with("result")));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
//! File input component
|
|
2
|
-
|
|
3
|
-
use egui::*;
|
|
4
|
-
use crate::{colors::*, tokens::*};
|
|
5
|
-
|
|
6
|
-
pub struct FileInput {
|
|
7
|
-
pub accept: String,
|
|
8
|
-
pub multiple: bool,
|
|
9
|
-
pub files: Vec<String>,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
impl FileInput {
|
|
13
|
-
pub fn new() -> Self {
|
|
14
|
-
Self { accept: String::new(), multiple: false, files: Vec::new() }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
pub fn accept(mut self, accept: impl Into<String>) -> Self {
|
|
18
|
-
self.accept = accept.into();
|
|
19
|
-
self
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub fn multiple(mut self) -> Self {
|
|
23
|
-
self.multiple = true;
|
|
24
|
-
self
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
pub fn show(&mut self, ui: &mut Ui) -> Response {
|
|
28
|
-
let colors = Colors::default();
|
|
29
|
-
|
|
30
|
-
egui::Frame::none()
|
|
31
|
-
.fill(colors.surface)
|
|
32
|
-
.stroke(egui::Stroke::new(1.0, colors.border))
|
|
33
|
-
.rounding(Rounding::same(tokens::RADIUS))
|
|
34
|
-
.inner_margin(tokens::SPACE_4)
|
|
35
|
-
.show(ui, |ui| {
|
|
36
|
-
ui.vertical(|ui| {
|
|
37
|
-
ui.label(
|
|
38
|
-
RichText::new("📁 Drop files here or click to browse")
|
|
39
|
-
.size(tokens::FONT_SIZE_BASE)
|
|
40
|
-
.color(colors.text_muted),
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
if ui.button_primary("Browse files").clicked() {
|
|
44
|
-
// Note: actual file selection requires platform-specific code
|
|
45
|
-
// This is a UI placeholder
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if !self.files.is_empty() {
|
|
49
|
-
ui.add_space(tokens::SPACE_2);
|
|
50
|
-
ui.separator();
|
|
51
|
-
ui.add_space(tokens::SPACE_2);
|
|
52
|
-
|
|
53
|
-
for file in &self.files {
|
|
54
|
-
ui.horizontal(|ui| {
|
|
55
|
-
ui.label("📄");
|
|
56
|
-
ui.label(
|
|
57
|
-
RichText::new(file)
|
|
58
|
-
.size(tokens::FONT_SIZE_SM)
|
|
59
|
-
.color(colors.text),
|
|
60
|
-
);
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
})
|
|
66
|
-
.response
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
impl Default for FileInput {
|
|
71
|
-
fn default() -> Self {
|
|
72
|
-
Self::new()
|
|
73
|
-
}
|
|
74
|
-
}
|
|
1
|
+
//! File input component
|
|
2
|
+
|
|
3
|
+
use egui::*;
|
|
4
|
+
use crate::{colors::*, tokens::*};
|
|
5
|
+
|
|
6
|
+
pub struct FileInput {
|
|
7
|
+
pub accept: String,
|
|
8
|
+
pub multiple: bool,
|
|
9
|
+
pub files: Vec<String>,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
impl FileInput {
|
|
13
|
+
pub fn new() -> Self {
|
|
14
|
+
Self { accept: String::new(), multiple: false, files: Vec::new() }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
pub fn accept(mut self, accept: impl Into<String>) -> Self {
|
|
18
|
+
self.accept = accept.into();
|
|
19
|
+
self
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub fn multiple(mut self) -> Self {
|
|
23
|
+
self.multiple = true;
|
|
24
|
+
self
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pub fn show(&mut self, ui: &mut Ui) -> Response {
|
|
28
|
+
let colors = Colors::default();
|
|
29
|
+
|
|
30
|
+
egui::Frame::none()
|
|
31
|
+
.fill(colors.surface)
|
|
32
|
+
.stroke(egui::Stroke::new(1.0, colors.border))
|
|
33
|
+
.rounding(Rounding::same(tokens::RADIUS))
|
|
34
|
+
.inner_margin(tokens::SPACE_4)
|
|
35
|
+
.show(ui, |ui| {
|
|
36
|
+
ui.vertical(|ui| {
|
|
37
|
+
ui.label(
|
|
38
|
+
RichText::new("📁 Drop files here or click to browse")
|
|
39
|
+
.size(tokens::FONT_SIZE_BASE)
|
|
40
|
+
.color(colors.text_muted),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if ui.button_primary("Browse files").clicked() {
|
|
44
|
+
// Note: actual file selection requires platform-specific code
|
|
45
|
+
// This is a UI placeholder
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if !self.files.is_empty() {
|
|
49
|
+
ui.add_space(tokens::SPACE_2);
|
|
50
|
+
ui.separator();
|
|
51
|
+
ui.add_space(tokens::SPACE_2);
|
|
52
|
+
|
|
53
|
+
for file in &self.files {
|
|
54
|
+
ui.horizontal(|ui| {
|
|
55
|
+
ui.label("📄");
|
|
56
|
+
ui.label(
|
|
57
|
+
RichText::new(file)
|
|
58
|
+
.size(tokens::FONT_SIZE_SM)
|
|
59
|
+
.color(colors.text),
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
})
|
|
66
|
+
.response
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
impl Default for FileInput {
|
|
71
|
+
fn default() -> Self {
|
|
72
|
+
Self::new()
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
//! CronixUI Components for egui
|
|
2
|
-
|
|
3
|
-
pub mod button;
|
|
4
|
-
pub mod card;
|
|
5
|
-
pub mod input;
|
|
6
|
-
pub mod toggle;
|
|
7
|
-
pub mod modal;
|
|
8
|
-
pub mod tabs;
|
|
9
|
-
pub mod accordion;
|
|
10
|
-
pub mod toast;
|
|
11
|
-
pub mod badge;
|
|
12
|
-
pub mod avatar;
|
|
13
|
-
pub mod progress;
|
|
14
|
-
pub mod spinner;
|
|
15
|
-
pub mod skeleton;
|
|
16
|
-
pub mod table;
|
|
17
|
-
pub mod list;
|
|
18
|
-
pub mod nav;
|
|
19
|
-
pub mod breadcrumb;
|
|
20
|
-
pub mod tooltip;
|
|
21
|
-
pub mod dropdown;
|
|
22
|
-
pub mod pagination;
|
|
23
|
-
pub mod file_input;
|
|
24
|
-
pub mod search;
|
|
25
|
-
pub mod command_palette;
|
|
26
|
-
pub mod alert;
|
|
27
|
-
|
|
28
|
-
pub use button::*;
|
|
29
|
-
pub use card::*;
|
|
30
|
-
pub use input::*;
|
|
31
|
-
pub use toggle::*;
|
|
32
|
-
pub use modal::*;
|
|
33
|
-
pub use tabs::*;
|
|
34
|
-
pub use accordion::*;
|
|
35
|
-
pub use toast::*;
|
|
36
|
-
pub use badge::*;
|
|
37
|
-
pub use avatar::*;
|
|
38
|
-
pub use progress::*;
|
|
39
|
-
pub use spinner::*;
|
|
40
|
-
pub use skeleton::*;
|
|
41
|
-
pub use table::*;
|
|
42
|
-
pub use list::*;
|
|
43
|
-
pub use nav::*;
|
|
44
|
-
pub use breadcrumb::*;
|
|
45
|
-
pub use tooltip::*;
|
|
46
|
-
pub use dropdown::*;
|
|
47
|
-
pub use pagination::*;
|
|
48
|
-
pub use file_input::*;
|
|
49
|
-
pub use search::*;
|
|
50
|
-
pub use command_palette::*;
|
|
51
|
-
pub use alert::*;
|
|
1
|
+
//! CronixUI Components for egui
|
|
2
|
+
|
|
3
|
+
pub mod button;
|
|
4
|
+
pub mod card;
|
|
5
|
+
pub mod input;
|
|
6
|
+
pub mod toggle;
|
|
7
|
+
pub mod modal;
|
|
8
|
+
pub mod tabs;
|
|
9
|
+
pub mod accordion;
|
|
10
|
+
pub mod toast;
|
|
11
|
+
pub mod badge;
|
|
12
|
+
pub mod avatar;
|
|
13
|
+
pub mod progress;
|
|
14
|
+
pub mod spinner;
|
|
15
|
+
pub mod skeleton;
|
|
16
|
+
pub mod table;
|
|
17
|
+
pub mod list;
|
|
18
|
+
pub mod nav;
|
|
19
|
+
pub mod breadcrumb;
|
|
20
|
+
pub mod tooltip;
|
|
21
|
+
pub mod dropdown;
|
|
22
|
+
pub mod pagination;
|
|
23
|
+
pub mod file_input;
|
|
24
|
+
pub mod search;
|
|
25
|
+
pub mod command_palette;
|
|
26
|
+
pub mod alert;
|
|
27
|
+
|
|
28
|
+
pub use button::*;
|
|
29
|
+
pub use card::*;
|
|
30
|
+
pub use input::*;
|
|
31
|
+
pub use toggle::*;
|
|
32
|
+
pub use modal::*;
|
|
33
|
+
pub use tabs::*;
|
|
34
|
+
pub use accordion::*;
|
|
35
|
+
pub use toast::*;
|
|
36
|
+
pub use badge::*;
|
|
37
|
+
pub use avatar::*;
|
|
38
|
+
pub use progress::*;
|
|
39
|
+
pub use spinner::*;
|
|
40
|
+
pub use skeleton::*;
|
|
41
|
+
pub use table::*;
|
|
42
|
+
pub use list::*;
|
|
43
|
+
pub use nav::*;
|
|
44
|
+
pub use breadcrumb::*;
|
|
45
|
+
pub use tooltip::*;
|
|
46
|
+
pub use dropdown::*;
|
|
47
|
+
pub use pagination::*;
|
|
48
|
+
pub use file_input::*;
|
|
49
|
+
pub use search::*;
|
|
50
|
+
pub use command_palette::*;
|
|
51
|
+
pub use alert::*;
|