@@ -11,6 +11,15 @@ enum QueryaBadgeStatus {
1111 neutral,
1212}
1313
14+ enum _BadgeVariant {
15+ custom,
16+ primaryKey,
17+ foreignKey,
18+ dataType,
19+ status,
20+ readOnly,
21+ }
22+
1423/// Standard semantic badge widget for database types, constraints, and status indicators.
1524class QueryaBadge extends material.StatelessWidget {
1625 const QueryaBadge ({
@@ -21,38 +30,69 @@ class QueryaBadge extends material.StatelessWidget {
2130 this .foregroundColor,
2231 this .borderColor,
2332 this .isMonospace = false ,
24- });
33+ }) : _variant = _BadgeVariant .custom,
34+ _status = null ;
2535
2636 /// Primary Key badge (distinctive type1 gold/amber badge).
27- const factory QueryaBadge .primaryKey ({
28- material.Key ? key,
29- String label,
30- }) = _QueryaPrimaryKeyBadge ;
37+ const QueryaBadge .primaryKey ({
38+ super .key,
39+ this .label = 'PK' ,
40+ }) : icon = null ,
41+ backgroundColor = null ,
42+ foregroundColor = null ,
43+ borderColor = null ,
44+ isMonospace = false ,
45+ _variant = _BadgeVariant .primaryKey,
46+ _status = null ;
3147
3248 /// Foreign Key badge (distinctive type2 blue/cyan badge).
33- const factory QueryaBadge .foreignKey ({
34- material.Key ? key,
35- String label,
36- }) = _QueryaForeignKeyBadge ;
49+ const QueryaBadge .foreignKey ({
50+ super .key,
51+ this .label = 'FK' ,
52+ }) : icon = null ,
53+ backgroundColor = null ,
54+ foregroundColor = null ,
55+ borderColor = null ,
56+ isMonospace = false ,
57+ _variant = _BadgeVariant .foreignKey,
58+ _status = null ;
3759
3860 /// SQL / NoSQL data type badge (monospace label with subtle tint).
39- const factory QueryaBadge .dataType (
40- String type, {
41- material.Key ? key,
42- }) = _QueryaDataTypeBadge ;
61+ const QueryaBadge .dataType (
62+ this .label, {
63+ super .key,
64+ }) : icon = null ,
65+ backgroundColor = null ,
66+ foregroundColor = null ,
67+ borderColor = null ,
68+ isMonospace = true ,
69+ _variant = _BadgeVariant .dataType,
70+ _status = null ;
4371
4472 /// Operational or connection status badge.
45- const factory QueryaBadge .status (
46- String label, {
47- material. Key ? key,
73+ const QueryaBadge .status (
74+ this . label, {
75+ super . key,
4876 required QueryaBadgeStatus status,
49- }) = _QueryaStatusBadge ;
77+ }) : icon = null ,
78+ backgroundColor = null ,
79+ foregroundColor = null ,
80+ borderColor = null ,
81+ isMonospace = false ,
82+ _variant = _BadgeVariant .status,
83+ _status = status;
5084
5185 /// Read-only indicator badge.
52- const factory QueryaBadge .readOnly ({
53- material.Key ? key,
54- String label,
55- }) = _QueryaReadOnlyBadge ;
86+ const QueryaBadge .readOnly ({
87+ super .key,
88+ this .label = 'READ ONLY' ,
89+ }) : icon = null ,
90+ backgroundColor = null ,
91+ foregroundColor = null ,
92+ borderColor = null ,
93+ isMonospace = false ,
94+ _variant = _BadgeVariant .readOnly,
95+ _status = null ;
5696
5797 final String label;
5898 final material.Widget ? icon;
@@ -61,12 +101,82 @@ class QueryaBadge extends material.StatelessWidget {
61101 final material.Color ? borderColor;
62102 final bool isMonospace;
63103
104+ final _BadgeVariant _variant;
105+ final QueryaBadgeStatus ? _status;
106+
64107 @override
65108 material.Widget build (material.BuildContext context) {
66109 final cs = Theme .of (context).colorScheme;
67- final fg = foregroundColor ?? cs.foreground;
68- final bg = backgroundColor ?? cs.muted.withValues (alpha: 0.35 );
69- final border = borderColor ?? fg.withValues (alpha: 0.2 );
110+ final workbench = QueryaThemeScope .maybeOf (context)? .workbench;
111+ final palette = context.semanticPalette;
112+
113+ material.Color fg;
114+ material.Color bg;
115+ material.Color border;
116+ material.Widget ? effectiveIcon = icon;
117+ String effectiveLabel = label;
118+
119+ switch (_variant) {
120+ case _BadgeVariant .primaryKey:
121+ fg = palette.type1;
122+ bg = fg.withValues (alpha: 0.12 );
123+ border = fg.withValues (alpha: 0.3 );
124+ effectiveIcon = const material.Icon (material.Icons .vpn_key_rounded);
125+ break ;
126+ case _BadgeVariant .foreignKey:
127+ fg = palette.type2;
128+ bg = fg.withValues (alpha: 0.12 );
129+ border = fg.withValues (alpha: 0.3 );
130+ effectiveIcon = const material.Icon (material.Icons .link_rounded);
131+ break ;
132+ case _BadgeVariant .dataType:
133+ fg = workbench? .mutedForeground ?? cs.mutedForeground;
134+ bg = cs.muted.withValues (alpha: 0.3 );
135+ border = cs.border.withValues (alpha: 0.5 );
136+ effectiveLabel = label.toUpperCase ();
137+ break ;
138+ case _BadgeVariant .status:
139+ material.IconData ? statusIcon;
140+ switch (_status ?? QueryaBadgeStatus .neutral) {
141+ case QueryaBadgeStatus .success:
142+ fg = workbench? .success ?? palette.success;
143+ statusIcon = material.Icons .check_circle_outline_rounded;
144+ break ;
145+ case QueryaBadgeStatus .warning:
146+ fg = workbench? .warning ?? const material.Color (0xFFE88C30 );
147+ statusIcon = material.Icons .warning_amber_rounded;
148+ break ;
149+ case QueryaBadgeStatus .error:
150+ fg = workbench? .destructive ?? palette.destructive;
151+ statusIcon = material.Icons .error_outline_rounded;
152+ break ;
153+ case QueryaBadgeStatus .info:
154+ fg = workbench? .accent ?? cs.primary;
155+ statusIcon = material.Icons .info_outline_rounded;
156+ break ;
157+ case QueryaBadgeStatus .neutral:
158+ fg = workbench? .mutedForeground ?? cs.mutedForeground;
159+ statusIcon = null ;
160+ break ;
161+ }
162+ bg = fg.withValues (alpha: 0.12 );
163+ border = fg.withValues (alpha: 0.3 );
164+ if (statusIcon != null ) {
165+ effectiveIcon = material.Icon (statusIcon);
166+ }
167+ break ;
168+ case _BadgeVariant .readOnly:
169+ fg = workbench? .mutedForeground ?? cs.mutedForeground;
170+ bg = cs.muted.withValues (alpha: 0.4 );
171+ border = cs.border.withValues (alpha: 0.6 );
172+ effectiveIcon = const material.Icon (material.Icons .lock_outline_rounded);
173+ break ;
174+ case _BadgeVariant .custom:
175+ fg = foregroundColor ?? cs.foreground;
176+ bg = backgroundColor ?? cs.muted.withValues (alpha: 0.35 );
177+ border = borderColor ?? fg.withValues (alpha: 0.2 );
178+ break ;
179+ }
70180
71181 return material.Container (
72182 padding: const material.EdgeInsets .symmetric (horizontal: 6 , vertical: 2 ),
@@ -79,18 +189,18 @@ class QueryaBadge extends material.StatelessWidget {
79189 mainAxisSize: material.MainAxisSize .min,
80190 crossAxisAlignment: material.CrossAxisAlignment .center,
81191 children: [
82- if (icon != null ) ...[
192+ if (effectiveIcon != null ) ...[
83193 material.IconTheme (
84194 data: material.IconThemeData (
85195 size: 11 ,
86196 color: fg,
87197 ),
88- child: icon ! ,
198+ child: effectiveIcon ,
89199 ),
90200 const Gap (4 ),
91201 ],
92202 material.Text (
93- label ,
203+ effectiveLabel ,
94204 style: material.TextStyle (
95205 fontSize: 10 ,
96206 fontWeight: material.FontWeight .w600,
@@ -104,146 +214,3 @@ class QueryaBadge extends material.StatelessWidget {
104214 );
105215 }
106216}
107-
108- class _QueryaPrimaryKeyBadge extends QueryaBadge {
109- const _QueryaPrimaryKeyBadge ({
110- super .key,
111- super .label = 'PK' ,
112- });
113-
114- @override
115- material.Widget build (material.BuildContext context) {
116- final palette = context.semanticPalette;
117- final fg = palette.type1;
118- final bg = fg.withValues (alpha: 0.12 );
119-
120- return QueryaBadge (
121- label: label,
122- icon: const material.Icon (material.Icons .vpn_key_rounded),
123- backgroundColor: bg,
124- foregroundColor: fg,
125- borderColor: fg.withValues (alpha: 0.3 ),
126- );
127- }
128- }
129-
130- class _QueryaForeignKeyBadge extends QueryaBadge {
131- const _QueryaForeignKeyBadge ({
132- super .key,
133- super .label = 'FK' ,
134- });
135-
136- @override
137- material.Widget build (material.BuildContext context) {
138- final palette = context.semanticPalette;
139- final fg = palette.type2;
140- final bg = fg.withValues (alpha: 0.12 );
141-
142- return QueryaBadge (
143- label: label,
144- icon: const material.Icon (material.Icons .link_rounded),
145- backgroundColor: bg,
146- foregroundColor: fg,
147- borderColor: fg.withValues (alpha: 0.3 ),
148- );
149- }
150- }
151-
152- class _QueryaDataTypeBadge extends QueryaBadge {
153- const _QueryaDataTypeBadge (
154- super .label, {
155- super .key,
156- }) : super (isMonospace: true );
157-
158- @override
159- material.Widget build (material.BuildContext context) {
160- final cs = Theme .of (context).colorScheme;
161- final workbench = QueryaThemeScope .maybeOf (context)? .workbench;
162- final fg = workbench? .mutedForeground ?? cs.mutedForeground;
163- final bg = cs.muted.withValues (alpha: 0.3 );
164-
165- return QueryaBadge (
166- label: label.toUpperCase (),
167- backgroundColor: bg,
168- foregroundColor: fg,
169- borderColor: cs.border.withValues (alpha: 0.5 ),
170- isMonospace: true ,
171- );
172- }
173- }
174-
175- class _QueryaStatusBadge extends QueryaBadge {
176- const _QueryaStatusBadge (
177- super .label, {
178- super .key,
179- required this .status,
180- });
181-
182- final QueryaBadgeStatus status;
183-
184- @override
185- material.Widget build (material.BuildContext context) {
186- final cs = Theme .of (context).colorScheme;
187- final workbench = QueryaThemeScope .maybeOf (context)? .workbench;
188- final palette = context.semanticPalette;
189-
190- material.Color fg;
191- material.IconData ? iconData;
192-
193- switch (status) {
194- case QueryaBadgeStatus .success:
195- fg = workbench? .success ?? palette.success;
196- iconData = material.Icons .check_circle_outline_rounded;
197- break ;
198- case QueryaBadgeStatus .warning:
199- fg = workbench? .warning ?? material.const Color (0xFFE88C30 );
200- iconData = material.Icons .warning_amber_rounded;
201- break ;
202- case QueryaBadgeStatus .error:
203- fg = workbench? .destructive ?? palette.destructive;
204- iconData = material.Icons .error_outline_rounded;
205- break ;
206- case QueryaBadgeStatus .info:
207- fg = workbench? .accent ?? cs.primary;
208- iconData = material.Icons .info_outline_rounded;
209- break ;
210- case QueryaBadgeStatus .neutral:
211- fg = workbench? .mutedForeground ?? cs.mutedForeground;
212- iconData = null ;
213- break ;
214- }
215-
216- final bg = fg.withValues (alpha: 0.12 );
217-
218- return QueryaBadge (
219- label: label,
220- icon: iconData != null ? material.Icon (iconData) : null ,
221- backgroundColor: bg,
222- foregroundColor: fg,
223- borderColor: fg.withValues (alpha: 0.3 ),
224- );
225- }
226- }
227-
228- class _QueryaReadOnlyBadge extends QueryaBadge {
229- const _QueryaReadOnlyBadge ({
230- super .key,
231- super .label = 'READ ONLY' ,
232- });
233-
234- @override
235- material.Widget build (material.BuildContext context) {
236- final cs = Theme .of (context).colorScheme;
237- final workbench = QueryaThemeScope .maybeOf (context)? .workbench;
238- final fg = workbench? .mutedForeground ?? cs.mutedForeground;
239- final bg = cs.muted.withValues (alpha: 0.4 );
240-
241- return QueryaBadge (
242- label: label,
243- icon: const material.Icon (material.Icons .lock_outline_rounded),
244- backgroundColor: bg,
245- foregroundColor: fg,
246- borderColor: cs.border.withValues (alpha: 0.6 ),
247- );
248- }
249- }
0 commit comments