cronixui 1.0.4 → 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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cronixui",
3
- "version": "1.0.4",
4
- "description": "CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography",
3
+ "version": "1.0.5",
4
+ "description": "CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography. Available for JavaScript, TypeScript, Python, Go, and Rust.",
5
5
  "keywords": [
6
6
  "ui",
7
7
  "css",
@@ -40,6 +40,9 @@
40
40
  "packages/web/src/",
41
41
  "packages/react/src/",
42
42
  "packages/win/CronixUI.WinUI/",
43
+ "packages/python/cronixui/",
44
+ "packages/go/cronixui/",
45
+ "packages/rust/cronixui/src/",
43
46
  "README.md"
44
47
  ],
45
48
  "scripts": {
@@ -0,0 +1,379 @@
1
+ package cronixui
2
+
3
+ import "fmt"
4
+
5
+ // Version of CronixUI
6
+ const Version = "1.0.4"
7
+
8
+ // ToastType represents toast notification type
9
+ type ToastType int
10
+
11
+ const (
12
+ ToastTypeSuccess ToastType = iota
13
+ ToastTypeError
14
+ ToastTypeWarning
15
+ ToastTypeInfo
16
+ )
17
+
18
+ // Toast represents a toast notification
19
+ type Toast struct {
20
+ Title string
21
+ Message string
22
+ Type ToastType
23
+ Duration int
24
+ }
25
+
26
+ // ToastShow displays a toast notification
27
+ func ToastShow(message string, opts ...func(*Toast)) *Toast {
28
+ t := &Toast{Message: message, Type: ToastTypeInfo, Duration: 4000}
29
+ for _, opt := range opts {
30
+ opt(t)
31
+ }
32
+ return t
33
+ }
34
+
35
+ // WithTitle sets toast title
36
+ func WithTitle(title string) func(*Toast) {
37
+ return func(t *Toast) { t.Title = title }
38
+ }
39
+
40
+ // WithType sets toast type
41
+ func WithType(toastType ToastType) func(*Toast) {
42
+ return func(t *Toast) { t.Type = toastType }
43
+ }
44
+
45
+ // WithDuration sets toast duration
46
+ func WithDuration(duration int) func(*Toast) {
47
+ return func(t *Toast) { t.Duration = duration }
48
+ }
49
+
50
+ // ToastSuccess shows a success toast
51
+ func ToastSuccess(message string) *Toast {
52
+ return ToastShow(message, WithType(ToastTypeSuccess))
53
+ }
54
+
55
+ // ToastError shows an error toast
56
+ func ToastError(message string) *Toast {
57
+ return ToastShow(message, WithType(ToastTypeError))
58
+ }
59
+
60
+ // ToastWarning shows a warning toast
61
+ func ToastWarning(message string) *Toast {
62
+ return ToastShow(message, WithType(ToastTypeWarning))
63
+ }
64
+
65
+ // ToastInfo shows an info toast
66
+ func ToastInfo(message string) *Toast {
67
+ return ToastShow(message, WithType(ToastTypeInfo))
68
+ }
69
+
70
+ // Toggle represents a toggle switch
71
+ type Toggle struct {
72
+ on bool
73
+ }
74
+
75
+ // NewToggle creates a new toggle
76
+ func NewToggle() *Toggle {
77
+ return &Toggle{}
78
+ }
79
+
80
+ // Toggle flips the toggle state
81
+ func (t *Toggle) Toggle() {
82
+ t.on = !t.on
83
+ }
84
+
85
+ // IsOn returns current toggle state
86
+ func (t *Toggle) IsOn() bool {
87
+ return t.on
88
+ }
89
+
90
+ // SetOn sets the toggle state
91
+ func (t *Toggle) SetOn(value bool) {
92
+ t.on = value
93
+ }
94
+
95
+ // Modal represents a modal dialog
96
+ type Modal struct {
97
+ open bool
98
+ }
99
+
100
+ // NewModal creates a new modal
101
+ func NewModal() *Modal {
102
+ return &Modal{}
103
+ }
104
+
105
+ // Open opens the modal
106
+ func (m *Modal) Open() {
107
+ m.open = true
108
+ }
109
+
110
+ // Close closes the modal
111
+ func (m *Modal) Close() {
112
+ m.open = false
113
+ }
114
+
115
+ // IsOpen returns whether modal is open
116
+ func (m *Modal) IsOpen() bool {
117
+ return m.open
118
+ }
119
+
120
+ // Dropdown represents a dropdown menu
121
+ type Dropdown struct {
122
+ open bool
123
+ }
124
+
125
+ // NewDropdown creates a new dropdown
126
+ func NewDropdown() *Dropdown {
127
+ return &Dropdown{}
128
+ }
129
+
130
+ // Open opens the dropdown
131
+ func (d *Dropdown) Open() {
132
+ d.open = true
133
+ }
134
+
135
+ // Close closes the dropdown
136
+ func (d *Dropdown) Close() {
137
+ d.open = false
138
+ }
139
+
140
+ // Toggle flips dropdown state
141
+ func (d *Dropdown) Toggle() {
142
+ d.open = !d.open
143
+ }
144
+
145
+ // IsOpen returns whether dropdown is open
146
+ func (d *Dropdown) IsOpen() bool {
147
+ return d.open
148
+ }
149
+
150
+ // Tabs represents a tabs component
151
+ type Tabs struct {
152
+ activeIndex int
153
+ }
154
+
155
+ // NewTabs creates new tabs
156
+ func NewTabs() *Tabs {
157
+ return &Tabs{activeIndex: 0}
158
+ }
159
+
160
+ // SetActive sets active tab by index
161
+ func (t *Tabs) SetActive(index int) {
162
+ t.activeIndex = index
163
+ }
164
+
165
+ // ActiveIndex returns current active index
166
+ func (t *Tabs) ActiveIndex() int {
167
+ return t.activeIndex
168
+ }
169
+
170
+ // Accordion represents an accordion component
171
+ type Accordion struct {
172
+ openIndices map[int]bool
173
+ }
174
+
175
+ // NewAccordion creates a new accordion
176
+ func NewAccordion() *Accordion {
177
+ return &Accordion{openIndices: make(map[int]bool)}
178
+ }
179
+
180
+ // Toggle toggles an accordion item
181
+ func (a *Accordion) Toggle(index int) {
182
+ a.openIndices[index] = !a.openIndices[index]
183
+ }
184
+
185
+ // Open opens an accordion item
186
+ func (a *Accordion) Open(index int) {
187
+ a.openIndices[index] = true
188
+ }
189
+
190
+ // Close closes an accordion item
191
+ func (a *Accordion) Close(index int) {
192
+ a.openIndices[index] = false
193
+ }
194
+
195
+ // OpenAll opens all items up to total
196
+ func (a *Accordion) OpenAll(total int) {
197
+ for i := 0; i < total; i++ {
198
+ a.openIndices[i] = true
199
+ }
200
+ }
201
+
202
+ // CloseAll closes all accordion items
203
+ func (a *Accordion) CloseAll() {
204
+ a.openIndices = make(map[int]bool)
205
+ }
206
+
207
+ // IsOpen returns whether item is open
208
+ func (a *Accordion) IsOpen(index int) bool {
209
+ return a.openIndices[index]
210
+ }
211
+
212
+ // Pagination represents a pagination component
213
+ type Pagination struct {
214
+ total int
215
+ current int
216
+ }
217
+
218
+ // NewPagination creates new pagination
219
+ func NewPagination(total, current int) *Pagination {
220
+ if current < 1 {
221
+ current = 1
222
+ }
223
+ if current > total {
224
+ current = total
225
+ }
226
+ return &Pagination{total: total, current: current}
227
+ }
228
+
229
+ // GoTo navigates to a specific page
230
+ func (p *Pagination) GoTo(page int) {
231
+ if page >= 1 && page <= p.total {
232
+ p.current = page
233
+ }
234
+ }
235
+
236
+ // Next goes to next page
237
+ func (p *Pagination) Next() {
238
+ if p.current < p.total {
239
+ p.current++
240
+ }
241
+ }
242
+
243
+ // Prev goes to previous page
244
+ func (p *Pagination) Prev() {
245
+ if p.current > 1 {
246
+ p.current--
247
+ }
248
+ }
249
+
250
+ // Current returns current page
251
+ func (p *Pagination) Current() int {
252
+ return p.current
253
+ }
254
+
255
+ // Total returns total pages
256
+ func (p *Pagination) Total() int {
257
+ return p.total
258
+ }
259
+
260
+ // CommandPaletteItem represents a command palette item
261
+ type CommandPaletteItem struct {
262
+ Title string
263
+ Kbd string
264
+ Action func()
265
+ }
266
+
267
+ // CommandPalette represents a command palette
268
+ type CommandPalette struct {
269
+ open bool
270
+ items []CommandPaletteItem
271
+ }
272
+
273
+ // NewCommandPalette creates a new command palette
274
+ func NewCommandPalette() *CommandPalette {
275
+ return &CommandPalette{items: make([]CommandPaletteItem, 0)}
276
+ }
277
+
278
+ // Open opens command palette
279
+ func (c *CommandPalette) Open() {
280
+ c.open = true
281
+ }
282
+
283
+ // Close closes command palette
284
+ func (c *CommandPalette) Close() {
285
+ c.open = false
286
+ }
287
+
288
+ // Toggle toggles command palette
289
+ func (c *CommandPalette) Toggle() {
290
+ c.open = !c.open
291
+ }
292
+
293
+ // IsOpen returns whether command palette is open
294
+ func (c *CommandPalette) IsOpen() bool {
295
+ return c.open
296
+ }
297
+
298
+ // SetItems sets command items
299
+ func (c *CommandPalette) SetItems(items []CommandPaletteItem) {
300
+ c.items = items
301
+ }
302
+
303
+ // Items returns all items
304
+ func (c *CommandPalette) Items() []CommandPaletteItem {
305
+ return c.items
306
+ }
307
+
308
+ // Execute executes item by index
309
+ func (c *CommandPalette) Execute(index int) {
310
+ if index >= 0 && index < len(c.items) && c.items[index].Action != nil {
311
+ c.items[index].Action()
312
+ c.Close()
313
+ }
314
+ }
315
+
316
+ // SearchItem represents a search result item
317
+ type SearchItem struct {
318
+ Title string
319
+ Subtitle string
320
+ Action func()
321
+ }
322
+
323
+ // Search represents a search component
324
+ type Search struct {
325
+ open bool
326
+ items []SearchItem
327
+ }
328
+
329
+ // NewSearch creates a new search
330
+ func NewSearch() *Search {
331
+ return &Search{items: make([]SearchItem, 0)}
332
+ }
333
+
334
+ // SetItems sets searchable items
335
+ func (s *Search) SetItems(items []SearchItem) {
336
+ s.items = items
337
+ }
338
+
339
+ // Filter filters items by query
340
+ func (s *Search) Filter(query string) []SearchItem {
341
+ var results []SearchItem
342
+ for _, item := range s.items {
343
+ results = append(results, item)
344
+ }
345
+ return results
346
+ }
347
+
348
+ // Open opens search results
349
+ func (s *Search) Open() {
350
+ s.open = true
351
+ }
352
+
353
+ // Close closes search results
354
+ func (s *Search) Close() {
355
+ s.open = false
356
+ }
357
+
358
+ // IsOpen returns whether search is open
359
+ func (s *Search) IsOpen() bool {
360
+ return s.open
361
+ }
362
+
363
+ // Items returns all items
364
+ func (s *Search) Items() []SearchItem {
365
+ return s.items
366
+ }
367
+
368
+ // Select selects and executes item by index
369
+ func (s *Search) Select(index int) {
370
+ if index >= 0 && index < len(s.items) && s.items[index].Action != nil {
371
+ s.items[index].Action()
372
+ s.Close()
373
+ }
374
+ }
375
+
376
+ // Init initializes all CronixUI components
377
+ func Init() {
378
+ fmt.Println("CronixUI", Version, "initialized")
379
+ }
@@ -0,0 +1,10 @@
1
+ [package]
2
+ name = "cronixui"
3
+ version = "1.0.2"
4
+ description = "CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography"
5
+ license = "GPL-3.0"
6
+ authors = ["CazyUndee"]
7
+ keywords = ["ui", "dark-mode", "design-system", "components"]
8
+
9
+ [lib]
10
+ path = "cronixui.go"
@@ -0,0 +1,35 @@
1
+ """
2
+ CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography
3
+ """
4
+
5
+ from .toast import Toast
6
+ from .toggle import Toggle
7
+ from .modal import Modal
8
+ from .dropdown import Dropdown
9
+ from .tabs import Tabs
10
+ from .accordion import Accordion
11
+ from .pagination import Pagination
12
+ from .command_palette import CommandPalette, CommandPaletteItem
13
+ from .search import Search, SearchItem
14
+ from .nav import Nav
15
+ from .core import init, query, query_all, create_el
16
+
17
+ __version__ = "1.0.4"
18
+ __all__ = [
19
+ "Toast",
20
+ "Toggle",
21
+ "Modal",
22
+ "Dropdown",
23
+ "Tabs",
24
+ "Accordion",
25
+ "Pagination",
26
+ "CommandPalette",
27
+ "CommandPaletteItem",
28
+ "Search",
29
+ "SearchItem",
30
+ "Nav",
31
+ "init",
32
+ "query",
33
+ "query_all",
34
+ "create_el",
35
+ ]
@@ -0,0 +1,29 @@
1
+ """Accordion component."""
2
+
3
+
4
+ class Accordion:
5
+ """Accordion component."""
6
+
7
+ def __init__(self, element=None):
8
+ """Initialize accordion on element."""
9
+ self._element = element
10
+ self._open_indices: list = []
11
+
12
+ def toggle(self, index: int) -> None:
13
+ """Toggle accordion item by index."""
14
+ if index in self._open_indices:
15
+ self._open_indices.remove(index)
16
+ else:
17
+ self._open_indices.append(index)
18
+
19
+ def open_all(self, total: int) -> None:
20
+ """Open all accordion items."""
21
+ self._open_indices = list(range(total))
22
+
23
+ def close_all(self) -> None:
24
+ """Close all accordion items."""
25
+ self._open_indices.clear()
26
+
27
+ def is_open(self, index: int) -> bool:
28
+ """Check if item is open."""
29
+ return index in self._open_indices
@@ -0,0 +1,53 @@
1
+ """Command palette component."""
2
+
3
+ from typing import Callable, Optional, List
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class CommandPaletteItem:
9
+ """Command palette item."""
10
+
11
+ title: str
12
+ kbd: Optional[str] = None
13
+ action: Optional[Callable] = None
14
+
15
+
16
+ class CommandPalette:
17
+ """Command palette component."""
18
+
19
+ def __init__(self, element=None):
20
+ """Initialize command palette on element."""
21
+ self._element = element
22
+ self._items: List[CommandPaletteItem] = []
23
+ self._open: bool = False
24
+
25
+ def open(self) -> None:
26
+ """Open command palette."""
27
+ self._open = True
28
+
29
+ def close(self) -> None:
30
+ """Close command palette."""
31
+ self._open = False
32
+
33
+ def toggle(self) -> None:
34
+ """Toggle command palette."""
35
+ self._open = not self._open
36
+
37
+ def is_open(self) -> bool:
38
+ """Check if command palette is open."""
39
+ return self._open
40
+
41
+ def set_items(self, items: List[CommandPaletteItem]) -> None:
42
+ """Set command items."""
43
+ self._items = items
44
+
45
+ def get_items(self) -> List[CommandPaletteItem]:
46
+ """Get all items."""
47
+ return self._items
48
+
49
+ def execute(self, index: int) -> None:
50
+ """Execute item by index."""
51
+ if 0 <= index < len(self._items) and self._items[index].action:
52
+ self._items[index].action()
53
+ self.close()
@@ -0,0 +1,48 @@
1
+ """Core CronixUI functions."""
2
+
3
+ from typing import Dict, Optional, List, Any
4
+
5
+
6
+ def init() -> None:
7
+ """Initialize all CronixUI components."""
8
+ pass
9
+
10
+
11
+ def query(selector: str) -> Optional[Any]:
12
+ """Query single element.
13
+
14
+ Args:
15
+ selector: CSS selector
16
+
17
+ Returns:
18
+ Element or None
19
+ """
20
+ pass
21
+
22
+
23
+ def query_all(selector: str) -> List[Any]:
24
+ """Query all matching elements.
25
+
26
+ Args:
27
+ selector: CSS selector
28
+
29
+ Returns:
30
+ List of elements
31
+ """
32
+ return []
33
+
34
+
35
+ def create_el(
36
+ tag: str, class_name: Optional[str] = None, attrs: Optional[Dict[str, str]] = None
37
+ ) -> Any:
38
+ """Create an element.
39
+
40
+ Args:
41
+ tag: HTML tag name
42
+ class_name: Optional CSS class name
43
+ attrs: Optional attributes dict
44
+
45
+ Returns:
46
+ Created element
47
+ """
48
+ pass
@@ -0,0 +1,26 @@
1
+ """Dropdown menu component."""
2
+
3
+
4
+ class Dropdown:
5
+ """Dropdown menu component."""
6
+
7
+ def __init__(self, element=None):
8
+ """Initialize dropdown on element."""
9
+ self._element = element
10
+ self._open: bool = False
11
+
12
+ def open(self) -> None:
13
+ """Open the dropdown."""
14
+ self._open = True
15
+
16
+ def close(self) -> None:
17
+ """Close the dropdown."""
18
+ self._open = False
19
+
20
+ def toggle(self) -> None:
21
+ """Toggle the dropdown."""
22
+ self._open = not self._open
23
+
24
+ def is_open(self) -> bool:
25
+ """Check if dropdown is open."""
26
+ return self._open
@@ -0,0 +1,22 @@
1
+ """Modal dialog component."""
2
+
3
+
4
+ class Modal:
5
+ """Modal dialog component."""
6
+
7
+ def __init__(self, element=None):
8
+ """Initialize modal on element."""
9
+ self._element = element
10
+ self._open: bool = False
11
+
12
+ def open(self) -> None:
13
+ """Open the modal."""
14
+ self._open = True
15
+
16
+ def close(self) -> None:
17
+ """Close the modal."""
18
+ self._open = False
19
+
20
+ def is_open(self) -> bool:
21
+ """Check if modal is open."""
22
+ return self._open
@@ -0,0 +1,31 @@
1
+ """Navigation component."""
2
+
3
+
4
+ class Nav:
5
+ """Navigation component."""
6
+
7
+ _instances = []
8
+
9
+ def __init__(self, element=None):
10
+ """Initialize navigation on element."""
11
+ self._element = element
12
+ self._active: str = ""
13
+ Nav._instances.append(self)
14
+
15
+ def set_active(self, item: str) -> None:
16
+ """Set active navigation item."""
17
+ self._active = item
18
+
19
+ def get_active(self) -> str:
20
+ """Get active navigation item."""
21
+ return self._active
22
+
23
+ @classmethod
24
+ def init(cls) -> None:
25
+ """Initialize all navigation components."""
26
+ pass
27
+
28
+ @classmethod
29
+ def get_all(cls) -> list:
30
+ """Get all navigation instances."""
31
+ return cls._instances
@@ -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,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
+ }
@@ -0,0 +1,70 @@
1
+ use std::fmt;
2
+
3
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
4
+ pub enum ToastType {
5
+ Success,
6
+ Error,
7
+ Warning,
8
+ Info,
9
+ }
10
+
11
+ impl fmt::Display for ToastType {
12
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13
+ match self {
14
+ ToastType::Success => write!(f, "success"),
15
+ ToastType::Error => write!(f, "error"),
16
+ ToastType::Warning => write!(f, "warning"),
17
+ ToastType::Info => write!(f, "info"),
18
+ }
19
+ }
20
+ }
21
+
22
+ #[derive(Debug, Clone)]
23
+ pub struct Toast {
24
+ pub title: Option<String>,
25
+ pub message: String,
26
+ pub toast_type: ToastType,
27
+ pub duration: u32,
28
+ }
29
+
30
+ impl Toast {
31
+ pub fn show(message: impl Into<String>) -> Self {
32
+ Self {
33
+ title: None,
34
+ message: message.into(),
35
+ toast_type: ToastType::Info,
36
+ duration: 4000,
37
+ }
38
+ }
39
+
40
+ pub fn title(mut self, title: impl Into<String>) -> Self {
41
+ self.title = Some(title.into());
42
+ self
43
+ }
44
+
45
+ pub fn toast_type(mut self, toast_type: ToastType) -> Self {
46
+ self.toast_type = toast_type;
47
+ self
48
+ }
49
+
50
+ pub fn duration(mut self, duration: u32) -> Self {
51
+ self.duration = duration;
52
+ self
53
+ }
54
+
55
+ pub fn success(message: impl Into<String>) -> Self {
56
+ Self::show(message).toast_type(ToastType::Success)
57
+ }
58
+
59
+ pub fn error(message: impl Into<String>) -> Self {
60
+ Self::show(message).toast_type(ToastType::Error)
61
+ }
62
+
63
+ pub fn warning(message: impl Into<String>) -> Self {
64
+ Self::show(message).toast_type(ToastType::Warning)
65
+ }
66
+
67
+ pub fn info(message: impl Into<String>) -> Self {
68
+ Self::show(message).toast_type(ToastType::Info)
69
+ }
70
+ }
@@ -0,0 +1,27 @@
1
+ pub struct Toggle {
2
+ on: bool,
3
+ }
4
+
5
+ impl Toggle {
6
+ pub fn new() -> Self {
7
+ Self { on: false }
8
+ }
9
+
10
+ pub fn toggle(&mut self) {
11
+ self.on = !self.on;
12
+ }
13
+
14
+ pub fn is_on(&self) -> bool {
15
+ self.on
16
+ }
17
+
18
+ pub fn set_on(&mut self, value: bool) {
19
+ self.on = value;
20
+ }
21
+ }
22
+
23
+ impl Default for Toggle {
24
+ fn default() -> Self {
25
+ Self::new()
26
+ }
27
+ }
@@ -0,0 +1,2 @@
1
+ export { default as CronixUI } from './cronixui.js';
2
+ export * from './cronixui.js';
@@ -0,0 +1,2 @@
1
+ export { default as CronixUI } from './cronixui.js';
2
+ export * from './cronixui.js';