cronixui 1.1.0 → 1.1.2
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 +16 -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
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
import '../tokens/colors.dart';
|
|
3
|
+
import '../tokens/spacing.dart';
|
|
4
|
+
|
|
5
|
+
enum CnToastVariant { info, success, warning, error }
|
|
6
|
+
|
|
7
|
+
class CnToast {
|
|
8
|
+
final String message;
|
|
9
|
+
final CnToastVariant variant;
|
|
10
|
+
final Duration duration;
|
|
11
|
+
final IconData? icon;
|
|
12
|
+
final String? actionLabel;
|
|
13
|
+
final VoidCallback? onAction;
|
|
14
|
+
|
|
15
|
+
CnToast({
|
|
16
|
+
required this.message,
|
|
17
|
+
this.variant = CnToastVariant.info,
|
|
18
|
+
this.duration = const Duration(seconds: 3),
|
|
19
|
+
this.icon,
|
|
20
|
+
this.actionLabel,
|
|
21
|
+
this.onAction,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
IconData get _defaultIcon {
|
|
25
|
+
switch (variant) {
|
|
26
|
+
case CnToastVariant.info:
|
|
27
|
+
return Icons.info_outline;
|
|
28
|
+
case CnToastVariant.success:
|
|
29
|
+
return Icons.check_circle_outline;
|
|
30
|
+
case CnToastVariant.warning:
|
|
31
|
+
return Icons.warning_amber_outlined;
|
|
32
|
+
case CnToastVariant.error:
|
|
33
|
+
return Icons.error_outline;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Color get _backgroundColor {
|
|
38
|
+
switch (variant) {
|
|
39
|
+
case CnToastVariant.info:
|
|
40
|
+
return CronixColors.info;
|
|
41
|
+
case CnToastVariant.success:
|
|
42
|
+
return CronixColors.success;
|
|
43
|
+
case CnToastVariant.warning:
|
|
44
|
+
return CronixColors.warning;
|
|
45
|
+
case CnToastVariant.error:
|
|
46
|
+
return CronixColors.error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
SnackBar toSnackBar() {
|
|
51
|
+
return SnackBar(
|
|
52
|
+
content: Row(
|
|
53
|
+
children: [
|
|
54
|
+
Icon(icon ?? _defaultIcon, color: CronixColors.text, size: 20),
|
|
55
|
+
const SizedBox(width: 12),
|
|
56
|
+
Expanded(
|
|
57
|
+
child: Text(
|
|
58
|
+
message,
|
|
59
|
+
style: const TextStyle(color: CronixColors.text),
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
if (actionLabel != null)
|
|
63
|
+
TextButton(
|
|
64
|
+
onPressed: onAction,
|
|
65
|
+
child: Text(
|
|
66
|
+
actionLabel!,
|
|
67
|
+
style: const TextStyle(
|
|
68
|
+
color: CronixColors.text,
|
|
69
|
+
fontWeight: FontWeight.w600,
|
|
70
|
+
),
|
|
71
|
+
),
|
|
72
|
+
),
|
|
73
|
+
],
|
|
74
|
+
),
|
|
75
|
+
backgroundColor: _backgroundColor,
|
|
76
|
+
duration: duration,
|
|
77
|
+
behavior: SnackBarBehavior.floating,
|
|
78
|
+
shape: RoundedRectangleBorder(
|
|
79
|
+
borderRadius: CronixRadius.radiusMD,
|
|
80
|
+
),
|
|
81
|
+
margin: const EdgeInsets.all(16),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static void show(
|
|
86
|
+
BuildContext context, {
|
|
87
|
+
required String message,
|
|
88
|
+
CnToastVariant variant = CnToastVariant.info,
|
|
89
|
+
Duration duration = const Duration(seconds: 3),
|
|
90
|
+
IconData? icon,
|
|
91
|
+
String? actionLabel,
|
|
92
|
+
VoidCallback? onAction,
|
|
93
|
+
}) {
|
|
94
|
+
final toast = CnToast(
|
|
95
|
+
message: message,
|
|
96
|
+
variant: variant,
|
|
97
|
+
duration: duration,
|
|
98
|
+
icon: icon,
|
|
99
|
+
actionLabel: actionLabel,
|
|
100
|
+
onAction: onAction,
|
|
101
|
+
);
|
|
102
|
+
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
|
103
|
+
ScaffoldMessenger.of(context).showSnackBar(toast.toSnackBar());
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static void success(BuildContext context, String message) {
|
|
107
|
+
show(context, message: message, variant: CnToastVariant.success);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static void error(BuildContext context, String message) {
|
|
111
|
+
show(context, message: message, variant: CnToastVariant.error);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static void warning(BuildContext context, String message) {
|
|
115
|
+
show(context, message: message, variant: CnToastVariant.warning);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static void info(BuildContext context, String message) {
|
|
119
|
+
show(context, message: message, variant: CnToastVariant.info);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
import '../tokens/colors.dart';
|
|
3
|
+
import '../tokens/spacing.dart';
|
|
4
|
+
|
|
5
|
+
class CnToggle extends StatelessWidget {
|
|
6
|
+
final bool value;
|
|
7
|
+
final ValueChanged<bool>? onChanged;
|
|
8
|
+
final String? label;
|
|
9
|
+
final bool enabled;
|
|
10
|
+
final Color? activeColor;
|
|
11
|
+
|
|
12
|
+
const CnToggle({
|
|
13
|
+
super.key,
|
|
14
|
+
required this.value,
|
|
15
|
+
this.onChanged,
|
|
16
|
+
this.label,
|
|
17
|
+
this.enabled = true,
|
|
18
|
+
this.activeColor,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
@override
|
|
22
|
+
Widget build(BuildContext context) {
|
|
23
|
+
final toggle = GestureDetector(
|
|
24
|
+
onTap: enabled && onChanged != null
|
|
25
|
+
? () => onChanged!(!value)
|
|
26
|
+
: null,
|
|
27
|
+
child: AnimatedContainer(
|
|
28
|
+
duration: const Duration(milliseconds: 200),
|
|
29
|
+
width: 44,
|
|
30
|
+
height: 24,
|
|
31
|
+
decoration: BoxDecoration(
|
|
32
|
+
color: value
|
|
33
|
+
? (activeColor ?? CronixColors.accent)
|
|
34
|
+
: CronixColors.border,
|
|
35
|
+
borderRadius: CronixRadius.radiusFull,
|
|
36
|
+
),
|
|
37
|
+
child: AnimatedAlign(
|
|
38
|
+
duration: const Duration(milliseconds: 200),
|
|
39
|
+
alignment: value ? Alignment.centerRight : Alignment.centerLeft,
|
|
40
|
+
child: Container(
|
|
41
|
+
width: 20,
|
|
42
|
+
height: 20,
|
|
43
|
+
margin: const EdgeInsets.all(2),
|
|
44
|
+
decoration: BoxDecoration(
|
|
45
|
+
color: CronixColors.text,
|
|
46
|
+
borderRadius: CronixRadius.radiusFull,
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
),
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (label != null) {
|
|
54
|
+
return InkWell(
|
|
55
|
+
onTap: enabled && onChanged != null
|
|
56
|
+
? () => onChanged!(!value)
|
|
57
|
+
: null,
|
|
58
|
+
borderRadius: CronixRadius.radiusSM,
|
|
59
|
+
child: Row(
|
|
60
|
+
mainAxisSize: MainAxisSize.min,
|
|
61
|
+
children: [
|
|
62
|
+
Text(
|
|
63
|
+
label!,
|
|
64
|
+
style: TextStyle(
|
|
65
|
+
color: enabled ? CronixColors.text : CronixColors.textMuted,
|
|
66
|
+
fontSize: 14,
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
const SizedBox(width: 12),
|
|
70
|
+
toggle,
|
|
71
|
+
],
|
|
72
|
+
),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return toggle;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
import '../tokens/colors.dart';
|
|
3
|
+
import '../tokens/spacing.dart';
|
|
4
|
+
|
|
5
|
+
class CnTooltip extends StatelessWidget {
|
|
6
|
+
final String message;
|
|
7
|
+
final Widget child;
|
|
8
|
+
final EdgeInsetsGeometry? padding;
|
|
9
|
+
final Color? backgroundColor;
|
|
10
|
+
final Color? textColor;
|
|
11
|
+
final Duration? waitDuration;
|
|
12
|
+
final Duration? showDuration;
|
|
13
|
+
final bool preferBelow;
|
|
14
|
+
|
|
15
|
+
const CnTooltip({
|
|
16
|
+
super.key,
|
|
17
|
+
required this.message,
|
|
18
|
+
required this.child,
|
|
19
|
+
this.padding,
|
|
20
|
+
this.backgroundColor,
|
|
21
|
+
this.textColor,
|
|
22
|
+
this.waitDuration,
|
|
23
|
+
this.showDuration,
|
|
24
|
+
this.preferBelow = true,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
@override
|
|
28
|
+
Widget build(BuildContext context) {
|
|
29
|
+
return Tooltip(
|
|
30
|
+
message: message,
|
|
31
|
+
padding: padding ?? const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
32
|
+
margin: const EdgeInsets.all(8),
|
|
33
|
+
decoration: BoxDecoration(
|
|
34
|
+
color: backgroundColor ?? CronixColors.surfaceLight,
|
|
35
|
+
borderRadius: CronixRadius.radiusSM,
|
|
36
|
+
border: Border.all(color: CronixColors.border),
|
|
37
|
+
),
|
|
38
|
+
textStyle: TextStyle(
|
|
39
|
+
color: textColor ?? CronixColors.text,
|
|
40
|
+
fontSize: 12,
|
|
41
|
+
),
|
|
42
|
+
waitDuration: waitDuration ?? const Duration(milliseconds: 500),
|
|
43
|
+
showDuration: showDuration ?? const Duration(seconds: 2),
|
|
44
|
+
preferBelow: preferBelow,
|
|
45
|
+
child: child,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class CnRichTooltip extends StatelessWidget {
|
|
51
|
+
final Widget Function(BuildContext context) builder;
|
|
52
|
+
final Widget child;
|
|
53
|
+
final Offset? offset;
|
|
54
|
+
|
|
55
|
+
const CnRichTooltip({
|
|
56
|
+
super.key,
|
|
57
|
+
required this.builder,
|
|
58
|
+
required this.child,
|
|
59
|
+
this.offset,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
@override
|
|
63
|
+
Widget build(BuildContext context) {
|
|
64
|
+
return _CnRichTooltipWrapper(
|
|
65
|
+
builder: builder,
|
|
66
|
+
offset: offset,
|
|
67
|
+
child: child,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
class _CnRichTooltipWrapper extends StatefulWidget {
|
|
73
|
+
final Widget Function(BuildContext context) builder;
|
|
74
|
+
final Widget child;
|
|
75
|
+
final Offset? offset;
|
|
76
|
+
|
|
77
|
+
const _CnRichTooltipWrapper({
|
|
78
|
+
required this.builder,
|
|
79
|
+
required this.child,
|
|
80
|
+
this.offset,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
@override
|
|
84
|
+
State<_CnRichTooltipWrapper> createState() => _CnRichTooltipWrapperState();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
class _CnRichTooltipWrapperState extends State<_CnRichTooltipWrapper> {
|
|
88
|
+
OverlayEntry? _overlayEntry;
|
|
89
|
+
bool _isVisible = false;
|
|
90
|
+
|
|
91
|
+
void _showTooltip() {
|
|
92
|
+
_overlayEntry = OverlayEntry(
|
|
93
|
+
builder: widget.builder,
|
|
94
|
+
);
|
|
95
|
+
Overlay.of(context).insert(_overlayEntry!);
|
|
96
|
+
setState(() => _isVisible = true);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
void _hideTooltip() {
|
|
100
|
+
_overlayEntry?.remove();
|
|
101
|
+
_overlayEntry = null;
|
|
102
|
+
setState(() => _isVisible = false);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@override
|
|
106
|
+
Widget build(BuildContext context) {
|
|
107
|
+
return MouseRegion(
|
|
108
|
+
onEnter: (_) => _showTooltip(),
|
|
109
|
+
onExit: (_) => _hideTooltip(),
|
|
110
|
+
child: GestureDetector(
|
|
111
|
+
onTapDown: (_) => _showTooltip(),
|
|
112
|
+
onTapUp: (_) => _hideTooltip(),
|
|
113
|
+
onTapCancel: () => _hideTooltip(),
|
|
114
|
+
child: widget.child,
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: cronixui
|
|
2
|
+
description: A dark-themed Flutter UI component library with Material Design base
|
|
3
|
+
version: 1.1.1
|
|
4
|
+
homepage: https://github.com/CazyUndee/CronixUI
|
|
5
|
+
|
|
6
|
+
environment:
|
|
7
|
+
sdk: '>=3.0.0 <4.0.0'
|
|
8
|
+
flutter: '>=3.16.0'
|
|
9
|
+
|
|
10
|
+
dependencies:
|
|
11
|
+
flutter:
|
|
12
|
+
sdk: flutter
|
|
13
|
+
|
|
14
|
+
dev_dependencies:
|
|
15
|
+
flutter_test:
|
|
16
|
+
sdk: flutter
|
|
17
|
+
flutter_lints: ^3.0.0
|
|
18
|
+
|
|
19
|
+
flutter:
|
|
20
|
+
uses-material-design: true
|