cronixui 1.0.6 → 1.1.0

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 (129) hide show
  1. package/README.md +35 -5
  2. package/package.json +19 -5
  3. package/packages/go/cronixui/cronixui.go +784 -237
  4. package/packages/go/cronixui/go.mod +32 -0
  5. package/packages/go/cronixui/go.sum +666 -0
  6. package/packages/python/cronixui/__init__.py +59 -3
  7. package/packages/python/cronixui/alert.py +61 -0
  8. package/packages/python/cronixui/avatar.py +50 -0
  9. package/packages/python/cronixui/badge.py +46 -0
  10. package/packages/python/cronixui/button.py +64 -0
  11. package/packages/python/cronixui/card.py +62 -0
  12. package/packages/python/cronixui/form.py +255 -0
  13. package/packages/python/cronixui/layout.py +143 -0
  14. package/packages/python/cronixui/list.py +51 -0
  15. package/packages/python/cronixui/loading.py +36 -0
  16. package/packages/python/cronixui/progress.py +90 -0
  17. package/packages/python/cronixui/table.py +48 -0
  18. package/packages/python/cronixui/tooltip.py +28 -0
  19. package/packages/react/src/components/Accordion.tsx +82 -0
  20. package/packages/react/src/components/Alert.tsx +80 -0
  21. package/packages/react/src/components/Avatar.tsx +54 -0
  22. package/packages/react/src/components/Badge.tsx +32 -0
  23. package/packages/react/src/components/Breadcrumb.tsx +50 -0
  24. package/packages/react/src/components/Button.tsx +47 -0
  25. package/packages/react/src/components/Card.tsx +69 -0
  26. package/packages/react/src/components/Checkbox.tsx +30 -0
  27. package/packages/react/src/components/CommandPalette.tsx +131 -0
  28. package/packages/react/src/components/Container.tsx +26 -0
  29. package/packages/react/src/components/Dropdown.tsx +88 -0
  30. package/packages/react/src/components/FileInput.tsx +86 -0
  31. package/packages/react/src/components/Footer.tsx +36 -0
  32. package/packages/react/src/components/FormGroup.tsx +36 -0
  33. package/packages/react/src/components/Header.tsx +29 -0
  34. package/packages/react/src/components/Input.tsx +54 -0
  35. package/packages/react/src/components/List.tsx +55 -0
  36. package/packages/react/src/components/Modal.tsx +89 -0
  37. package/packages/react/src/components/Nav.tsx +63 -0
  38. package/packages/react/src/components/Pagination.tsx +107 -0
  39. package/packages/react/src/components/Progress.tsx +49 -0
  40. package/packages/react/src/components/Radio.tsx +64 -0
  41. package/packages/react/src/components/Search.tsx +95 -0
  42. package/packages/react/src/components/Select.tsx +41 -0
  43. package/packages/react/src/components/Sidebar.tsx +64 -0
  44. package/packages/react/src/components/Skeleton.tsx +39 -0
  45. package/packages/react/src/components/Slider.tsx +32 -0
  46. package/packages/react/src/components/Spinner.tsx +24 -0
  47. package/packages/react/src/components/Stack.tsx +69 -0
  48. package/packages/react/src/components/Stat.tsx +35 -0
  49. package/packages/react/src/components/Table.tsx +90 -0
  50. package/packages/react/src/components/Tabs.tsx +85 -0
  51. package/packages/react/src/components/Tag.tsx +30 -0
  52. package/packages/react/src/components/Textarea.tsx +21 -0
  53. package/packages/react/src/components/Toast.tsx +134 -0
  54. package/packages/react/src/components/Toggle.tsx +58 -0
  55. package/packages/react/src/components/Tooltip.tsx +31 -0
  56. package/packages/react/src/components/Typography.tsx +66 -0
  57. package/packages/react/src/index.ts +40 -0
  58. package/packages/react/src/styles.css +2039 -0
  59. package/packages/react/src/tokens/index.ts +94 -0
  60. package/packages/rust/cronixui/src/colors.rs +135 -0
  61. package/packages/rust/cronixui/src/components/accordion.rs +47 -0
  62. package/packages/rust/cronixui/src/components/alert.rs +95 -0
  63. package/packages/rust/cronixui/src/components/avatar.rs +85 -0
  64. package/packages/rust/cronixui/src/components/badge.rs +35 -0
  65. package/packages/rust/cronixui/src/components/breadcrumb.rs +58 -0
  66. package/packages/rust/cronixui/src/components/button.rs +70 -0
  67. package/packages/rust/cronixui/src/components/card.rs +259 -0
  68. package/packages/rust/cronixui/src/components/command_palette.rs +254 -0
  69. package/packages/rust/cronixui/src/components/dropdown.rs +179 -0
  70. package/packages/rust/cronixui/src/components/file_input.rs +74 -0
  71. package/packages/rust/cronixui/src/components/input.rs +21 -0
  72. package/packages/rust/cronixui/src/components/list.rs +38 -0
  73. package/packages/rust/cronixui/src/components/mod.rs +51 -0
  74. package/packages/rust/cronixui/src/{modal.rs → components/modal.rs} +15 -1
  75. package/packages/rust/cronixui/src/components/nav.rs +19 -0
  76. package/packages/rust/cronixui/src/{pagination.rs → components/pagination.rs} +14 -13
  77. package/packages/rust/cronixui/src/components/progress.rs +50 -0
  78. package/packages/rust/cronixui/src/components/search.rs +185 -0
  79. package/packages/rust/cronixui/src/components/skeleton.rs +63 -0
  80. package/packages/rust/cronixui/src/components/spinner.rs +21 -0
  81. package/packages/rust/cronixui/src/components/table.rs +56 -0
  82. package/packages/rust/cronixui/src/components/tabs.rs +43 -0
  83. package/packages/rust/cronixui/src/components/toast.rs +69 -0
  84. package/packages/rust/cronixui/src/{toggle.rs → components/toggle.rs} +7 -5
  85. package/packages/rust/cronixui/src/components/tooltip.rs +11 -0
  86. package/packages/rust/cronixui/src/lib.rs +111 -64
  87. package/packages/rust/cronixui/src/tokens.rs +97 -127
  88. package/packages/web/src/variables.css +81 -81
  89. package/packages/go/cronixui/tokens.go +0 -129
  90. package/packages/python/cronixui/pyproject.toml +0 -11
  91. package/packages/react/src/components/Accordion.jsx +0 -50
  92. package/packages/react/src/components/Alert.jsx +0 -62
  93. package/packages/react/src/components/Avatar.jsx +0 -34
  94. package/packages/react/src/components/Badge.jsx +0 -15
  95. package/packages/react/src/components/Breadcrumb.jsx +0 -27
  96. package/packages/react/src/components/Button.jsx +0 -21
  97. package/packages/react/src/components/Card.jsx +0 -23
  98. package/packages/react/src/components/Checkbox.jsx +0 -27
  99. package/packages/react/src/components/CommandPalette.jsx +0 -93
  100. package/packages/react/src/components/Dropdown.jsx +0 -48
  101. package/packages/react/src/components/FileInput.jsx +0 -44
  102. package/packages/react/src/components/Input.jsx +0 -22
  103. package/packages/react/src/components/List.jsx +0 -29
  104. package/packages/react/src/components/Modal.jsx +0 -65
  105. package/packages/react/src/components/Nav.jsx +0 -50
  106. package/packages/react/src/components/Pagination.jsx +0 -81
  107. package/packages/react/src/components/Progress.jsx +0 -23
  108. package/packages/react/src/components/Radio.jsx +0 -50
  109. package/packages/react/src/components/Search.jsx +0 -70
  110. package/packages/react/src/components/Select.jsx +0 -33
  111. package/packages/react/src/components/Skeleton.jsx +0 -15
  112. package/packages/react/src/components/Slider.jsx +0 -29
  113. package/packages/react/src/components/Spinner.jsx +0 -5
  114. package/packages/react/src/components/Stat.jsx +0 -19
  115. package/packages/react/src/components/Table.jsx +0 -48
  116. package/packages/react/src/components/Tabs.jsx +0 -65
  117. package/packages/react/src/components/Tag.jsx +0 -19
  118. package/packages/react/src/components/Textarea.jsx +0 -17
  119. package/packages/react/src/components/Toast.jsx +0 -78
  120. package/packages/react/src/components/Toggle.jsx +0 -34
  121. package/packages/react/src/components/Tooltip.jsx +0 -12
  122. package/packages/react/src/index.d.ts +0 -103
  123. package/packages/react/src/index.js +0 -33
  124. package/packages/rust/cronixui/src/accordion.rs +0 -49
  125. package/packages/rust/cronixui/src/command_palette.rs +0 -62
  126. package/packages/rust/cronixui/src/dropdown.rs +0 -31
  127. package/packages/rust/cronixui/src/search.rs +0 -49
  128. package/packages/rust/cronixui/src/tabs.rs +0 -23
  129. package/packages/rust/cronixui/src/toast.rs +0 -70
@@ -1,65 +0,0 @@
1
- import { useState } from 'react';
2
-
3
- export default function Tabs({
4
- defaultIndex = 0,
5
- index: controlledIndex,
6
- onChange,
7
- children,
8
- className = ''
9
- }) {
10
- const [internalIndex, setInternalIndex] = useState(defaultIndex);
11
- const activeIndex = controlledIndex !== undefined ? controlledIndex : internalIndex;
12
-
13
- const handleTabClick = (idx) => {
14
- if (onChange) {
15
- onChange(idx);
16
- } else {
17
- setInternalIndex(idx);
18
- }
19
- };
20
-
21
- const tabs = [];
22
- const panels = [];
23
-
24
- children.forEach((child) => {
25
- if (child.type?.displayName === 'Tab') {
26
- tabs.push(child);
27
- } else if (child.type?.displayName === 'TabPanel') {
28
- panels.push(child);
29
- }
30
- });
31
-
32
- return (
33
- <div className={className}>
34
- <div className="cn-tabs">
35
- {tabs.map((tab, idx) => (
36
- <div
37
- key={idx}
38
- className={`cn-tab ${activeIndex === idx ? 'cn-tab-active' : ''}`}
39
- onClick={() => handleTabClick(idx)}
40
- >
41
- {tab.props.children}
42
- </div>
43
- ))}
44
- </div>
45
- {panels.map((panel, idx) => (
46
- <div
47
- key={idx}
48
- className={`cn-tab-panel ${activeIndex === idx ? 'cn-tab-panel-active' : ''}`}
49
- >
50
- {panel.props.children}
51
- </div>
52
- ))}
53
- </div>
54
- );
55
- }
56
-
57
- export function Tab({ children }) {
58
- return children;
59
- }
60
- Tab.displayName = 'Tab';
61
-
62
- export function TabPanel({ children }) {
63
- return children;
64
- }
65
- TabPanel.displayName = 'TabPanel';
@@ -1,19 +0,0 @@
1
- export default function Tag({
2
- children,
3
- onRemove,
4
- className = ''
5
- }) {
6
- return (
7
- <div className={`cn-tag ${className}`}>
8
- <span>{children}</span>
9
- {onRemove && (
10
- <button className="cn-tag-remove" onClick={onRemove}>
11
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
12
- <line x1="18" y1="6" x2="6" y2="18"></line>
13
- <line x1="6" y1="6" x2="18" y2="18"></line>
14
- </svg>
15
- </button>
16
- )}
17
- </div>
18
- );
19
- }
@@ -1,17 +0,0 @@
1
- import { forwardRef } from 'react';
2
-
3
- const Textarea = forwardRef(function Textarea({
4
- error = false,
5
- className = '',
6
- ...props
7
- }, ref) {
8
- return (
9
- <textarea
10
- ref={ref}
11
- className={`cn-input cn-textarea ${error ? 'cn-input-error' : ''} ${className}`}
12
- {...props}
13
- />
14
- );
15
- });
16
-
17
- export default Textarea;
@@ -1,78 +0,0 @@
1
- import { useState, useEffect, useRef } from 'react';
2
-
3
- function ToastContainer() {
4
- return <div className="cn-toast-container" />;
5
- }
6
-
7
- function ToastItem({ toast, onRemove }) {
8
- useEffect(() => {
9
- if (toast.duration > 0) {
10
- const timer = setTimeout(() => onRemove(toast.id), toast.duration);
11
- return () => clearTimeout(timer);
12
- }
13
- }, [toast.id, toast.duration, onRemove]);
14
-
15
- const icons = {
16
- success: '<polyline points="20 6 9 17 4 12"></polyline>',
17
- error: '<circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line>',
18
- warning: '<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line>',
19
- info: '<circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line>'
20
- };
21
-
22
- return (
23
- <div className={`cn-toast cn-toast-${toast.type}`}>
24
- <div className="cn-alert-icon">
25
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" dangerouslySetInnerHTML={{ __html: icons[toast.type] }} />
26
- </div>
27
- <div className="cn-alert-content">
28
- {toast.title && <div className="cn-alert-title">{toast.title}</div>}
29
- {toast.message && <div className="cn-alert-message">{toast.message}</div>}
30
- </div>
31
- {toast.closable && (
32
- <button className="cn-alert-close" onClick={() => onRemove(toast.id)}>
33
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" width="16" height="16">
34
- <line x1="18" y1="6" x2="6" y2="18"></line>
35
- <line x1="6" y1="6" x2="18" y2="18"></line>
36
- </svg>
37
- </button>
38
- )}
39
- </div>
40
- );
41
- }
42
-
43
- export default function Toast({ toasts = [], onRemove }) {
44
- return (
45
- <div className="cn-toast-container">
46
- {toasts.map((toast) => (
47
- <ToastItem key={toast.id} toast={toast} onRemove={onRemove} />
48
- ))}
49
- </div>
50
- );
51
- }
52
-
53
- export function useToast() {
54
- const [toasts, setToasts] = useState([]);
55
- const idRef = useRef(0);
56
-
57
- const addToast = (options) => {
58
- const id = ++idRef.current;
59
- const toast = { id, duration: 4000, closable: true, type: 'info', ...options };
60
- setToasts((prev) => [...prev, toast]);
61
- return id;
62
- };
63
-
64
- const removeToast = (id) => {
65
- setToasts((prev) => prev.filter((t) => t.id !== id));
66
- };
67
-
68
- const toast = {
69
- success: (message, title) => addToast({ message, title, type: 'success' }),
70
- error: (message, title) => addToast({ message, title, type: 'error' }),
71
- warning: (message, title) => addToast({ message, title, type: 'warning' }),
72
- info: (message, title) => addToast({ message, title, type: 'info' }),
73
- show: addToast,
74
- remove: removeToast
75
- };
76
-
77
- return { toasts, toast, removeToast };
78
- }
@@ -1,34 +0,0 @@
1
- import { useState } from 'react';
2
-
3
- export default function Toggle({
4
- on = false,
5
- onChange,
6
- disabled = false,
7
- size = 'md',
8
- className = '',
9
- ...props
10
- }) {
11
- const [internalOn, setInternalOn] = useState(on);
12
- const isOn = onChange !== undefined ? on : internalOn;
13
-
14
- const handleToggle = () => {
15
- if (disabled) return;
16
- if (onChange) {
17
- onChange(!on);
18
- } else {
19
- setInternalOn(!internalOn);
20
- }
21
- };
22
-
23
- const sizeClass = size === 'sm' ? 'cn-toggle-sm' : size === 'lg' ? 'cn-toggle-lg' : '';
24
-
25
- return (
26
- <div
27
- className={`cn-toggle ${isOn ? 'on' : ''} ${sizeClass} ${disabled ? 'disabled' : ''} ${className}`}
28
- onClick={handleToggle}
29
- {...props}
30
- >
31
- <div className="cn-toggle-box"></div>
32
- </div>
33
- );
34
- }
@@ -1,12 +0,0 @@
1
- export default function Tooltip({
2
- children,
3
- content,
4
- className = ''
5
- }) {
6
- return (
7
- <div className={`cn-tooltip ${className}`}>
8
- {children}
9
- <div className="cn-tooltip-content">{content}</div>
10
- </div>
11
- );
12
- }
@@ -1,103 +0,0 @@
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;
@@ -1,33 +0,0 @@
1
- import 'CronixUI-web/dist/CronixUI.css';
2
-
3
- export { default as Toggle } from './components/Toggle';
4
- export { default as Button } from './components/Button';
5
- export { default as Input } from './components/Input';
6
- export { default as Textarea } from './components/Textarea';
7
- export { default as Checkbox } from './components/Checkbox';
8
- export { default as Radio, RadioGroup } from './components/Radio';
9
- export { default as Select } from './components/Select';
10
- export { default as Slider } from './components/Slider';
11
- export { default as FileInput } from './components/FileInput';
12
- export { default as Modal } from './components/Modal';
13
- export { default as Alert } from './components/Alert';
14
- export { default as Toast, useToast } from './components/Toast';
15
- export { default as Tabs, Tab, TabPanel } from './components/Tabs';
16
- export { default as Accordion, AccordionItem } from './components/Accordion';
17
- export { default as Dropdown, DropdownItem } from './components/Dropdown';
18
- export { default as Nav, NavItem } from './components/Nav';
19
- export { default as Badge } from './components/Badge';
20
- export { default as Tag } from './components/Tag';
21
- export { default as Card } from './components/Card';
22
- export { default as Avatar, AvatarGroup } from './components/Avatar';
23
- export { default as Progress } from './components/Progress';
24
- export { default as Spinner } from './components/Spinner';
25
- export { default as Skeleton } from './components/Skeleton';
26
- export { default as Tooltip } from './components/Tooltip';
27
- export { default as Stat } from './components/Stat';
28
- export { default as Pagination } from './components/Pagination';
29
- export { default as Table } from './components/Table';
30
- export { default as List, ListItem } from './components/List';
31
- export { default as Breadcrumb, BreadcrumbItem } from './components/Breadcrumb';
32
- export { default as Search } from './components/Search';
33
- export { default as CommandPalette } from './components/CommandPalette';
@@ -1,49 +0,0 @@
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
- }
@@ -1,62 +0,0 @@
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
- }
@@ -1,31 +0,0 @@
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
- }
@@ -1,49 +0,0 @@
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
- }
@@ -1,23 +0,0 @@
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
- }
@@ -1,70 +0,0 @@
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
- }