Add dartpad example to RoundedSuperellipseBorder (#172185)

Now that Web supports squircles, we can finally add this dartpad example
to `RoundedSuperellipseBorder`'s doc.



https://github.com/user-attachments/assets/855be690-d9a1-45ec-a262-e0c38cf75b63


## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Tong Mu 2025-07-15 20:52:06 -07:00 committed by GitHub
parent 0a6aa6f340
commit 1f0041eb96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 188 additions and 0 deletions

View File

@ -0,0 +1,134 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
/// Flutter code sample for [RoundedSuperellipseBorder].
void main() {
runApp(const RoundedSuperellipseBorderExample());
}
class RoundedSuperellipseBorderExample extends StatefulWidget {
const RoundedSuperellipseBorderExample({super.key});
static final GlobalKey kBorderBoxKey = GlobalKey();
static final GlobalKey kThicknessSliderKey = GlobalKey();
static final GlobalKey kRadiusSliderKey = GlobalKey();
@override
State<RoundedSuperellipseBorderExample> createState() => RoundedSuperellipseBorderExampleState();
}
class RoundedSuperellipseBorderExampleState extends State<RoundedSuperellipseBorderExample> {
bool _toggle = true;
double _borderThickness = 4;
double _borderRadius = 69;
@override
Widget build(BuildContext context) {
final BorderRadiusGeometry radius = BorderRadiusGeometry.circular(_borderRadius);
final BorderSide side = BorderSide(width: _borderThickness, color: const Color(0xFF111111));
final ShapeBorder shape = _toggle
? RoundedSuperellipseBorder(side: side, borderRadius: radius)
: RoundedRectangleBorder(side: side, borderRadius: radius);
return CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: Container(
padding: const EdgeInsetsGeometry.all(10),
constraints: const BoxConstraints(maxWidth: 600),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 16,
children: <Widget>[
// The border is drawn by this DecoratedBox.
DecoratedBox(
key: RoundedSuperellipseBorderExample.kBorderBoxKey,
decoration: ShapeDecoration(shape: shape, color: const Color(0xFFFFC107)),
child: const SizedBox(width: 400, height: 200),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Shape: '),
CupertinoSwitch(
value: _toggle,
onChanged: (bool value) {
setState(() {
_toggle = value;
});
},
),
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 200),
child: Text(_toggle ? 'Rounded Superellipse' : 'Rounded Rect'),
),
],
),
SliderRow(
label: 'Thickness',
slider: CupertinoSlider(
value: _borderThickness,
max: 14,
min: 0.0000001,
onChanged: (double value) {
setState(() {
_borderThickness = value;
});
},
),
valueString: _borderThickness.toStringAsFixed(1),
key: RoundedSuperellipseBorderExample.kThicknessSliderKey,
),
SliderRow(
label: 'Radius',
slider: CupertinoSlider(
value: _borderRadius,
max: 100,
onChanged: (double value) {
setState(() {
_borderRadius = value;
});
},
),
valueString: _borderRadius.toStringAsFixed(1),
key: RoundedSuperellipseBorderExample.kRadiusSliderKey,
),
],
),
),
),
),
);
}
}
class SliderRow extends StatelessWidget {
const SliderRow({
super.key,
required this.label,
required this.slider,
required this.valueString,
});
final String label;
final Widget slider;
final String valueString;
@override
Widget build(BuildContext context) {
return Flex(
direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ConstrainedBox(constraints: const BoxConstraints(minWidth: 50), child: Text(label)),
Expanded(child: slider),
ConstrainedBox(constraints: const BoxConstraints(minWidth: 50), child: Text(valueString)),
],
);
}
}

View File

@ -0,0 +1,40 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter_api_samples/painting/rounded_superellipse_border/rounded_superellipse_border.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Smoke Test', (WidgetTester tester) async {
await tester.pumpWidget(const example.RoundedSuperellipseBorderExample());
expect(find.byType(example.RoundedSuperellipseBorderExample), findsOneWidget);
final RenderObject borderBox = tester.renderObject(
find.byKey(example.RoundedSuperellipseBorderExample.kBorderBoxKey),
);
expect(borderBox, paints..rsuperellipse());
// Test tapping switches
await tester.tap(find.byType(CupertinoSwitch));
await tester.pumpAndSettle();
expect(borderBox, paints..rrect());
final Finder radiusSlider = find.descendant(
of: find.byKey(example.RoundedSuperellipseBorderExample.kRadiusSliderKey),
matching: find.byType(CupertinoSlider),
);
expect(radiusSlider, findsOne);
final Finder thicknessSlider = find.descendant(
of: find.byKey(example.RoundedSuperellipseBorderExample.kThicknessSliderKey),
matching: find.byType(CupertinoSlider),
);
expect(thicknessSlider, findsOne);
// Preferrably we should test the interaction between the sliders and the
// drawn box, but it seems very hard if the slider thumb doesn't start at
// the left-most position.
});
}

View File

@ -205,6 +205,20 @@ class _RoundedRectangleToCircleBorder extends _ShapeToCircleBorder<RoundedRectan
/// Typically used with [ShapeDecoration] to draw a box that mimics the rounded
/// rectangle style commonly seen in iOS design.
///
/// {@tool dartpad}
/// This interactive example demonstrates the use of
/// [RoundedSuperellipseBorder].
///
/// Toggle the switch at the top to compare [RoundedSuperellipseBorder] with the
/// traditional [RoundedRectangleBorder] and observe their subtle visual
/// differences.
///
/// Use the sliders below to adjust the border's thickness and radius to explore
/// its behavior in real-time.
///
/// ** See code in examples/api/lib/painting/rounded_superellipse_border/rounded_superellipse_border.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [RSuperellipse], which defines the shape.