cronixui 1.0.6 → 1.1.1

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 (169) hide show
  1. package/README.md +20 -5
  2. package/package.json +20 -5
  3. package/packages/flutter/lib/cronixui.dart +41 -0
  4. package/packages/flutter/lib/src/tokens/colors.dart +34 -0
  5. package/packages/flutter/lib/src/tokens/spacing.dart +54 -0
  6. package/packages/flutter/lib/src/tokens/theme.dart +174 -0
  7. package/packages/flutter/lib/src/widgets/cn_accordion.dart +254 -0
  8. package/packages/flutter/lib/src/widgets/cn_alert.dart +137 -0
  9. package/packages/flutter/lib/src/widgets/cn_avatar.dart +98 -0
  10. package/packages/flutter/lib/src/widgets/cn_badge.dart +80 -0
  11. package/packages/flutter/lib/src/widgets/cn_breadcrumb.dart +88 -0
  12. package/packages/flutter/lib/src/widgets/cn_button.dart +137 -0
  13. package/packages/flutter/lib/src/widgets/cn_card.dart +99 -0
  14. package/packages/flutter/lib/src/widgets/cn_checkbox.dart +77 -0
  15. package/packages/flutter/lib/src/widgets/cn_command_palette.dart +299 -0
  16. package/packages/flutter/lib/src/widgets/cn_container.dart +131 -0
  17. package/packages/flutter/lib/src/widgets/cn_dropdown.dart +149 -0
  18. package/packages/flutter/lib/src/widgets/cn_file_input.dart +113 -0
  19. package/packages/flutter/lib/src/widgets/cn_footer.dart +108 -0
  20. package/packages/flutter/lib/src/widgets/cn_header.dart +173 -0
  21. package/packages/flutter/lib/src/widgets/cn_input.dart +142 -0
  22. package/packages/flutter/lib/src/widgets/cn_list.dart +150 -0
  23. package/packages/flutter/lib/src/widgets/cn_modal.dart +213 -0
  24. package/packages/flutter/lib/src/widgets/cn_nav.dart +157 -0
  25. package/packages/flutter/lib/src/widgets/cn_pagination.dart +193 -0
  26. package/packages/flutter/lib/src/widgets/cn_progress.dart +146 -0
  27. package/packages/flutter/lib/src/widgets/cn_radio.dart +133 -0
  28. package/packages/flutter/lib/src/widgets/cn_search.dart +183 -0
  29. package/packages/flutter/lib/src/widgets/cn_select.dart +244 -0
  30. package/packages/flutter/lib/src/widgets/cn_sidebar.dart +207 -0
  31. package/packages/flutter/lib/src/widgets/cn_skeleton.dart +136 -0
  32. package/packages/flutter/lib/src/widgets/cn_slider.dart +141 -0
  33. package/packages/flutter/lib/src/widgets/cn_spinner.dart +85 -0
  34. package/packages/flutter/lib/src/widgets/cn_stat.dart +135 -0
  35. package/packages/flutter/lib/src/widgets/cn_table.dart +136 -0
  36. package/packages/flutter/lib/src/widgets/cn_tabs.dart +229 -0
  37. package/packages/flutter/lib/src/widgets/cn_tag.dart +185 -0
  38. package/packages/flutter/lib/src/widgets/cn_textarea.dart +143 -0
  39. package/packages/flutter/lib/src/widgets/cn_toast.dart +121 -0
  40. package/packages/flutter/lib/src/widgets/cn_toggle.dart +78 -0
  41. package/packages/flutter/lib/src/widgets/cn_tooltip.dart +118 -0
  42. package/packages/flutter/pubspec.yaml +20 -0
  43. package/packages/go/cronixui/cronixui.go +784 -237
  44. package/packages/go/cronixui/go.mod +32 -0
  45. package/packages/go/cronixui/go.sum +666 -0
  46. package/packages/python/cronixui/__init__.py +59 -3
  47. package/packages/python/cronixui/alert.py +61 -0
  48. package/packages/python/cronixui/avatar.py +50 -0
  49. package/packages/python/cronixui/badge.py +46 -0
  50. package/packages/python/cronixui/button.py +64 -0
  51. package/packages/python/cronixui/card.py +62 -0
  52. package/packages/python/cronixui/form.py +255 -0
  53. package/packages/python/cronixui/layout.py +143 -0
  54. package/packages/python/cronixui/list.py +51 -0
  55. package/packages/python/cronixui/loading.py +36 -0
  56. package/packages/python/cronixui/progress.py +90 -0
  57. package/packages/python/cronixui/table.py +48 -0
  58. package/packages/python/cronixui/tooltip.py +28 -0
  59. package/packages/react/src/components/Accordion.tsx +82 -0
  60. package/packages/react/src/components/Alert.tsx +80 -0
  61. package/packages/react/src/components/Avatar.tsx +54 -0
  62. package/packages/react/src/components/Badge.tsx +32 -0
  63. package/packages/react/src/components/Breadcrumb.tsx +50 -0
  64. package/packages/react/src/components/Button.tsx +47 -0
  65. package/packages/react/src/components/Card.tsx +69 -0
  66. package/packages/react/src/components/Checkbox.tsx +30 -0
  67. package/packages/react/src/components/CommandPalette.tsx +131 -0
  68. package/packages/react/src/components/Container.tsx +26 -0
  69. package/packages/react/src/components/Dropdown.tsx +88 -0
  70. package/packages/react/src/components/FileInput.tsx +86 -0
  71. package/packages/react/src/components/Footer.tsx +36 -0
  72. package/packages/react/src/components/FormGroup.tsx +36 -0
  73. package/packages/react/src/components/Header.tsx +29 -0
  74. package/packages/react/src/components/Input.tsx +54 -0
  75. package/packages/react/src/components/List.tsx +55 -0
  76. package/packages/react/src/components/Modal.tsx +89 -0
  77. package/packages/react/src/components/Nav.tsx +63 -0
  78. package/packages/react/src/components/Pagination.tsx +107 -0
  79. package/packages/react/src/components/Progress.tsx +49 -0
  80. package/packages/react/src/components/Radio.tsx +64 -0
  81. package/packages/react/src/components/Search.tsx +95 -0
  82. package/packages/react/src/components/Select.tsx +41 -0
  83. package/packages/react/src/components/Sidebar.tsx +64 -0
  84. package/packages/react/src/components/Skeleton.tsx +39 -0
  85. package/packages/react/src/components/Slider.tsx +32 -0
  86. package/packages/react/src/components/Spinner.tsx +24 -0
  87. package/packages/react/src/components/Stack.tsx +69 -0
  88. package/packages/react/src/components/Stat.tsx +35 -0
  89. package/packages/react/src/components/Table.tsx +90 -0
  90. package/packages/react/src/components/Tabs.tsx +85 -0
  91. package/packages/react/src/components/Tag.tsx +30 -0
  92. package/packages/react/src/components/Textarea.tsx +21 -0
  93. package/packages/react/src/components/Toast.tsx +134 -0
  94. package/packages/react/src/components/Toggle.tsx +58 -0
  95. package/packages/react/src/components/Tooltip.tsx +31 -0
  96. package/packages/react/src/components/Typography.tsx +66 -0
  97. package/packages/react/src/index.ts +40 -0
  98. package/packages/react/src/styles.css +2039 -0
  99. package/packages/react/src/tokens/index.ts +94 -0
  100. package/packages/rust/cronixui/src/colors.rs +135 -0
  101. package/packages/rust/cronixui/src/components/accordion.rs +47 -0
  102. package/packages/rust/cronixui/src/components/alert.rs +95 -0
  103. package/packages/rust/cronixui/src/components/avatar.rs +85 -0
  104. package/packages/rust/cronixui/src/components/badge.rs +35 -0
  105. package/packages/rust/cronixui/src/components/breadcrumb.rs +58 -0
  106. package/packages/rust/cronixui/src/components/button.rs +70 -0
  107. package/packages/rust/cronixui/src/components/card.rs +259 -0
  108. package/packages/rust/cronixui/src/components/command_palette.rs +254 -0
  109. package/packages/rust/cronixui/src/components/dropdown.rs +179 -0
  110. package/packages/rust/cronixui/src/components/file_input.rs +74 -0
  111. package/packages/rust/cronixui/src/components/input.rs +21 -0
  112. package/packages/rust/cronixui/src/components/list.rs +38 -0
  113. package/packages/rust/cronixui/src/components/mod.rs +51 -0
  114. package/packages/rust/cronixui/src/{modal.rs → components/modal.rs} +15 -1
  115. package/packages/rust/cronixui/src/components/nav.rs +19 -0
  116. package/packages/rust/cronixui/src/{pagination.rs → components/pagination.rs} +14 -13
  117. package/packages/rust/cronixui/src/components/progress.rs +50 -0
  118. package/packages/rust/cronixui/src/components/search.rs +185 -0
  119. package/packages/rust/cronixui/src/components/skeleton.rs +63 -0
  120. package/packages/rust/cronixui/src/components/spinner.rs +21 -0
  121. package/packages/rust/cronixui/src/components/table.rs +56 -0
  122. package/packages/rust/cronixui/src/components/tabs.rs +43 -0
  123. package/packages/rust/cronixui/src/components/toast.rs +69 -0
  124. package/packages/rust/cronixui/src/{toggle.rs → components/toggle.rs} +7 -5
  125. package/packages/rust/cronixui/src/components/tooltip.rs +11 -0
  126. package/packages/rust/cronixui/src/lib.rs +111 -64
  127. package/packages/rust/cronixui/src/tokens.rs +97 -127
  128. package/packages/web/src/variables.css +81 -81
  129. package/packages/go/cronixui/tokens.go +0 -129
  130. package/packages/python/cronixui/pyproject.toml +0 -11
  131. package/packages/react/src/components/Accordion.jsx +0 -50
  132. package/packages/react/src/components/Alert.jsx +0 -62
  133. package/packages/react/src/components/Avatar.jsx +0 -34
  134. package/packages/react/src/components/Badge.jsx +0 -15
  135. package/packages/react/src/components/Breadcrumb.jsx +0 -27
  136. package/packages/react/src/components/Button.jsx +0 -21
  137. package/packages/react/src/components/Card.jsx +0 -23
  138. package/packages/react/src/components/Checkbox.jsx +0 -27
  139. package/packages/react/src/components/CommandPalette.jsx +0 -93
  140. package/packages/react/src/components/Dropdown.jsx +0 -48
  141. package/packages/react/src/components/FileInput.jsx +0 -44
  142. package/packages/react/src/components/Input.jsx +0 -22
  143. package/packages/react/src/components/List.jsx +0 -29
  144. package/packages/react/src/components/Modal.jsx +0 -65
  145. package/packages/react/src/components/Nav.jsx +0 -50
  146. package/packages/react/src/components/Pagination.jsx +0 -81
  147. package/packages/react/src/components/Progress.jsx +0 -23
  148. package/packages/react/src/components/Radio.jsx +0 -50
  149. package/packages/react/src/components/Search.jsx +0 -70
  150. package/packages/react/src/components/Select.jsx +0 -33
  151. package/packages/react/src/components/Skeleton.jsx +0 -15
  152. package/packages/react/src/components/Slider.jsx +0 -29
  153. package/packages/react/src/components/Spinner.jsx +0 -5
  154. package/packages/react/src/components/Stat.jsx +0 -19
  155. package/packages/react/src/components/Table.jsx +0 -48
  156. package/packages/react/src/components/Tabs.jsx +0 -65
  157. package/packages/react/src/components/Tag.jsx +0 -19
  158. package/packages/react/src/components/Textarea.jsx +0 -17
  159. package/packages/react/src/components/Toast.jsx +0 -78
  160. package/packages/react/src/components/Toggle.jsx +0 -34
  161. package/packages/react/src/components/Tooltip.jsx +0 -12
  162. package/packages/react/src/index.d.ts +0 -103
  163. package/packages/react/src/index.js +0 -33
  164. package/packages/rust/cronixui/src/accordion.rs +0 -49
  165. package/packages/rust/cronixui/src/command_palette.rs +0 -62
  166. package/packages/rust/cronixui/src/dropdown.rs +0 -31
  167. package/packages/rust/cronixui/src/search.rs +0 -49
  168. package/packages/rust/cronixui/src/tabs.rs +0 -23
  169. package/packages/rust/cronixui/src/toast.rs +0 -70
package/README.md CHANGED
@@ -10,6 +10,15 @@ A multi-platform, multi-language UI toolkit with a dark theme, crimson accents,
10
10
  npm install cronixui
11
11
  ```
12
12
 
13
+ ### React, Vue, Svelte, Solid
14
+
15
+ ```bash
16
+ npm install @cronixui/react
17
+ npm install @cronixui/vue
18
+ npm install @cronixui/svelte
19
+ npm install @cronixui/solid
20
+ ```
21
+
13
22
  ### Python
14
23
 
15
24
  ```bash
@@ -26,14 +35,20 @@ go get github.com/CazyUndee/CronixUI/packages/go/cronixui
26
35
 
27
36
  ```toml
28
37
  [dependencies]
29
- cronixui = "1.0.2"
38
+ cronixui = "1.1.1"
39
+ ```
40
+
41
+ ### Flutter
42
+
43
+ ```bash
44
+ flutter pub add cronixui
30
45
  ```
31
46
 
32
47
  ### CDN
33
48
 
34
49
  ```html
35
- <link rel="stylesheet" href="https://unpkg.com/cronixui@1.0.2/packages/web/dist/cronixui.css">
36
- <script src="https://unpkg.com/cronixui@1.0.2/packages/web/dist/cronixui.js"></script>
50
+ <link rel="stylesheet" href="https://unpkg.com/cronixui@1.1.1/packages/web/dist/cronixui.css">
51
+ <script src="https://unpkg.com/cronixui@1.1.1/packages/web/dist/cronixui.js"></script>
37
52
  ```
38
53
 
39
54
  ## Quick Start (Web)
@@ -45,14 +60,14 @@ cronixui = "1.0.2"
45
60
  <meta charset="UTF-8">
46
61
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
47
62
  <title>My App</title>
48
- <link rel="stylesheet" href="https://unpkg.com/cronixui@1.0.2/packages/web/dist/cronixui.css">
63
+ <link rel="stylesheet" href="https://unpkg.com/cronixui@1.1.1/packages/web/dist/cronixui.css">
49
64
  </head>
50
65
  <body>
51
66
  <div class="cn-container">
52
67
  <h1 class="cn-h1">Hello, CronixUI!</h1>
53
68
  <button class="cn-btn cn-btn-primary">Get Started</button>
54
69
  </div>
55
- <script src="https://unpkg.com/cronixui@1.0.2/packages/web/dist/cronixui.js"></script>
70
+ <script src="https://unpkg.com/cronixui@1.1.1/packages/web/dist/cronixui.js"></script>
56
71
  </body>
57
72
  </html>
58
73
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cronixui",
3
- "version": "1.0.6",
3
+ "version": "1.1.1",
4
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",
@@ -30,9 +30,13 @@
30
30
  "import": "./packages/react/src/index.js",
31
31
  "types": "./packages/react/src/index.d.ts"
32
32
  },
33
+ "./typescript": {
34
+ "import": "./packages/typescript/dist/index.js",
35
+ "types": "./packages/typescript/dist/index.d.ts"
36
+ },
33
37
  "./tokens": {
34
- "import": "./packages/web/src/tokens.ts",
35
- "types": "./packages/web/src/tokens.ts"
38
+ "import": "./packages/typescript/dist/tokens.js",
39
+ "types": "./packages/typescript/dist/tokens.d.ts"
36
40
  },
37
41
  "./css": "./packages/web/dist/cronixui.css",
38
42
  "./css/min": "./packages/web/dist/cronixui.min.css",
@@ -43,14 +47,25 @@
43
47
  "packages/web/dist/",
44
48
  "packages/web/src/",
45
49
  "packages/react/src/",
50
+ "packages/typescript/dist/",
46
51
  "packages/win/CronixUI.WinUI/",
47
52
  "packages/python/cronixui/",
48
53
  "packages/go/cronixui/",
49
54
  "packages/rust/cronixui/src/",
55
+ "packages/flutter/",
50
56
  "README.md"
51
57
  ],
52
58
  "scripts": {
53
- "build": "node packages/web/scripts/build.js",
54
- "dev": "npx live-server packages/web/demo"
59
+ "build": "pnpm -r build",
60
+ "build:web": "node packages/web/scripts/build.js",
61
+ "build:ts": "cd packages/typescript && npm run build",
62
+ "dev": "npx live-server packages/web/demo",
63
+ "gen": "tsx packages/spec/generate.ts",
64
+ "gen:all": "tsx packages/spec/generate.ts --all",
65
+ "docs:dev": "cd docs && pnpm dev",
66
+ "docs:build": "cd docs && pnpm build",
67
+ "lint": "pnpm -r lint",
68
+ "test": "pnpm -r test",
69
+ "publish:dry": "pnpm -r publish --dry-run --access public"
55
70
  }
56
71
  }
@@ -0,0 +1,41 @@
1
+ library cronixui;
2
+
3
+ export 'src/tokens/colors.dart';
4
+ export 'src/tokens/spacing.dart';
5
+ export 'src/tokens/theme.dart';
6
+
7
+ export 'src/widgets/cn_button.dart';
8
+ export 'src/widgets/cn_card.dart';
9
+ export 'src/widgets/cn_badge.dart';
10
+ export 'src/widgets/cn_input.dart';
11
+ export 'src/widgets/cn_textarea.dart';
12
+ export 'src/widgets/cn_checkbox.dart';
13
+ export 'src/widgets/cn_radio.dart';
14
+ export 'src/widgets/cn_select.dart';
15
+ export 'src/widgets/cn_slider.dart';
16
+ export 'src/widgets/cn_toggle.dart';
17
+ export 'src/widgets/cn_file_input.dart';
18
+ export 'src/widgets/cn_avatar.dart';
19
+ export 'src/widgets/cn_alert.dart';
20
+ export 'src/widgets/cn_spinner.dart';
21
+ export 'src/widgets/cn_skeleton.dart';
22
+ export 'src/widgets/cn_progress.dart';
23
+ export 'src/widgets/cn_table.dart';
24
+ export 'src/widgets/cn_list.dart';
25
+ export 'src/widgets/cn_tooltip.dart';
26
+ export 'src/widgets/cn_stat.dart';
27
+ export 'src/widgets/cn_modal.dart';
28
+ export 'src/widgets/cn_dropdown.dart';
29
+ export 'src/widgets/cn_tabs.dart';
30
+ export 'src/widgets/cn_accordion.dart';
31
+ export 'src/widgets/cn_toast.dart';
32
+ export 'src/widgets/cn_pagination.dart';
33
+ export 'src/widgets/cn_search.dart';
34
+ export 'src/widgets/cn_command_palette.dart';
35
+ export 'src/widgets/cn_nav.dart';
36
+ export 'src/widgets/cn_breadcrumb.dart';
37
+ export 'src/widgets/cn_container.dart';
38
+ export 'src/widgets/cn_header.dart';
39
+ export 'src/widgets/cn_sidebar.dart';
40
+ export 'src/widgets/cn_footer.dart';
41
+ export 'src/widgets/cn_tag.dart';
@@ -0,0 +1,34 @@
1
+ import 'package:flutter/material.dart';
2
+
3
+ class CronixColors {
4
+ static const Color background = Color(0xFF0a0a0a);
5
+ static const Color text = Color(0xFFf0ede8);
6
+ static const Color accent = Color(0xFF6b2323);
7
+
8
+ static const Color backgroundLight = Color(0xFF1a1a1a);
9
+ static const Color backgroundDark = Color(0xFF050505);
10
+ static const Color surface = Color(0xFF141414);
11
+ static const Color surfaceLight = Color(0xFF1f1f1f);
12
+
13
+ static const Color textSecondary = Color(0xFFa0a0a0);
14
+ static const Color textMuted = Color(0xFF666666);
15
+
16
+ static const Color accentLight = Color(0xFF8b3333);
17
+ static const Color accentDark = Color(0xFF4b1a1a);
18
+
19
+ static const Color success = Color(0xFF22c55e);
20
+ static const Color successDark = Color(0xFF16a34a);
21
+ static const Color warning = Color(0xFFeab308);
22
+ static const Color warningDark = Color(0xFFca8a04);
23
+ static const Color error = Color(0xFFef4444);
24
+ static const Color errorDark = Color(0xFFdc2626);
25
+ static const Color info = Color(0xFF3b82f6);
26
+ static const Color infoDark = Color(0xFF2563eb);
27
+
28
+ static const Color border = Color(0xFF2a2a2a);
29
+ static const Color borderLight = Color(0xFF3a3a3a);
30
+ static const Color divider = Color(0xFF222222);
31
+
32
+ static const Color shimmerBase = Color(0xFF1a1a1a);
33
+ static const Color shimmerHighlight = Color(0xFF2a2a2a);
34
+ }
@@ -0,0 +1,54 @@
1
+ import 'package:flutter/material.dart';
2
+
3
+ class CronixSpacing {
4
+ static const double xxs = 2.0;
5
+ static const double xs = 4.0;
6
+ static const double sm = 8.0;
7
+ static const double md = 16.0;
8
+ static const double lg = 24.0;
9
+ static const double xl = 32.0;
10
+ static const double xxl = 48.0;
11
+ static const double xxxl = 64.0;
12
+
13
+ static const EdgeInsets paddingNone = EdgeInsets.zero;
14
+ static const EdgeInsets paddingXS = EdgeInsets.all(xs);
15
+ static const EdgeInsets paddingSM = EdgeInsets.all(sm);
16
+ static const EdgeInsets paddingMD = EdgeInsets.all(md);
17
+ static const EdgeInsets paddingLG = EdgeInsets.all(lg);
18
+ static const EdgeInsets paddingXL = EdgeInsets.all(xl);
19
+
20
+ static const EdgeInsets paddingHorizontalSM = EdgeInsets.symmetric(horizontal: sm);
21
+ static const EdgeInsets paddingHorizontalMD = EdgeInsets.symmetric(horizontal: md);
22
+ static const EdgeInsets paddingHorizontalLG = EdgeInsets.symmetric(horizontal: lg);
23
+
24
+ static const EdgeInsets paddingVerticalSM = EdgeInsets.symmetric(vertical: sm);
25
+ static const EdgeInsets paddingVerticalMD = EdgeInsets.symmetric(vertical: md);
26
+ static const EdgeInsets paddingVerticalLG = EdgeInsets.symmetric(vertical: lg);
27
+
28
+ static const SizedBox hXS = SizedBox(width: xs);
29
+ static const SizedBox hSM = SizedBox(width: sm);
30
+ static const SizedBox hMD = SizedBox(width: md);
31
+ static const SizedBox hLG = SizedBox(width: lg);
32
+ static const SizedBox hXL = SizedBox(width: xl);
33
+
34
+ static const SizedBox vXS = SizedBox(height: xs);
35
+ static const SizedBox vSM = SizedBox(height: sm);
36
+ static const SizedBox vMD = SizedBox(height: md);
37
+ static const SizedBox vLG = SizedBox(height: lg);
38
+ static const SizedBox vXL = SizedBox(height: xl);
39
+ }
40
+
41
+ class CronixRadius {
42
+ static const double none = 0;
43
+ static const double sm = 4.0;
44
+ static const double md = 8.0;
45
+ static const double lg = 12.0;
46
+ static const double xl = 16.0;
47
+ static const double full = 9999.0;
48
+
49
+ static const BorderRadius radiusSM = BorderRadius.all(Radius.circular(sm));
50
+ static const BorderRadius radiusMD = BorderRadius.all(Radius.circular(md));
51
+ static const BorderRadius radiusLG = BorderRadius.all(Radius.circular(lg));
52
+ static const BorderRadius radiusXL = BorderRadius.all(Radius.circular(xl));
53
+ static const BorderRadius radiusFull = BorderRadius.all(Radius.circular(full));
54
+ }
@@ -0,0 +1,174 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'colors.dart';
3
+ import 'spacing.dart';
4
+
5
+ class CronixTheme {
6
+ static ThemeData get dark {
7
+ return ThemeData(
8
+ useMaterial3: true,
9
+ brightness: Brightness.dark,
10
+ scaffoldBackgroundColor: CronixColors.background,
11
+ colorScheme: ColorScheme.dark(
12
+ primary: CronixColors.accent,
13
+ secondary: CronixColors.accentLight,
14
+ surface: CronixColors.surface,
15
+ error: CronixColors.error,
16
+ onPrimary: CronixColors.text,
17
+ onSecondary: CronixColors.text,
18
+ onSurface: CronixColors.text,
19
+ onError: CronixColors.text,
20
+ ),
21
+ textTheme: _buildTextTheme(),
22
+ appBarTheme: AppBarTheme(
23
+ backgroundColor: CronixColors.background,
24
+ foregroundColor: CronixColors.text,
25
+ elevation: 0,
26
+ scrolledUnderElevation: 1,
27
+ ),
28
+ cardTheme: CardTheme(
29
+ color: CronixColors.surface,
30
+ elevation: 0,
31
+ shape: RoundedRectangleBorder(
32
+ borderRadius: CronixRadius.radiusMD,
33
+ side: const BorderSide(color: CronixColors.border),
34
+ ),
35
+ ),
36
+ elevatedButtonTheme: ElevatedButtonThemeData(
37
+ style: ElevatedButton.styleFrom(
38
+ backgroundColor: CronixColors.accent,
39
+ foregroundColor: CronixColors.text,
40
+ shape: RoundedRectangleBorder(
41
+ borderRadius: CronixRadius.radiusMD,
42
+ ),
43
+ padding: CronixSpacing.paddingHorizontalMD.copyWith(
44
+ top: CronixSpacing.sm,
45
+ bottom: CronixSpacing.sm,
46
+ ),
47
+ ),
48
+ ),
49
+ inputDecorationTheme: InputDecorationTheme(
50
+ filled: true,
51
+ fillColor: CronixColors.surface,
52
+ border: OutlineInputBorder(
53
+ borderRadius: CronixRadius.radiusMD,
54
+ borderSide: const BorderSide(color: CronixColors.border),
55
+ ),
56
+ enabledBorder: OutlineInputBorder(
57
+ borderRadius: CronixRadius.radiusMD,
58
+ borderSide: const BorderSide(color: CronixColors.border),
59
+ ),
60
+ focusedBorder: OutlineInputBorder(
61
+ borderRadius: CronixRadius.radiusMD,
62
+ borderSide: const BorderSide(color: CronixColors.accent, width: 2),
63
+ ),
64
+ contentPadding: CronixSpacing.paddingSM,
65
+ ),
66
+ dividerTheme: const DividerThemeData(
67
+ color: CronixColors.divider,
68
+ thickness: 1,
69
+ ),
70
+ dialogTheme: DialogTheme(
71
+ backgroundColor: CronixColors.surface,
72
+ shape: RoundedRectangleBorder(
73
+ borderRadius: CronixRadius.radiusLG,
74
+ ),
75
+ ),
76
+ snackBarTheme: SnackBarThemeData(
77
+ backgroundColor: CronixColors.surfaceLight,
78
+ contentTextStyle: TextStyle(color: CronixColors.text),
79
+ shape: RoundedRectangleBorder(
80
+ borderRadius: CronixRadius.radiusMD,
81
+ ),
82
+ ),
83
+ );
84
+ }
85
+
86
+ static TextTheme _buildTextTheme() {
87
+ return TextTheme(
88
+ displayLarge: TextStyle(
89
+ fontSize: 57,
90
+ fontWeight: FontWeight.w400,
91
+ color: CronixColors.text,
92
+ letterSpacing: -0.25,
93
+ ),
94
+ displayMedium: TextStyle(
95
+ fontSize: 45,
96
+ fontWeight: FontWeight.w400,
97
+ color: CronixColors.text,
98
+ ),
99
+ displaySmall: TextStyle(
100
+ fontSize: 36,
101
+ fontWeight: FontWeight.w400,
102
+ color: CronixColors.text,
103
+ ),
104
+ headlineLarge: TextStyle(
105
+ fontSize: 32,
106
+ fontWeight: FontWeight.w600,
107
+ color: CronixColors.text,
108
+ ),
109
+ headlineMedium: TextStyle(
110
+ fontSize: 28,
111
+ fontWeight: FontWeight.w600,
112
+ color: CronixColors.text,
113
+ ),
114
+ headlineSmall: TextStyle(
115
+ fontSize: 24,
116
+ fontWeight: FontWeight.w600,
117
+ color: CronixColors.text,
118
+ ),
119
+ titleLarge: TextStyle(
120
+ fontSize: 22,
121
+ fontWeight: FontWeight.w500,
122
+ color: CronixColors.text,
123
+ ),
124
+ titleMedium: TextStyle(
125
+ fontSize: 16,
126
+ fontWeight: FontWeight.w500,
127
+ color: CronixColors.text,
128
+ letterSpacing: 0.15,
129
+ ),
130
+ titleSmall: TextStyle(
131
+ fontSize: 14,
132
+ fontWeight: FontWeight.w500,
133
+ color: CronixColors.text,
134
+ letterSpacing: 0.1,
135
+ ),
136
+ bodyLarge: TextStyle(
137
+ fontSize: 16,
138
+ fontWeight: FontWeight.w400,
139
+ color: CronixColors.text,
140
+ letterSpacing: 0.5,
141
+ ),
142
+ bodyMedium: TextStyle(
143
+ fontSize: 14,
144
+ fontWeight: FontWeight.w400,
145
+ color: CronixColors.text,
146
+ letterSpacing: 0.25,
147
+ ),
148
+ bodySmall: TextStyle(
149
+ fontSize: 12,
150
+ fontWeight: FontWeight.w400,
151
+ color: CronixColors.textSecondary,
152
+ letterSpacing: 0.4,
153
+ ),
154
+ labelLarge: TextStyle(
155
+ fontSize: 14,
156
+ fontWeight: FontWeight.w500,
157
+ color: CronixColors.text,
158
+ letterSpacing: 0.1,
159
+ ),
160
+ labelMedium: TextStyle(
161
+ fontSize: 12,
162
+ fontWeight: FontWeight.w500,
163
+ color: CronixColors.text,
164
+ letterSpacing: 0.5,
165
+ ),
166
+ labelSmall: TextStyle(
167
+ fontSize: 11,
168
+ fontWeight: FontWeight.w500,
169
+ color: CronixColors.textSecondary,
170
+ letterSpacing: 0.5,
171
+ ),
172
+ );
173
+ }
174
+ }
@@ -0,0 +1,254 @@
1
+ import 'package:flutter/material.dart';
2
+ import '../tokens/colors.dart';
3
+ import '../tokens/spacing.dart';
4
+
5
+ class CnAccordionItem {
6
+ final String title;
7
+ final Widget content;
8
+ final IconData? leadingIcon;
9
+ final bool initiallyExpanded;
10
+
11
+ const CnAccordionItem({
12
+ required this.title,
13
+ required this.content,
14
+ this.leadingIcon,
15
+ this.initiallyExpanded = false,
16
+ });
17
+ }
18
+
19
+ class CnAccordion extends StatelessWidget {
20
+ final List<CnAccordionItem> items;
21
+ final bool allowMultiple;
22
+ final Color? backgroundColor;
23
+ final Color? headerBackgroundColor;
24
+
25
+ const CnAccordion({
26
+ super.key,
27
+ required this.items,
28
+ this.allowMultiple = false,
29
+ this.backgroundColor,
30
+ this.headerBackgroundColor,
31
+ });
32
+
33
+ @override
34
+ Widget build(BuildContext context) {
35
+ if (allowMultiple) {
36
+ return Column(
37
+ children: items.asMap().entries.map((entry) {
38
+ return Padding(
39
+ padding: EdgeInsets.only(
40
+ bottom: entry.key < items.length - 1 ? 1 : 0,
41
+ ),
42
+ child: _CnAccordionItem(
43
+ item: entry.value,
44
+ backgroundColor: backgroundColor,
45
+ headerBackgroundColor: headerBackgroundColor,
46
+ ),
47
+ );
48
+ }).toList(),
49
+ );
50
+ }
51
+
52
+ return _CnAccordionGroup(
53
+ items: items,
54
+ backgroundColor: backgroundColor,
55
+ headerBackgroundColor: headerBackgroundColor,
56
+ );
57
+ }
58
+ }
59
+
60
+ class _CnAccordionGroup extends StatefulWidget {
61
+ final List<CnAccordionItem> items;
62
+ final Color? backgroundColor;
63
+ final Color? headerBackgroundColor;
64
+
65
+ const _CnAccordionGroup({
66
+ required this.items,
67
+ this.backgroundColor,
68
+ this.headerBackgroundColor,
69
+ });
70
+
71
+ @override
72
+ State<_CnAccordionGroup> createState() => _CnAccordionGroupState();
73
+ }
74
+
75
+ class _CnAccordionGroupState extends State<_CnAccordionGroup> {
76
+ int? _expandedIndex;
77
+
78
+ @override
79
+ void initState() {
80
+ super.initState();
81
+ for (int i = 0; i < widget.items.length; i++) {
82
+ if (widget.items[i].initiallyExpanded) {
83
+ _expandedIndex = i;
84
+ break;
85
+ }
86
+ }
87
+ }
88
+
89
+ @override
90
+ Widget build(BuildContext context) {
91
+ return Column(
92
+ children: widget.items.asMap().entries.map((entry) {
93
+ final index = entry.key;
94
+ final item = entry.value;
95
+ final isExpanded = _expandedIndex == index;
96
+
97
+ return Padding(
98
+ padding: EdgeInsets.only(
99
+ bottom: index < widget.items.length - 1 ? 1 : 0,
100
+ ),
101
+ child: Container(
102
+ decoration: BoxDecoration(
103
+ color: widget.backgroundColor ?? CronixColors.surface,
104
+ border: Border.all(color: CronixColors.border),
105
+ borderRadius: CronixRadius.radiusMD,
106
+ ),
107
+ child: Column(
108
+ children: [
109
+ InkWell(
110
+ onTap: () {
111
+ setState(() {
112
+ _expandedIndex = isExpanded ? null : index;
113
+ });
114
+ },
115
+ child: Container(
116
+ padding: const EdgeInsets.all(16),
117
+ child: Row(
118
+ children: [
119
+ if (item.leadingIcon != null) ...[
120
+ Icon(
121
+ item.leadingIcon,
122
+ size: 20,
123
+ color: CronixColors.textSecondary,
124
+ ),
125
+ const SizedBox(width: 12),
126
+ ],
127
+ Expanded(
128
+ child: Text(
129
+ item.title,
130
+ style: const TextStyle(
131
+ color: CronixColors.text,
132
+ fontSize: 14,
133
+ fontWeight: FontWeight.w500,
134
+ ),
135
+ ),
136
+ ),
137
+ Icon(
138
+ isExpanded
139
+ ? Icons.keyboard_arrow_up
140
+ : Icons.keyboard_arrow_down,
141
+ color: CronixColors.textSecondary,
142
+ ),
143
+ ],
144
+ ),
145
+ ),
146
+ ),
147
+ AnimatedCrossFade(
148
+ firstChild: const SizedBox.shrink(),
149
+ secondChild: Container(
150
+ width: double.infinity,
151
+ padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
152
+ child: item.content,
153
+ ),
154
+ crossFadeState: isExpanded
155
+ ? CrossFadeState.showSecond
156
+ : CrossFadeState.showFirst,
157
+ duration: const Duration(milliseconds: 200),
158
+ ),
159
+ ],
160
+ ),
161
+ ),
162
+ );
163
+ }).toList(),
164
+ );
165
+ }
166
+ }
167
+
168
+ class _CnAccordionItem extends StatefulWidget {
169
+ final CnAccordionItem item;
170
+ final Color? backgroundColor;
171
+ final Color? headerBackgroundColor;
172
+
173
+ const _CnAccordionItem({
174
+ required this.item,
175
+ this.backgroundColor,
176
+ this.headerBackgroundColor,
177
+ });
178
+
179
+ @override
180
+ State<_CnAccordionItem> createState() => _CnAccordionItemState();
181
+ }
182
+
183
+ class _CnAccordionItemState extends State<_CnAccordionItem> {
184
+ bool _isExpanded = false;
185
+
186
+ @override
187
+ void initState() {
188
+ super.initState();
189
+ _isExpanded = widget.item.initiallyExpanded;
190
+ }
191
+
192
+ @override
193
+ Widget build(BuildContext context) {
194
+ return Container(
195
+ decoration: BoxDecoration(
196
+ color: widget.backgroundColor ?? CronixColors.surface,
197
+ border: Border.all(color: CronixColors.border),
198
+ borderRadius: CronixRadius.radiusMD,
199
+ ),
200
+ child: Column(
201
+ children: [
202
+ InkWell(
203
+ onTap: () {
204
+ setState(() => _isExpanded = !_isExpanded);
205
+ },
206
+ child: Container(
207
+ padding: const EdgeInsets.all(16),
208
+ child: Row(
209
+ children: [
210
+ if (widget.item.leadingIcon != null) ...[
211
+ Icon(
212
+ widget.item.leadingIcon,
213
+ size: 20,
214
+ color: CronixColors.textSecondary,
215
+ ),
216
+ const SizedBox(width: 12),
217
+ ],
218
+ Expanded(
219
+ child: Text(
220
+ widget.item.title,
221
+ style: const TextStyle(
222
+ color: CronixColors.text,
223
+ fontSize: 14,
224
+ fontWeight: FontWeight.w500,
225
+ ),
226
+ ),
227
+ ),
228
+ Icon(
229
+ _isExpanded
230
+ ? Icons.keyboard_arrow_up
231
+ : Icons.keyboard_arrow_down,
232
+ color: CronixColors.textSecondary,
233
+ ),
234
+ ],
235
+ ),
236
+ ),
237
+ ),
238
+ AnimatedCrossFade(
239
+ firstChild: const SizedBox.shrink(),
240
+ secondChild: Container(
241
+ width: double.infinity,
242
+ padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
243
+ child: widget.item.content,
244
+ ),
245
+ crossFadeState: _isExpanded
246
+ ? CrossFadeState.showSecond
247
+ : CrossFadeState.showFirst,
248
+ duration: const Duration(milliseconds: 200),
249
+ ),
250
+ ],
251
+ ),
252
+ );
253
+ }
254
+ }