cronixui 1.0.3 → 1.0.5

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.
@@ -0,0 +1,58 @@
1
+ """Pagination component."""
2
+
3
+ from typing import Callable, Optional
4
+
5
+
6
+ class Pagination:
7
+ """Pagination component."""
8
+
9
+ def __init__(
10
+ self,
11
+ element=None,
12
+ total: int = 1,
13
+ current: int = 1,
14
+ on_change: Optional[Callable[[int], None]] = None,
15
+ ):
16
+ """Initialize pagination.
17
+
18
+ Args:
19
+ element: Target element
20
+ total: Total number of pages
21
+ current: Current page (default: 1)
22
+ on_change: Callback when page changes
23
+ """
24
+ self._element = element
25
+ self._total = total
26
+ self._current = current
27
+ self._on_change = on_change
28
+
29
+ def go_to(self, page: int) -> None:
30
+ """Go to specific page."""
31
+ if 1 <= page <= self._total:
32
+ self._current = page
33
+ if self._on_change:
34
+ self._on_change(page)
35
+
36
+ def next(self) -> None:
37
+ """Go to next page."""
38
+ if self._current < self._total:
39
+ self.go_to(self._current + 1)
40
+
41
+ def prev(self) -> None:
42
+ """Go to previous page."""
43
+ if self._current > 1:
44
+ self.go_to(self._current - 1)
45
+
46
+ @property
47
+ def current(self) -> int:
48
+ """Get current page."""
49
+ return self._current
50
+
51
+ @property
52
+ def total(self) -> int:
53
+ """Get total pages."""
54
+ return self._total
55
+
56
+ def render(self) -> None:
57
+ """Re-render pagination."""
58
+ pass
@@ -0,0 +1,11 @@
1
+ [project]
2
+ name = "cronixui"
3
+ version = "1.0.2"
4
+ description = "CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography"
5
+ license = {text = "GPL-3.0"}
6
+ authors = [{name = "CazyUndee"}]
7
+ keywords = ["ui", "dark-mode", "design-system", "components"]
8
+ requires-python = ">=3.8"
9
+
10
+ [project.urls]
11
+ Repository = "https://github.com/CazyUndee/CronixUI"
@@ -0,0 +1,50 @@
1
+ """Search component."""
2
+
3
+ from typing import Callable, Optional, List
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class SearchItem:
9
+ """Search result item."""
10
+
11
+ title: str
12
+ subtitle: Optional[str] = None
13
+ action: Optional[Callable] = None
14
+
15
+
16
+ class Search:
17
+ """Search component."""
18
+
19
+ def __init__(self, element=None):
20
+ """Initialize search on element."""
21
+ self._element = element
22
+ self._items: List[SearchItem] = []
23
+ self._open: bool = False
24
+
25
+ def set_items(self, items: List[SearchItem]) -> None:
26
+ """Set searchable items."""
27
+ self._items = items
28
+
29
+ def filter(self, query: str) -> List[SearchItem]:
30
+ """Filter items by query."""
31
+ query_lower = query.lower()
32
+ return [item for item in self._items if query_lower in item.title.lower()]
33
+
34
+ def open(self) -> None:
35
+ """Open search results."""
36
+ self._open = True
37
+
38
+ def close(self) -> None:
39
+ """Close search results."""
40
+ self._open = False
41
+
42
+ def is_open(self) -> bool:
43
+ """Check if search is open."""
44
+ return self._open
45
+
46
+ def select(self, index: int) -> None:
47
+ """Select and execute item by index."""
48
+ if 0 <= index < len(self._items) and self._items[index].action:
49
+ self._items[index].action()
50
+ self.close()
@@ -0,0 +1,18 @@
1
+ """Tabs component."""
2
+
3
+
4
+ class Tabs:
5
+ """Tabs component."""
6
+
7
+ def __init__(self, element=None):
8
+ """Initialize tabs on element."""
9
+ self._element = element
10
+ self._active_index: int = 0
11
+
12
+ def set_active(self, index: int) -> None:
13
+ """Set active tab by index."""
14
+ self._active_index = index
15
+
16
+ def active_index(self) -> int:
17
+ """Get active tab index."""
18
+ return self._active_index
@@ -0,0 +1,73 @@
1
+ """Toast notification component."""
2
+
3
+ from typing import Optional
4
+ from enum import Enum
5
+
6
+
7
+ class ToastType(Enum):
8
+ SUCCESS = "success"
9
+ ERROR = "error"
10
+ WARNING = "warning"
11
+ INFO = "info"
12
+
13
+
14
+ class Toast:
15
+ """Toast notification component."""
16
+
17
+ def __init__(self, element=None):
18
+ self._element = element
19
+ self._title: Optional[str] = None
20
+ self._message: str = ""
21
+ self._type: ToastType = ToastType.INFO
22
+ self._duration: int = 4000
23
+
24
+ @staticmethod
25
+ def show(
26
+ title: Optional[str] = None,
27
+ message: str = "",
28
+ type: str = "info",
29
+ duration: int = 4000,
30
+ ) -> "Toast":
31
+ """Show a toast notification."""
32
+ toast = Toast()
33
+ toast._title = title
34
+ toast._message = message
35
+ toast._type = ToastType(type)
36
+ toast._duration = duration
37
+ return toast
38
+
39
+ @staticmethod
40
+ def success(message: str, title: Optional[str] = None) -> "Toast":
41
+ """Show a success toast."""
42
+ return Toast.show(title=title, message=message, type="success")
43
+
44
+ @staticmethod
45
+ def error(message: str, title: Optional[str] = None) -> "Toast":
46
+ """Show an error toast."""
47
+ return Toast.show(title=title, message=message, type="error")
48
+
49
+ @staticmethod
50
+ def warning(message: str, title: Optional[str] = None) -> "Toast":
51
+ """Show a warning toast."""
52
+ return Toast.show(title=title, message=message, type="warning")
53
+
54
+ @staticmethod
55
+ def info(message: str, title: Optional[str] = None) -> "Toast":
56
+ """Show an info toast."""
57
+ return Toast.show(title=title, message=message, type="info")
58
+
59
+ @property
60
+ def title(self) -> Optional[str]:
61
+ return self._title
62
+
63
+ @property
64
+ def message(self) -> str:
65
+ return self._message
66
+
67
+ @property
68
+ def type(self) -> ToastType:
69
+ return self._type
70
+
71
+ @property
72
+ def duration(self) -> int:
73
+ return self._duration
@@ -0,0 +1,22 @@
1
+ """Toggle switch component."""
2
+
3
+
4
+ class Toggle:
5
+ """Toggle switch component."""
6
+
7
+ def __init__(self, element=None):
8
+ """Initialize toggle on element."""
9
+ self._element = element
10
+ self._on: bool = False
11
+
12
+ def toggle(self) -> None:
13
+ """Toggle the state."""
14
+ self._on = not self._on
15
+
16
+ def is_on(self) -> bool:
17
+ """Check if toggle is on."""
18
+ return self._on
19
+
20
+ def set_on(self, value: bool) -> None:
21
+ """Set toggle state."""
22
+ self._on = value
@@ -0,0 +1,103 @@
1
+ declare namespace CronixUI {
2
+ interface ToastOptions {
3
+ title?: string;
4
+ message: string;
5
+ type?: 'success' | 'error' | 'warning' | 'info';
6
+ duration?: number;
7
+ }
8
+
9
+ interface PaginationOptions {
10
+ total: number;
11
+ current: number;
12
+ onChange?: (page: number) => void;
13
+ }
14
+
15
+ interface SearchItem {
16
+ title: string;
17
+ subtitle?: string;
18
+ action: () => void;
19
+ }
20
+
21
+ interface CommandPaletteItem {
22
+ title: string;
23
+ kbd?: string;
24
+ action: () => void;
25
+ }
26
+
27
+ interface ModalInstance {
28
+ open(): void;
29
+ close(): void;
30
+ }
31
+
32
+ interface DropdownInstance {
33
+ open(): void;
34
+ close(): void;
35
+ toggle(): void;
36
+ }
37
+
38
+ interface ToggleInstance {
39
+ toggle(): void;
40
+ isOn(): boolean;
41
+ setOn(value: boolean): void;
42
+ }
43
+
44
+ interface TabsInstance {
45
+ setActive(index: number): void;
46
+ }
47
+
48
+ interface AccordionInstance {
49
+ toggle(item: HTMLElement): void;
50
+ openAll(): void;
51
+ closeAll(): void;
52
+ }
53
+
54
+ interface PaginationInstance {
55
+ goTo(page: number): void;
56
+ render(): void;
57
+ }
58
+
59
+ interface CommandPaletteInstance {
60
+ open(): void;
61
+ close(): void;
62
+ setItems(items: CommandPaletteItem[]): void;
63
+ }
64
+
65
+ interface SearchInstance {
66
+ setItems(items: SearchItem[]): void;
67
+ filter(query: string): SearchItem[];
68
+ open(): void;
69
+ close(): void;
70
+ }
71
+
72
+ interface ToastStatic {
73
+ show(options: ToastOptions): void;
74
+ success(message: string): void;
75
+ error(message: string): void;
76
+ warning(message: string): void;
77
+ info(message: string): void;
78
+ }
79
+
80
+ interface NavStatic {
81
+ init(): void;
82
+ }
83
+
84
+ interface CronixUIStatic {
85
+ init(): void;
86
+ $(selector: string): HTMLElement | null;
87
+ $$(selector: string): NodeListOf<HTMLElement>;
88
+ createEl(tag: string, className?: string, attrs?: Record<string, string>): HTMLElement;
89
+ Toast: ToastStatic;
90
+ Nav: NavStatic;
91
+ Toggle: new (element: HTMLElement) => ToggleInstance;
92
+ Modal: new (element: HTMLElement) => ModalInstance;
93
+ Dropdown: new (element: HTMLElement) => DropdownInstance;
94
+ Tabs: new (element: HTMLElement) => TabsInstance;
95
+ Accordion: new (element: HTMLElement) => AccordionInstance;
96
+ Pagination: new (element: HTMLElement, options: PaginationOptions) => PaginationInstance;
97
+ CommandPalette: new (element: HTMLElement) => CommandPaletteInstance;
98
+ Search: new (element: HTMLElement) => SearchInstance;
99
+ }
100
+ }
101
+
102
+ declare const CronixUI: CronixUI.CronixUIStatic;
103
+ export default CronixUI;
@@ -0,0 +1,49 @@
1
+ use std::collections::HashSet;
2
+
3
+ pub struct Accordion {
4
+ open_indices: HashSet<usize>,
5
+ }
6
+
7
+ impl Accordion {
8
+ pub fn new() -> Self {
9
+ Self {
10
+ open_indices: HashSet::new(),
11
+ }
12
+ }
13
+
14
+ pub fn toggle(&mut self, index: usize) {
15
+ if self.open_indices.contains(&index) {
16
+ self.open_indices.remove(&index);
17
+ } else {
18
+ self.open_indices.insert(index);
19
+ }
20
+ }
21
+
22
+ pub fn open(&mut self, index: usize) {
23
+ self.open_indices.insert(index);
24
+ }
25
+
26
+ pub fn close(&mut self, index: usize) {
27
+ self.open_indices.remove(&index);
28
+ }
29
+
30
+ pub fn open_all(&mut self, total: usize) {
31
+ for i in 0..total {
32
+ self.open_indices.insert(i);
33
+ }
34
+ }
35
+
36
+ pub fn close_all(&mut self) {
37
+ self.open_indices.clear();
38
+ }
39
+
40
+ pub fn is_open(&self, index: usize) -> bool {
41
+ self.open_indices.contains(&index)
42
+ }
43
+ }
44
+
45
+ impl Default for Accordion {
46
+ fn default() -> Self {
47
+ Self::new()
48
+ }
49
+ }
@@ -0,0 +1,62 @@
1
+ pub struct CommandPaletteItem {
2
+ pub title: String,
3
+ pub kbd: Option<String>,
4
+ }
5
+
6
+ impl CommandPaletteItem {
7
+ pub fn new(title: impl Into<String>) -> Self {
8
+ Self {
9
+ title: title.into(),
10
+ kbd: None,
11
+ }
12
+ }
13
+
14
+ pub fn kbd(mut self, kbd: impl Into<String>) -> Self {
15
+ self.kbd = Some(kbd.into());
16
+ self
17
+ }
18
+ }
19
+
20
+ pub struct CommandPalette {
21
+ open: bool,
22
+ items: Vec<CommandPaletteItem>,
23
+ }
24
+
25
+ impl CommandPalette {
26
+ pub fn new() -> Self {
27
+ Self {
28
+ open: false,
29
+ items: Vec::new(),
30
+ }
31
+ }
32
+
33
+ pub fn open(&mut self) {
34
+ self.open = true;
35
+ }
36
+
37
+ pub fn close(&mut self) {
38
+ self.open = false;
39
+ }
40
+
41
+ pub fn toggle(&mut self) {
42
+ self.open = !self.open;
43
+ }
44
+
45
+ pub fn is_open(&self) -> bool {
46
+ self.open
47
+ }
48
+
49
+ pub fn set_items(&mut self, items: Vec<CommandPaletteItem>) {
50
+ self.items = items;
51
+ }
52
+
53
+ pub fn items(&self) -> &[CommandPaletteItem] {
54
+ &self.items
55
+ }
56
+ }
57
+
58
+ impl Default for CommandPalette {
59
+ fn default() -> Self {
60
+ Self::new()
61
+ }
62
+ }
@@ -0,0 +1,31 @@
1
+ pub struct Dropdown {
2
+ open: bool,
3
+ }
4
+
5
+ impl Dropdown {
6
+ pub fn new() -> Self {
7
+ Self { open: false }
8
+ }
9
+
10
+ pub fn open(&mut self) {
11
+ self.open = true;
12
+ }
13
+
14
+ pub fn close(&mut self) {
15
+ self.open = false;
16
+ }
17
+
18
+ pub fn toggle(&mut self) {
19
+ self.open = !self.open;
20
+ }
21
+
22
+ pub fn is_open(&self) -> bool {
23
+ self.open
24
+ }
25
+ }
26
+
27
+ impl Default for Dropdown {
28
+ fn default() -> Self {
29
+ Self::new()
30
+ }
31
+ }
@@ -0,0 +1,79 @@
1
+ //! CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography
2
+ //!
3
+ //! ## Example
4
+ //!
5
+ //! ```rust
6
+ //! use cronixui::{Toast, Toggle, Modal};
7
+ //!
8
+ //! // Create a toast
9
+ //! let toast = Toast::success("Operation completed!");
10
+ //!
11
+ //! // Create a toggle
12
+ //! let mut toggle = Toggle::new();
13
+ //! toggle.toggle();
14
+ //! assert!(toggle.is_on());
15
+ //! ```
16
+
17
+ pub const VERSION: &str = "1.0.4";
18
+
19
+ mod toast;
20
+ mod toggle;
21
+ mod modal;
22
+ mod dropdown;
23
+ mod tabs;
24
+ mod accordion;
25
+ mod pagination;
26
+ mod command_palette;
27
+ mod search;
28
+
29
+ pub use toast::{Toast, ToastType};
30
+ pub use toggle::Toggle;
31
+ pub use modal::Modal;
32
+ pub use dropdown::Dropdown;
33
+ pub use tabs::Tabs;
34
+ pub use accordion::Accordion;
35
+ pub use pagination::Pagination;
36
+ pub use command_palette::{CommandPalette, CommandPaletteItem};
37
+ pub use search::{Search, SearchItem};
38
+
39
+ /// Initialize CronixUI
40
+ pub fn init() {
41
+ println!("CronixUI {} initialized", VERSION);
42
+ }
43
+
44
+ #[cfg(test)]
45
+ mod tests {
46
+ use super::*;
47
+
48
+ #[test]
49
+ fn test_toggle() {
50
+ let mut toggle = Toggle::new();
51
+ assert!(!toggle.is_on());
52
+ toggle.toggle();
53
+ assert!(toggle.is_on());
54
+ toggle.set_on(false);
55
+ assert!(!toggle.is_on());
56
+ }
57
+
58
+ #[test]
59
+ fn test_pagination() {
60
+ let mut pagination = Pagination::new(10, 1);
61
+ assert_eq!(pagination.current(), 1);
62
+ pagination.next();
63
+ assert_eq!(pagination.current(), 2);
64
+ pagination.go_to(5);
65
+ assert_eq!(pagination.current(), 5);
66
+ }
67
+
68
+ #[test]
69
+ fn test_search() {
70
+ let mut search = Search::new();
71
+ search.set_items(vec![
72
+ SearchItem::new("Apple"),
73
+ SearchItem::new("Banana"),
74
+ SearchItem::new("Apricot"),
75
+ ]);
76
+ let results = search.filter("ap");
77
+ assert_eq!(results.len(), 2);
78
+ }
79
+ }
@@ -0,0 +1,27 @@
1
+ pub struct Modal {
2
+ open: bool,
3
+ }
4
+
5
+ impl Modal {
6
+ pub fn new() -> Self {
7
+ Self { open: false }
8
+ }
9
+
10
+ pub fn open(&mut self) {
11
+ self.open = true;
12
+ }
13
+
14
+ pub fn close(&mut self) {
15
+ self.open = false;
16
+ }
17
+
18
+ pub fn is_open(&self) -> bool {
19
+ self.open
20
+ }
21
+ }
22
+
23
+ impl Default for Modal {
24
+ fn default() -> Self {
25
+ Self::new()
26
+ }
27
+ }
@@ -0,0 +1,37 @@
1
+ pub struct Pagination {
2
+ total: usize,
3
+ current: usize,
4
+ }
5
+
6
+ impl Pagination {
7
+ pub fn new(total: usize, current: usize) -> Self {
8
+ let current = current.clamp(1, total.max(1));
9
+ Self { total, current }
10
+ }
11
+
12
+ pub fn go_to(&mut self, page: usize) {
13
+ if page >= 1 && page <= self.total {
14
+ self.current = page;
15
+ }
16
+ }
17
+
18
+ pub fn current(&self) -> usize {
19
+ self.current
20
+ }
21
+
22
+ pub fn total(&self) -> usize {
23
+ self.total
24
+ }
25
+
26
+ pub fn next(&mut self) {
27
+ if self.current < self.total {
28
+ self.current += 1;
29
+ }
30
+ }
31
+
32
+ pub fn prev(&mut self) {
33
+ if self.current > 1 {
34
+ self.current -= 1;
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,49 @@
1
+ pub struct SearchItem {
2
+ pub title: String,
3
+ pub subtitle: Option<String>,
4
+ }
5
+
6
+ impl SearchItem {
7
+ pub fn new(title: impl Into<String>) -> Self {
8
+ Self {
9
+ title: title.into(),
10
+ subtitle: None,
11
+ }
12
+ }
13
+
14
+ pub fn subtitle(mut self, subtitle: impl Into<String>) -> Self {
15
+ self.subtitle = Some(subtitle.into());
16
+ self
17
+ }
18
+ }
19
+
20
+ pub struct Search {
21
+ items: Vec<SearchItem>,
22
+ }
23
+
24
+ impl Search {
25
+ pub fn new() -> Self {
26
+ Self { items: Vec::new() }
27
+ }
28
+
29
+ pub fn set_items(&mut self, items: Vec<SearchItem>) {
30
+ self.items = items;
31
+ }
32
+
33
+ pub fn filter(&self, query: &str) -> Vec<&SearchItem> {
34
+ self.items
35
+ .iter()
36
+ .filter(|item| item.title.to_lowercase().contains(&query.to_lowercase()))
37
+ .collect()
38
+ }
39
+
40
+ pub fn items(&self) -> &[SearchItem] {
41
+ &self.items
42
+ }
43
+ }
44
+
45
+ impl Default for Search {
46
+ fn default() -> Self {
47
+ Self::new()
48
+ }
49
+ }
@@ -0,0 +1,23 @@
1
+ pub struct Tabs {
2
+ active_index: usize,
3
+ }
4
+
5
+ impl Tabs {
6
+ pub fn new() -> Self {
7
+ Self { active_index: 0 }
8
+ }
9
+
10
+ pub fn set_active(&mut self, index: usize) {
11
+ self.active_index = index;
12
+ }
13
+
14
+ pub fn active_index(&self) -> usize {
15
+ self.active_index
16
+ }
17
+ }
18
+
19
+ impl Default for Tabs {
20
+ fn default() -> Self {
21
+ Self::new()
22
+ }
23
+ }