Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/cupertino_ui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## NEXT

* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10.
* Fixes cross imports of `material_ui` in the `cupertino_ui` API examples.

## 0.0.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

// #region body
import 'package:cupertino_ui/cupertino_ui.dart';
import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [CupertinoListTile].

Expand Down Expand Up @@ -37,25 +36,25 @@ class CupertinoListTileExample extends StatelessWidget {
),
CupertinoListTile(
title: Text('One-line with trailing widget'),
trailing: Icon(Icons.more_vert),
trailing: Icon(CupertinoIcons.ellipsis_vertical),
),
CupertinoListTile(
leading: FlutterLogo(),
title: Text('One-line with both widgets'),
trailing: Icon(Icons.more_vert),
trailing: Icon(CupertinoIcons.ellipsis_vertical),
),
CupertinoListTile(
leading: FlutterLogo(size: 56.0),
title: Text('Two-line CupertinoListTile'),
subtitle: Text('Here is a subtitle'),
trailing: Icon(Icons.more_vert),
additionalInfo: Icon(Icons.info),
trailing: Icon(CupertinoIcons.ellipsis_vertical),
additionalInfo: Icon(CupertinoIcons.info),
),
CupertinoListTile(
key: Key('CupertinoListTile with background color'),
leading: FlutterLogo(size: 56.0),
title: Text('CupertinoListTile with background color'),
backgroundColor: Colors.lightBlue,
backgroundColor: Color(0xFF0000FF),
),
],
),
Expand Down
34 changes: 24 additions & 10 deletions packages/cupertino_ui/example/lib/magnifier/text_magnifier.0.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

// #region body
import 'package:flutter/foundation.dart';
import 'package:material_ui/material_ui.dart';
import 'package:cupertino_ui/cupertino_ui.dart';

void main() => runApp(const TextMagnifierExampleApp(text: 'Hello world!'));

class TextMagnifierExampleApp extends StatelessWidget {
class TextMagnifierExampleApp extends StatefulWidget {
const TextMagnifierExampleApp({
super.key,
this.textDirection = TextDirection.ltr,
Expand All @@ -18,29 +18,43 @@ class TextMagnifierExampleApp extends StatelessWidget {
final TextDirection textDirection;
final String text;

@override
State<TextMagnifierExampleApp> createState() =>
_TextMagnifierExampleAppState();
}

class _TextMagnifierExampleAppState extends State<TextMagnifierExampleApp> {
late final controller = TextEditingController(text: widget.text);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one was not disposed :(


@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Padding(
return CupertinoApp(
home: CupertinoPageScaffold(
child: Padding(
padding: const .symmetric(horizontal: 48.0),
child: Center(
child: TextField(
textDirection: textDirection,
child: CupertinoTextField(
textDirection: widget.textDirection,
// Create a custom magnifier configuration that
// this `TextField` will use to build a magnifier with.
// this `CupertinoTextField` will use to build a magnifier with.
magnifierConfiguration: TextMagnifierConfiguration(
magnifierBuilder:
(_, _, ValueNotifier<MagnifierInfo> magnifierInfo) =>
CustomMagnifier(magnifierInfo: magnifierInfo),
),
controller: TextEditingController(text: text),
controller: controller,
),
),
),
),
);
}

@override
void dispose() {
controller.dispose();
super.dispose();
}
}

class CustomMagnifier extends StatelessWidget {
Expand Down Expand Up @@ -96,7 +110,7 @@ class CustomMagnifier extends StatelessWidget {
// Decorate it however we'd like!
decoration: const MagnifierDecoration(
shape: StarBorder(
side: BorderSide(color: Colors.green, width: 2),
side: BorderSide(color: Color(0xFF00FF00), width: 2),
),
),
size: magnifierSize,
Expand Down
1 change: 1 addition & 0 deletions packages/cupertino_ui/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies:
test: ^1.31.0
vector_math: ^2.2.0
web: ^1.1.1
cupertino_icons: ^1.0.9

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the examples were relying on the Material Icons, I opted to switch to CupertinoIcons to fix those cross imports.

cupertino_ui:
path: ..
material_ui:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since all cross-imports of material_ui have been removed from the cupertino_ui examples and tests, the material_ui dependency (and its path override) in pubspec.yaml is no longer needed and can be safely removed to keep the dependencies clean.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true, since there are @docImports of material_ui, which this PR does not fix.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:material_ui/material_ui.dart';
import 'package:cupertino_ui/cupertino_ui.dart';
import 'package:cupertino_ui_examples/context_menu/cupertino_context_menu.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:material_ui/material_ui.dart';
import 'package:cupertino_ui/cupertino_ui.dart';
import 'package:cupertino_ui_examples/context_menu/cupertino_context_menu.1.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// found in the LICENSE file.

import 'package:cupertino_ui/cupertino_ui.dart';
import 'package:material_ui/material_ui.dart';
import 'package:cupertino_ui_examples/list_tile/cupertino_list_tile.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -26,8 +25,8 @@ void main() {
expect(find.text('Two-line CupertinoListTile'), findsOne);
expect(find.text('Here is a subtitle'), findsOne);
expect(find.text('CupertinoListTile with background color'), findsOne);
expect(find.byIcon(Icons.more_vert), findsNWidgets(3));
expect(find.byIcon(Icons.info), findsOne);
expect(find.byIcon(CupertinoIcons.ellipsis_vertical), findsNWidgets(3));
expect(find.byIcon(CupertinoIcons.info), findsOne);

final Finder tileWithBackgroundFinder = find.byKey(
const Key('CupertinoListTile with background color'),
Expand All @@ -36,7 +35,7 @@ void main() {
tester
.firstWidget<CupertinoListTile>(tileWithBackgroundFinder)
.backgroundColor,
Colors.lightBlue,
const Color(0xFF0000FF),
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,15 @@
// found in the LICENSE file.

import 'package:flutter/rendering.dart';
import 'package:material_ui/material_ui.dart';
import 'package:cupertino_ui/cupertino_ui.dart';
import 'package:cupertino_ui_examples/magnifier/text_magnifier.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';

List<TextSelectionPoint> _globalize(
Iterable<TextSelectionPoint> points,
RenderBox box,
) {
return points.map<TextSelectionPoint>((TextSelectionPoint point) {
return TextSelectionPoint(box.localToGlobal(point.point), point.direction);
}).toList();
}

RenderEditable _findRenderEditable<T extends State<StatefulWidget>>(
WidgetTester tester,
) {
return (tester.state(find.byType(TextField))
return (tester.state(find.byType(CupertinoTextField))
as TextSelectionGestureDetectorBuilderDelegate)
.editableTextKey
.currentState!
Expand All @@ -47,40 +38,16 @@ Offset _textOffsetToPosition<T extends State<StatefulWidget>>(
}

void main() {
const Duration durationBetweenActions = Duration(milliseconds: 20);
const String defaultText = 'I am a magnifier, fear me!';

Future<void> showMagnifier(WidgetTester tester, int textOffset) async {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For CupertinoTextField, instead of double tapping the word, I had to use long press to make it show up.

assert(textOffset >= 0);
final Offset tapOffset = _textOffsetToPosition(tester, textOffset);

// Double tap 'Magnifier' word to show the selection handles.
// Long press to show the magnifier.
final TestGesture testGesture = await tester.startGesture(tapOffset);
await tester.pump(durationBetweenActions);
await testGesture.up();
await tester.pump(durationBetweenActions);
await testGesture.down(tapOffset);
await tester.pump(durationBetweenActions);
await testGesture.up();
await tester.pumpAndSettle();

final TextEditingController controller = tester
.firstWidget<TextField>(find.byType(TextField))
.controller!;

final TextSelection selection = controller.selection;
final RenderEditable renderEditable = _findRenderEditable(tester);
final List<TextSelectionPoint> endpoints = _globalize(
renderEditable.getEndpointsForSelection(selection),
renderEditable,
);

final Offset handlePos = endpoints.last.point + const Offset(10.0, 10.0);

final TestGesture gesture = await tester.startGesture(handlePos);

await gesture.moveTo(_textOffsetToPosition(tester, defaultText.length - 2));
await tester.pump();
addTearDown(testGesture.removePointer);
await tester.pump(const Duration(milliseconds: 600));
}

testWidgets(
Expand All @@ -89,8 +56,10 @@ void main() {
await tester.pumpWidget(
const example.TextMagnifierExampleApp(text: defaultText),
);
final int textOffset = defaultText.indexOf('e');

await showMagnifier(tester, textOffset);

await showMagnifier(tester, defaultText.indexOf('e'));
expect(find.byType(example.CustomMagnifier), findsOneWidget);

await expectLater(
Expand All @@ -113,7 +82,9 @@ void main() {
const example.TextMagnifierExampleApp(textDirection: .rtl, text: text),
);

await showMagnifier(tester, text.indexOf(textToTapOn));
final int textOffset = text.indexOf(textToTapOn);

await showMagnifier(tester, textOffset);

expect(find.byType(example.CustomMagnifier), findsOneWidget);
});
Expand Down
Loading