Skip to content

Commit 3ae8c20

Browse files
authored
Fixed hex color picker in material 3 demo (#2578)
This pull request fixes the problem where the color picker wasn't handling hex values correctly. Fixes #2577
1 parent ac85e2c commit 3ae8c20

File tree

2 files changed

+77
-7
lines changed

2 files changed

+77
-7
lines changed

material_3_demo/lib/color_box.dart

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,13 @@ class _ColorBoxState extends State<ColorBox> {
6666
onPressed: () async {
6767
final messenger = ScaffoldMessenger.of(context);
6868
// Copy color as hex to clipboard
69-
String hex = '#';
7069
final c = widget.color;
71-
// Will change from int 0-255 to double 0.0-1.0 in 3.26+
72-
// The properties also change from red/green/blue to r/g/b
73-
// hex += (c.[r g b] * 255.0).round().toRadixString(16).padLeft(2, '0');
74-
hex += c.r.round().toRadixString(16).padLeft(2, '0');
75-
hex += c.g.round().toRadixString(16).padLeft(2, '0');
76-
hex += c.b.round().toRadixString(16).padLeft(2, '0');
70+
71+
final hex =
72+
'#${_colorChannelToHex(c.r)}'
73+
'${_colorChannelToHex(c.g)}'
74+
'${_colorChannelToHex(c.b)}';
75+
7776
final data = ClipboardData(text: hex);
7877
await Clipboard.setData(data);
7978
messenger.hideCurrentSnackBar();
@@ -90,3 +89,8 @@ class _ColorBoxState extends State<ColorBox> {
9089
);
9190
}
9291
}
92+
93+
String _colorChannelToHex(double value) {
94+
final intVal = (value * 255).round();
95+
return intVal.toRadixString(16).padLeft(2, '0');
96+
}

material_3_demo/test/color_screen_test.dart

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'dart:ui';
6+
57
import 'package:flutter/material.dart';
8+
import 'package:flutter/services.dart';
69
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:material_3_demo/color_box.dart';
711
import 'package:material_3_demo/color_palettes_screen.dart';
812
import 'package:material_3_demo/main.dart';
913
import 'package:material_3_demo/scheme.dart';
@@ -88,4 +92,66 @@ void main() {
8892
expect(find.text('Dark ColorScheme'), findsOneWidget);
8993
expect(find.byType(SchemePreview, skipOffstage: false), findsNWidgets(2));
9094
});
95+
96+
testWidgets(
97+
'ColorBox displays correct info and copies hex color on button tap',
98+
(tester) async {
99+
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
100+
.setMockMessageHandler('flutter/platform', (_) async {
101+
// To intercept method calls to 'Clipboard.setData'
102+
return const JSONMethodCodec().encodeSuccessEnvelope(null);
103+
});
104+
const hexColor = 0xFF3d3d8d;
105+
const testColor = Color(hexColor);
106+
const onTestColor = Colors.white;
107+
const testLabel = 'Test Label';
108+
const testTone = '50';
109+
110+
final gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
111+
112+
// Wrap in MaterialApp + Scaffold so we can show SnackBars
113+
await tester.pumpWidget(
114+
MaterialApp(
115+
home: Scaffold(
116+
body: ColorBox(
117+
label: testLabel,
118+
tone: testTone,
119+
color: testColor,
120+
onColor: onTestColor,
121+
height: 100,
122+
width: 100,
123+
displayPaletteInfo: true,
124+
),
125+
),
126+
),
127+
);
128+
129+
expect(find.text(testLabel), findsOneWidget);
130+
expect(find.text(testTone), findsOneWidget);
131+
132+
// The copy icon should NOT be there initially (only appears on hover).
133+
expect(find.byIcon(Icons.copy), findsNothing);
134+
135+
await gesture.addPointer(location: Offset.zero);
136+
addTearDown(gesture.removePointer);
137+
await tester.pump();
138+
await gesture.moveTo(tester.getCenter(find.byType(ColorBox)));
139+
await tester.pumpAndSettle();
140+
141+
expect(find.byIcon(Icons.copy), findsOneWidget);
142+
143+
// Tap the copy icon, which copies the hex to clipboard and shows a SnackBar.
144+
await tester.tap(find.byIcon(Icons.copy));
145+
await tester.pumpAndSettle();
146+
147+
expect(find.byType(SnackBar), findsOneWidget);
148+
149+
expect(
150+
find.text(
151+
'Copied #${hexColor.toRadixString(16).substring(2)} to clipboard',
152+
),
153+
findsOneWidget,
154+
);
155+
},
156+
);
91157
}

0 commit comments

Comments
 (0)