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.
Files changed (76) hide show
  1. package/README.md +1 -1
  2. package/package.json +71 -71
  3. package/packages/flutter/.qwen/settings.json +7 -0
  4. package/packages/flutter/pubspec.yaml +20 -20
  5. package/packages/go/cronixui/cronixui.go +926 -926
  6. package/packages/python/README.md +142 -0
  7. package/packages/python/cronixui/__init__.py +15 -6
  8. package/packages/python/cronixui/__pycache__/__init__.cpython-314.pyc +0 -0
  9. package/packages/python/cronixui/__pycache__/accordion.cpython-314.pyc +0 -0
  10. package/packages/python/cronixui/__pycache__/alert.cpython-314.pyc +0 -0
  11. package/packages/python/cronixui/__pycache__/avatar.cpython-314.pyc +0 -0
  12. package/packages/python/cronixui/__pycache__/badge.cpython-314.pyc +0 -0
  13. package/packages/python/cronixui/__pycache__/button.cpython-314.pyc +0 -0
  14. package/packages/python/cronixui/__pycache__/card.cpython-314.pyc +0 -0
  15. package/packages/python/cronixui/__pycache__/command_palette.cpython-314.pyc +0 -0
  16. package/packages/python/cronixui/__pycache__/core.cpython-314.pyc +0 -0
  17. package/packages/python/cronixui/__pycache__/dropdown.cpython-314.pyc +0 -0
  18. package/packages/python/cronixui/__pycache__/form.cpython-314.pyc +0 -0
  19. package/packages/python/cronixui/__pycache__/layout.cpython-314.pyc +0 -0
  20. package/packages/python/cronixui/__pycache__/list.cpython-314.pyc +0 -0
  21. package/packages/python/cronixui/__pycache__/loading.cpython-314.pyc +0 -0
  22. package/packages/python/cronixui/__pycache__/modal.cpython-314.pyc +0 -0
  23. package/packages/python/cronixui/__pycache__/nav.cpython-314.pyc +0 -0
  24. package/packages/python/cronixui/__pycache__/pagination.cpython-314.pyc +0 -0
  25. package/packages/python/cronixui/__pycache__/progress.cpython-314.pyc +0 -0
  26. package/packages/python/cronixui/__pycache__/search.cpython-314.pyc +0 -0
  27. package/packages/python/cronixui/__pycache__/table.cpython-314.pyc +0 -0
  28. package/packages/python/cronixui/__pycache__/tabs.cpython-314.pyc +0 -0
  29. package/packages/python/cronixui/__pycache__/toast.cpython-314.pyc +0 -0
  30. package/packages/python/cronixui/__pycache__/toggle.cpython-314.pyc +0 -0
  31. package/packages/python/cronixui/__pycache__/tokens.cpython-314.pyc +0 -0
  32. package/packages/python/cronixui/__pycache__/tooltip.cpython-314.pyc +0 -0
  33. package/packages/python/cronixui/alert.py +119 -36
  34. package/packages/python/cronixui/avatar.py +129 -22
  35. package/packages/python/cronixui/badge.py +161 -24
  36. package/packages/python/cronixui/button.py +96 -27
  37. package/packages/python/cronixui/card.py +206 -33
  38. package/packages/python/cronixui/core.py +212 -23
  39. package/packages/python/cronixui/form.py +552 -141
  40. package/packages/python/cronixui/layout.py +358 -96
  41. package/packages/python/cronixui/list.py +140 -37
  42. package/packages/python/cronixui/loading.py +107 -17
  43. package/packages/python/cronixui/progress.py +189 -47
  44. package/packages/python/cronixui/table.py +118 -31
  45. package/packages/python/cronixui/tooltip.py +117 -15
  46. package/packages/react/src/components/Accordion.tsx +82 -82
  47. package/packages/react/src/components/Button.tsx +47 -47
  48. package/packages/react/src/components/Card.tsx +69 -69
  49. package/packages/react/src/components/CommandPalette.tsx +131 -131
  50. package/packages/react/src/components/Dropdown.tsx +88 -88
  51. package/packages/react/src/components/FileInput.tsx +86 -86
  52. package/packages/react/src/components/FormGroup.tsx +36 -36
  53. package/packages/react/src/components/List.tsx +55 -55
  54. package/packages/react/src/components/Pagination.tsx +107 -107
  55. package/packages/react/src/components/Progress.tsx +49 -49
  56. package/packages/react/src/components/Search.tsx +95 -95
  57. package/packages/react/src/components/Sidebar.tsx +64 -64
  58. package/packages/react/src/components/Stack.tsx +69 -69
  59. package/packages/react/src/components/Table.tsx +90 -90
  60. package/packages/react/src/components/Toast.tsx +134 -134
  61. package/packages/react/src/components/Typography.tsx +66 -66
  62. package/packages/react/src/index.ts +40 -40
  63. package/packages/react/src/styles.css +2039 -2039
  64. package/packages/rust/cronixui/src/components/avatar.rs +85 -85
  65. package/packages/rust/cronixui/src/components/breadcrumb.rs +58 -58
  66. package/packages/rust/cronixui/src/components/card.rs +259 -259
  67. package/packages/rust/cronixui/src/components/command_palette.rs +254 -254
  68. package/packages/rust/cronixui/src/components/dropdown.rs +179 -179
  69. package/packages/rust/cronixui/src/components/file_input.rs +74 -74
  70. package/packages/rust/cronixui/src/components/mod.rs +51 -51
  71. package/packages/rust/cronixui/src/components/search.rs +185 -185
  72. package/packages/rust/cronixui/src/components/skeleton.rs +63 -63
  73. package/packages/rust/cronixui/src/components/table.rs +56 -56
  74. package/packages/rust/cronixui/src/lib.rs +128 -128
  75. package/packages/web/dist/cronixui.css +97 -93
  76. package/packages/web/dist/cronixui.min.css +1 -1
@@ -1,254 +1,254 @@
1
- //! Command palette component
2
-
3
- use egui::*;
4
- use crate::{colors::*, tokens::*};
5
-
6
- pub struct CommandItem {
7
- pub title: String,
8
- pub subtitle: Option<String>,
9
- pub kbd: Option<String>,
10
- }
11
-
12
- impl CommandItem {
13
- pub fn new(title: impl Into<String>) -> Self {
14
- Self { title: title.into(), subtitle: None, kbd: None }
15
- }
16
-
17
- pub fn subtitle(mut self, subtitle: impl Into<String>) -> Self {
18
- self.subtitle = Some(subtitle.into());
19
- self
20
- }
21
-
22
- pub fn kbd(mut self, kbd: impl Into<String>) -> Self {
23
- self.kbd = Some(kbd.into());
24
- self
25
- }
26
- }
27
-
28
- pub struct CommandPalette {
29
- pub items: Vec<CommandItem>,
30
- pub query: String,
31
- pub open: bool,
32
- pub selected_index: usize,
33
- id: Id,
34
- }
35
-
36
- impl CommandPalette {
37
- pub fn new(id: impl Into<Id>) -> Self {
38
- Self { items: Vec::new(), query: String::new(), open: false, selected_index: 0, id: id.into() }
39
- }
40
-
41
- pub fn item(mut self, item: CommandItem) -> Self {
42
- self.items.push(item);
43
- self
44
- }
45
-
46
- pub fn set_items(&mut self, items: Vec<CommandItem>) {
47
- self.items = items;
48
- }
49
-
50
- pub fn open(&mut self) {
51
- self.open = true;
52
- self.query.clear();
53
- self.selected_index = 0;
54
- }
55
-
56
- pub fn close(&mut self) {
57
- self.open = false;
58
- self.query.clear();
59
- self.selected_index = 0;
60
- }
61
-
62
- pub fn toggle(&mut self) {
63
- if self.open {
64
- self.close();
65
- } else {
66
- self.open();
67
- }
68
- }
69
-
70
- pub fn filter(&self) -> Vec<&CommandItem> {
71
- if self.query.is_empty() {
72
- return self.items.iter().collect();
73
- }
74
- self.items
75
- .iter()
76
- .filter(|item| item.title.to_lowercase().contains(&self.query.to_lowercase()))
77
- .collect()
78
- }
79
-
80
- /// Render the command palette as a modal dialog
81
- /// Returns the index of the selected command (into the filtered list)
82
- pub fn show(&mut self, ctx: &egui::Context) -> Option<usize> {
83
- if !self.open {
84
- return None;
85
- }
86
-
87
- let colors = Colors::default();
88
- let mut result = None;
89
-
90
- // Modal backdrop
91
- egui::Area::new(self.id.with("backdrop"))
92
- .order(Order::Foreground)
93
- .interactable(true)
94
- .show(ctx, |ui| {
95
- let screen_size = ctx.screen_rect().size();
96
- ui.set_min_size(screen_size);
97
-
98
- // Semi-transparent backdrop
99
- let painter = ui.painter_at(ui.max_rect());
100
- painter.rect_filled(
101
- ui.max_rect(),
102
- Rounding::ZERO,
103
- Color32::from_black_alpha(150),
104
- );
105
-
106
- // Command palette panel centered on screen
107
- let panel_width = 500.0;
108
- let panel_height = 400.0;
109
-
110
- egui::Frame::none()
111
- .fill(colors.surface)
112
- .stroke(egui::Stroke::new(1.0, colors.border))
113
- .rounding(Rounding::same(tokens::RADIUS_LG))
114
- .shadow(egui::Shadow {
115
- offset: [0.0, 8.0].into(),
116
- blur: 24.0,
117
- spread: 0.0,
118
- color: Color32::from_black_alpha(100),
119
- })
120
- .show(ui, |ui| {
121
- ui.set_min_size(vec2(panel_width, panel_height));
122
-
123
- // Search input at top
124
- ui.horizontal(|ui| {
125
- ui.label("⌘");
126
- let response = ui.add(
127
- TextEdit::singleline(&mut self.query)
128
- .hint_text("Type a command...")
129
- .desired_width(f32::INFINITY)
130
- .font(FontId::new(tokens::FONT_SIZE_BASE, FontFamily::Proportional)),
131
- );
132
-
133
- if response.has_focus() {
134
- // Handle keyboard navigation
135
- if ui.input(|i| i.key_pressed(Key::ArrowDown)) {
136
- let filtered = self.filter();
137
- if !filtered.is_empty() {
138
- self.selected_index = (self.selected_index + 1) % filtered.len();
139
- }
140
- }
141
- if ui.input(|i| i.key_pressed(Key::ArrowUp)) {
142
- let filtered = self.filter();
143
- if !filtered.is_empty() {
144
- self.selected_index = if self.selected_index == 0 {
145
- filtered.len() - 1
146
- } else {
147
- self.selected_index - 1
148
- };
149
- }
150
- }
151
- if ui.input(|i| i.key_pressed(Key::Enter)) {
152
- result = Some(self.selected_index);
153
- }
154
- if ui.input(|i| i.key_pressed(Key::Escape)) {
155
- self.close();
156
- }
157
- }
158
- });
159
-
160
- ui.add_space(SPACE_2);
161
-
162
- // Separator
163
- ui.separator();
164
-
165
- ui.add_space(SPACE_2);
166
-
167
- // Command list
168
- let filtered = self.filter();
169
- if !filtered.is_empty() {
170
- // Ensure selected_index is valid
171
- if self.selected_index >= filtered.len() {
172
- self.selected_index = 0;
173
- }
174
-
175
- egui::ScrollArea::vertical()
176
- .max_height(280.0)
177
- .show(ui, |ui| {
178
- for (idx, item) in filtered.iter().enumerate() {
179
- let is_selected = idx == self.selected_index;
180
-
181
- let response = ui.horizontal(|ui| {
182
- if is_selected {
183
- ui.label(
184
- RichText::new("→")
185
- .size(tokens::FONT_SIZE_BASE)
186
- .color(colors.accent_text),
187
- );
188
- } else {
189
- ui.add_space(SPACE_4);
190
- }
191
-
192
- ui.label(
193
- RichText::new(&item.title)
194
- .size(tokens::FONT_SIZE_BASE)
195
- .color(if is_selected { colors.accent_text } else { colors.text }),
196
- );
197
-
198
- if let Some(subtitle) = &item.subtitle {
199
- ui.label(
200
- RichText::new(subtitle)
201
- .size(tokens::FONT_SIZE_SM)
202
- .color(colors.text_muted),
203
- );
204
- }
205
-
206
- if let Some(kbd) = &item.kbd {
207
- ui.with_layout(egui::Layout::right_to_left(Align::Center), |ui| {
208
- egui::Frame::none()
209
- .fill(colors.surface_3)
210
- .stroke(egui::Stroke::new(1.0, colors.border))
211
- .rounding(Rounding::same(tokens::RADIUS_SM))
212
- .inner_margin(vec2(SPACE_2, SPACE_1))
213
- .show(ui, |ui| {
214
- ui.label(
215
- RichText::new(kbd)
216
- .size(tokens::FONT_SIZE_XS)
217
- .color(colors.text_muted)
218
- .font(FontFamily::Monospace),
219
- );
220
- });
221
- });
222
- }
223
- });
224
-
225
- if response.response.clicked() {
226
- result = Some(idx);
227
- }
228
- }
229
- });
230
- } else if !self.query.is_empty() {
231
- ui.centered_and_justified(|ui| {
232
- ui.label(
233
- RichText::new("No commands found")
234
- .size(tokens::FONT_SIZE_SM)
235
- .color(colors.text_muted),
236
- );
237
- });
238
- }
239
- });
240
- });
241
-
242
- if result.is_some() {
243
- self.close();
244
- }
245
-
246
- result
247
- }
248
- }
249
-
250
- impl Default for CommandPalette {
251
- fn default() -> Self {
252
- Self::new("default_command_palette")
253
- }
254
- }
1
+ //! Command palette component
2
+
3
+ use egui::*;
4
+ use crate::{colors::*, tokens::*};
5
+
6
+ pub struct CommandItem {
7
+ pub title: String,
8
+ pub subtitle: Option<String>,
9
+ pub kbd: Option<String>,
10
+ }
11
+
12
+ impl CommandItem {
13
+ pub fn new(title: impl Into<String>) -> Self {
14
+ Self { title: title.into(), subtitle: None, kbd: None }
15
+ }
16
+
17
+ pub fn subtitle(mut self, subtitle: impl Into<String>) -> Self {
18
+ self.subtitle = Some(subtitle.into());
19
+ self
20
+ }
21
+
22
+ pub fn kbd(mut self, kbd: impl Into<String>) -> Self {
23
+ self.kbd = Some(kbd.into());
24
+ self
25
+ }
26
+ }
27
+
28
+ pub struct CommandPalette {
29
+ pub items: Vec<CommandItem>,
30
+ pub query: String,
31
+ pub open: bool,
32
+ pub selected_index: usize,
33
+ id: Id,
34
+ }
35
+
36
+ impl CommandPalette {
37
+ pub fn new(id: impl Into<Id>) -> Self {
38
+ Self { items: Vec::new(), query: String::new(), open: false, selected_index: 0, id: id.into() }
39
+ }
40
+
41
+ pub fn item(mut self, item: CommandItem) -> Self {
42
+ self.items.push(item);
43
+ self
44
+ }
45
+
46
+ pub fn set_items(&mut self, items: Vec<CommandItem>) {
47
+ self.items = items;
48
+ }
49
+
50
+ pub fn open(&mut self) {
51
+ self.open = true;
52
+ self.query.clear();
53
+ self.selected_index = 0;
54
+ }
55
+
56
+ pub fn close(&mut self) {
57
+ self.open = false;
58
+ self.query.clear();
59
+ self.selected_index = 0;
60
+ }
61
+
62
+ pub fn toggle(&mut self) {
63
+ if self.open {
64
+ self.close();
65
+ } else {
66
+ self.open();
67
+ }
68
+ }
69
+
70
+ pub fn filter(&self) -> Vec<&CommandItem> {
71
+ if self.query.is_empty() {
72
+ return self.items.iter().collect();
73
+ }
74
+ self.items
75
+ .iter()
76
+ .filter(|item| item.title.to_lowercase().contains(&self.query.to_lowercase()))
77
+ .collect()
78
+ }
79
+
80
+ /// Render the command palette as a modal dialog
81
+ /// Returns the index of the selected command (into the filtered list)
82
+ pub fn show(&mut self, ctx: &egui::Context) -> Option<usize> {
83
+ if !self.open {
84
+ return None;
85
+ }
86
+
87
+ let colors = Colors::default();
88
+ let mut result = None;
89
+
90
+ // Modal backdrop
91
+ egui::Area::new(self.id.with("backdrop"))
92
+ .order(Order::Foreground)
93
+ .interactable(true)
94
+ .show(ctx, |ui| {
95
+ let screen_size = ctx.screen_rect().size();
96
+ ui.set_min_size(screen_size);
97
+
98
+ // Semi-transparent backdrop
99
+ let painter = ui.painter_at(ui.max_rect());
100
+ painter.rect_filled(
101
+ ui.max_rect(),
102
+ Rounding::ZERO,
103
+ Color32::from_black_alpha(150),
104
+ );
105
+
106
+ // Command palette panel centered on screen
107
+ let panel_width = 500.0;
108
+ let panel_height = 400.0;
109
+
110
+ egui::Frame::none()
111
+ .fill(colors.surface)
112
+ .stroke(egui::Stroke::new(1.0, colors.border))
113
+ .rounding(Rounding::same(tokens::RADIUS_LG))
114
+ .shadow(egui::Shadow {
115
+ offset: [0.0, 8.0].into(),
116
+ blur: 24.0,
117
+ spread: 0.0,
118
+ color: Color32::from_black_alpha(100),
119
+ })
120
+ .show(ui, |ui| {
121
+ ui.set_min_size(vec2(panel_width, panel_height));
122
+
123
+ // Search input at top
124
+ ui.horizontal(|ui| {
125
+ ui.label("⌘");
126
+ let response = ui.add(
127
+ TextEdit::singleline(&mut self.query)
128
+ .hint_text("Type a command...")
129
+ .desired_width(f32::INFINITY)
130
+ .font(FontId::new(tokens::FONT_SIZE_BASE, FontFamily::Proportional)),
131
+ );
132
+
133
+ if response.has_focus() {
134
+ // Handle keyboard navigation
135
+ if ui.input(|i| i.key_pressed(Key::ArrowDown)) {
136
+ let filtered = self.filter();
137
+ if !filtered.is_empty() {
138
+ self.selected_index = (self.selected_index + 1) % filtered.len();
139
+ }
140
+ }
141
+ if ui.input(|i| i.key_pressed(Key::ArrowUp)) {
142
+ let filtered = self.filter();
143
+ if !filtered.is_empty() {
144
+ self.selected_index = if self.selected_index == 0 {
145
+ filtered.len() - 1
146
+ } else {
147
+ self.selected_index - 1
148
+ };
149
+ }
150
+ }
151
+ if ui.input(|i| i.key_pressed(Key::Enter)) {
152
+ result = Some(self.selected_index);
153
+ }
154
+ if ui.input(|i| i.key_pressed(Key::Escape)) {
155
+ self.close();
156
+ }
157
+ }
158
+ });
159
+
160
+ ui.add_space(SPACE_2);
161
+
162
+ // Separator
163
+ ui.separator();
164
+
165
+ ui.add_space(SPACE_2);
166
+
167
+ // Command list
168
+ let filtered = self.filter();
169
+ if !filtered.is_empty() {
170
+ // Ensure selected_index is valid
171
+ if self.selected_index >= filtered.len() {
172
+ self.selected_index = 0;
173
+ }
174
+
175
+ egui::ScrollArea::vertical()
176
+ .max_height(280.0)
177
+ .show(ui, |ui| {
178
+ for (idx, item) in filtered.iter().enumerate() {
179
+ let is_selected = idx == self.selected_index;
180
+
181
+ let response = ui.horizontal(|ui| {
182
+ if is_selected {
183
+ ui.label(
184
+ RichText::new("→")
185
+ .size(tokens::FONT_SIZE_BASE)
186
+ .color(colors.accent_text),
187
+ );
188
+ } else {
189
+ ui.add_space(SPACE_4);
190
+ }
191
+
192
+ ui.label(
193
+ RichText::new(&item.title)
194
+ .size(tokens::FONT_SIZE_BASE)
195
+ .color(if is_selected { colors.accent_text } else { colors.text }),
196
+ );
197
+
198
+ if let Some(subtitle) = &item.subtitle {
199
+ ui.label(
200
+ RichText::new(subtitle)
201
+ .size(tokens::FONT_SIZE_SM)
202
+ .color(colors.text_muted),
203
+ );
204
+ }
205
+
206
+ if let Some(kbd) = &item.kbd {
207
+ ui.with_layout(egui::Layout::right_to_left(Align::Center), |ui| {
208
+ egui::Frame::none()
209
+ .fill(colors.surface_3)
210
+ .stroke(egui::Stroke::new(1.0, colors.border))
211
+ .rounding(Rounding::same(tokens::RADIUS_SM))
212
+ .inner_margin(vec2(SPACE_2, SPACE_1))
213
+ .show(ui, |ui| {
214
+ ui.label(
215
+ RichText::new(kbd)
216
+ .size(tokens::FONT_SIZE_XS)
217
+ .color(colors.text_muted)
218
+ .font(FontFamily::Monospace),
219
+ );
220
+ });
221
+ });
222
+ }
223
+ });
224
+
225
+ if response.response.clicked() {
226
+ result = Some(idx);
227
+ }
228
+ }
229
+ });
230
+ } else if !self.query.is_empty() {
231
+ ui.centered_and_justified(|ui| {
232
+ ui.label(
233
+ RichText::new("No commands found")
234
+ .size(tokens::FONT_SIZE_SM)
235
+ .color(colors.text_muted),
236
+ );
237
+ });
238
+ }
239
+ });
240
+ });
241
+
242
+ if result.is_some() {
243
+ self.close();
244
+ }
245
+
246
+ result
247
+ }
248
+ }
249
+
250
+ impl Default for CommandPalette {
251
+ fn default() -> Self {
252
+ Self::new("default_command_palette")
253
+ }
254
+ }