cronixui 1.1.0 → 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.
- package/README.md +12 -27
- package/package.json +2 -1
- package/packages/flutter/lib/cronixui.dart +41 -0
- package/packages/flutter/lib/src/tokens/colors.dart +34 -0
- package/packages/flutter/lib/src/tokens/spacing.dart +54 -0
- package/packages/flutter/lib/src/tokens/theme.dart +174 -0
- package/packages/flutter/lib/src/widgets/cn_accordion.dart +254 -0
- package/packages/flutter/lib/src/widgets/cn_alert.dart +137 -0
- package/packages/flutter/lib/src/widgets/cn_avatar.dart +98 -0
- package/packages/flutter/lib/src/widgets/cn_badge.dart +80 -0
- package/packages/flutter/lib/src/widgets/cn_breadcrumb.dart +88 -0
- package/packages/flutter/lib/src/widgets/cn_button.dart +137 -0
- package/packages/flutter/lib/src/widgets/cn_card.dart +99 -0
- package/packages/flutter/lib/src/widgets/cn_checkbox.dart +77 -0
- package/packages/flutter/lib/src/widgets/cn_command_palette.dart +299 -0
- package/packages/flutter/lib/src/widgets/cn_container.dart +131 -0
- package/packages/flutter/lib/src/widgets/cn_dropdown.dart +149 -0
- package/packages/flutter/lib/src/widgets/cn_file_input.dart +113 -0
- package/packages/flutter/lib/src/widgets/cn_footer.dart +108 -0
- package/packages/flutter/lib/src/widgets/cn_header.dart +173 -0
- package/packages/flutter/lib/src/widgets/cn_input.dart +142 -0
- package/packages/flutter/lib/src/widgets/cn_list.dart +150 -0
- package/packages/flutter/lib/src/widgets/cn_modal.dart +213 -0
- package/packages/flutter/lib/src/widgets/cn_nav.dart +157 -0
- package/packages/flutter/lib/src/widgets/cn_pagination.dart +193 -0
- package/packages/flutter/lib/src/widgets/cn_progress.dart +146 -0
- package/packages/flutter/lib/src/widgets/cn_radio.dart +133 -0
- package/packages/flutter/lib/src/widgets/cn_search.dart +183 -0
- package/packages/flutter/lib/src/widgets/cn_select.dart +244 -0
- package/packages/flutter/lib/src/widgets/cn_sidebar.dart +207 -0
- package/packages/flutter/lib/src/widgets/cn_skeleton.dart +136 -0
- package/packages/flutter/lib/src/widgets/cn_slider.dart +141 -0
- package/packages/flutter/lib/src/widgets/cn_spinner.dart +85 -0
- package/packages/flutter/lib/src/widgets/cn_stat.dart +135 -0
- package/packages/flutter/lib/src/widgets/cn_table.dart +136 -0
- package/packages/flutter/lib/src/widgets/cn_tabs.dart +229 -0
- package/packages/flutter/lib/src/widgets/cn_tag.dart +185 -0
- package/packages/flutter/lib/src/widgets/cn_textarea.dart +143 -0
- package/packages/flutter/lib/src/widgets/cn_toast.dart +121 -0
- package/packages/flutter/lib/src/widgets/cn_toggle.dart +78 -0
- package/packages/flutter/lib/src/widgets/cn_tooltip.dart +118 -0
- package/packages/flutter/pubspec.yaml +20 -0
package/README.md
CHANGED
|
@@ -10,36 +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
|
|
13
|
+
### React, Vue, Svelte, Solid
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm install @cronixui/react
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
### Vue
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
17
|
npm install @cronixui/vue
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Svelte
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
18
|
npm install @cronixui/svelte
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Solid
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
19
|
npm install @cronixui/solid
|
|
35
20
|
```
|
|
36
21
|
|
|
37
|
-
### Flutter
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
flutter pub add cronixui
|
|
41
|
-
```
|
|
42
|
-
|
|
43
22
|
### Python
|
|
44
23
|
|
|
45
24
|
```bash
|
|
@@ -56,14 +35,20 @@ go get github.com/CazyUndee/CronixUI/packages/go/cronixui
|
|
|
56
35
|
|
|
57
36
|
```toml
|
|
58
37
|
[dependencies]
|
|
59
|
-
cronixui = "1.1.
|
|
38
|
+
cronixui = "1.1.1"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Flutter
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
flutter pub add cronixui
|
|
60
45
|
```
|
|
61
46
|
|
|
62
47
|
### CDN
|
|
63
48
|
|
|
64
49
|
```html
|
|
65
|
-
<link rel="stylesheet" href="https://unpkg.com/cronixui@1.1.
|
|
66
|
-
<script src="https://unpkg.com/cronixui@1.1.
|
|
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>
|
|
67
52
|
```
|
|
68
53
|
|
|
69
54
|
## Quick Start (Web)
|
|
@@ -75,14 +60,14 @@ cronixui = "1.1.0"
|
|
|
75
60
|
<meta charset="UTF-8">
|
|
76
61
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
77
62
|
<title>My App</title>
|
|
78
|
-
<link rel="stylesheet" href="https://unpkg.com/cronixui@1.1.
|
|
63
|
+
<link rel="stylesheet" href="https://unpkg.com/cronixui@1.1.1/packages/web/dist/cronixui.css">
|
|
79
64
|
</head>
|
|
80
65
|
<body>
|
|
81
66
|
<div class="cn-container">
|
|
82
67
|
<h1 class="cn-h1">Hello, CronixUI!</h1>
|
|
83
68
|
<button class="cn-btn cn-btn-primary">Get Started</button>
|
|
84
69
|
</div>
|
|
85
|
-
<script src="https://unpkg.com/cronixui@1.1.
|
|
70
|
+
<script src="https://unpkg.com/cronixui@1.1.1/packages/web/dist/cronixui.js"></script>
|
|
86
71
|
</body>
|
|
87
72
|
</html>
|
|
88
73
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cronixui",
|
|
3
|
-
"version": "1.1.
|
|
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",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"packages/python/cronixui/",
|
|
53
53
|
"packages/go/cronixui/",
|
|
54
54
|
"packages/rust/cronixui/src/",
|
|
55
|
+
"packages/flutter/",
|
|
55
56
|
"README.md"
|
|
56
57
|
],
|
|
57
58
|
"scripts": {
|
|
@@ -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
|
+
}
|