Skip to content
Merged
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
17 changes: 17 additions & 0 deletions doc/marketing_goldens/flutter_test_config.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'dart:async';
import 'dart:io';

import 'package:flutter_test_goldens/flutter_test_goldens.dart';
import 'package:super_text_layout/super_text_layout.dart';

Future<void> testExecutable(FutureOr<void> Function() testMain) async {
// Adjust the theme that's applied to all golden tests in this suite.
GoldenSceneTheme.push(GoldenSceneTheme.standard.copyWith(
directory: Directory("."),
));

// Disable animations in Super Editor.
BlinkController.indeterminateAnimationsEnabled = false;

return testMain();
}
Binary file added doc/marketing_goldens/gallery/gallery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
114 changes: 114 additions & 0 deletions doc/marketing_goldens/gallery/gallery_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_test_goldens/flutter_test_goldens.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

import '../shadcn_test_tools.dart';

void main() {
group("Marketing >", () {
testGoldenScene("gallery", (tester) async {
FtgLog.initAllLogs();

// The following code is broken up so it can spread across multiple slides.
final gallery = Gallery(
"Gallery",
fileName: "gallery",
itemScaffold: shadcnItemScaffold,
layout: ShadcnGalleryLayout(
shadcnWordmarkProvider: shadcnWordmarkProvider,
),
);

gallery
.itemFromWidget(
id: "1",
description: "Primary",
widget: ShadButton(
child: const Text('Primary'),
onPressed: () {},
),
)
.itemFromWidget(
id: "2",
description: "Secondary",
widget: ShadButton.secondary(
child: const Text('Secondary'),
onPressed: () {},
),
)
.itemFromWidget(
id: "3",
description: "Destructive",
widget: ShadButton.destructive(
child: const Text('Destructive'),
onPressed: () {},
),
)
.itemFromWidget(
id: "4",
description: "Ghost",
widget: ShadButton.ghost(
child: const Text('Ghost'),
onPressed: () {},
),
)
.itemFromWidget(
id: "5",
description: "Link",
widget: ShadButton.ghost(
child: const Text('Link'),
onPressed: () {},
),
)
.itemFromWidget(
id: "6",
description: "Icon + Label",
widget: ShadButton(
onPressed: () {},
leading: const Icon(LucideIcons.mail),
child: const Text('Login with Email'),
),
)
.itemFromBuilder(
id: "7",
description: "Loading",
builder: (context) {
return ShadButton(
onPressed: () {},
leading: SizedBox.square(
dimension: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
color: ShadTheme.of(context).colorScheme.primaryForeground,
),
),
child: const Text('Please wait'),
);
},
)
.itemFromWidget(
id: "8",
description: "Gradient + Shadow",
widget: ShadButton(
onPressed: () {},
gradient: const LinearGradient(colors: [
Colors.cyan,
Colors.indigo,
]),
shadows: [
BoxShadow(
color: Colors.blue.withOpacity(.4),
spreadRadius: 4,
blurRadius: 10,
offset: const Offset(0, 2),
),
],
child: const Text('Gradient with Shadow'),
),
);

await gallery.run(tester);
});
});
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions doc/marketing_goldens/marketing_ui_toolkit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'dart:math';

import 'package:flutter/material.dart';

class AngledLinePainter extends CustomPainter {
AngledLinePainter({
required this.angleDegrees,
required this.gap,
required this.thickness,
required this.lineColor,
this.backgroundColor = Colors.transparent,
});

final double angleDegrees;
final double gap;
final double thickness;
final Color lineColor;
final Color backgroundColor;

@override
void paint(Canvas canvas, Size size) {
final rect = Offset.zero & size;
canvas
..save()
..clipRect(rect);

// Fill background.
canvas.drawRect(rect, Paint()..color = backgroundColor);

// Draw lines.
final paint = Paint()
..color = lineColor
..strokeWidth = thickness;

final angleRadians = angleDegrees * pi / 180;

// Calculate line direction
final dx = cos(angleRadians);
final dy = sin(angleRadians);
final direction = Offset(dx, dy);
final perpendicular = Offset(-dy, dx); // unit perpendicular vector

// Calculate diagonal length to cover the canvas
final diagonal = sqrt(size.width * size.width + size.height * size.height);

// Center of canvas
final center = Offset(size.width / 2, size.height / 2);

// Number of lines needed to cover the canvas
final numLines = (diagonal / gap).ceil();

for (int i = -numLines; i <= numLines; i++) {
final offset = perpendicular * (i * gap);
final start = center + offset - direction * diagonal;
final end = center + offset + direction * diagonal;

canvas.drawLine(start, end, paint);
}

canvas.restore();
}

@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_test_goldens/flutter_test_goldens.dart';
import 'package:flutter_test_goldens/golden_bricks.dart';
import 'package:super_editor/super_editor.dart';
import 'package:super_editor/super_editor_test.dart';

void main() {
group("Marketing > gallery > platform adaptive >", () {
testGoldenScene("text editor", (tester) async {
FtgLog.initLoggers({FtgLog.pipeline});

await Gallery(
"Platform Adaptive Gallery",
fileName: "platform_adaptive_gallery",
layout: GridGoldenSceneLayout(
itemDecorator: _itemDecorator,
),
)
.itemFromPumper(
id: "selected-text",
description: "Selected Text",
forEachPlatform: true,
pumper: _pumpEditor,
)
.run(tester);
});
});
}

Future<void> _pumpEditor(
WidgetTester tester,
GoldenSceneItemScaffold scaffold,
String description,
) async {
final editor = _createEditor();

await tester.pumpWidget(
scaffold(
tester,
DefaultTextStyle(
style: TextStyle(fontFamily: goldenBricks),
child: SizedBox(
width: 600,
child: SuperEditor(
editor: editor,
stylesheet: defaultStylesheet.copyWith(inlineTextStyler: (attributions, style) {
style = defaultInlineTextStyler(attributions, style);
return style.copyWith(fontFamily: goldenBricks);
}),
shrinkWrap: true,
),
),
),
),
);

await tester.doubleTapInParagraph("1", 25);
}

Editor _createEditor() {
return createDefaultDocumentEditor(
document: _createDocument(),
composer: MutableDocumentComposer(),
);
}

MutableDocument _createDocument() {
return MutableDocument(
nodes: [
ParagraphNode(
id: "0",
text: AttributedText("Multi Platform!"),
metadata: {
NodeMetadata.blockType: header1Attribution,
},
),
ParagraphNode(
id: "1",
text: AttributedText("Hello, world! This is a document editor built with Flutter."),
),
ParagraphNode(
id: "2",
text: AttributedText("You can place the caret, type text, delete text, select text, etc."),
),
],
);
}

Widget _itemDecorator(
BuildContext context,
GoldenScreenshotMetadata metadata,
Widget content,
) {
return Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
content,
Divider(),
Row(
mainAxisSize: MainAxisSize.min,
spacing: 16,
children: [
SvgPicture.file(
_getIconFileForPlatform(metadata.simulatedPlatform),
color: Colors.black,
width: 24,
height: 24,
),
Text(metadata.description),
],
),
],
),
);
}

File _getIconFileForPlatform(TargetPlatform platform) => switch (platform) {
TargetPlatform.android => File("doc/marketing_goldens/platform_adaptive_gallery/icons/android-brands.svg"),
TargetPlatform.iOS => File("doc/marketing_goldens/platform_adaptive_gallery/icons/apple-brands.svg"),
TargetPlatform.macOS => File("doc/marketing_goldens/platform_adaptive_gallery/icons/laptop-solid.svg"),
TargetPlatform.windows => File("doc/marketing_goldens/platform_adaptive_gallery/icons/windows-brands.svg"),
TargetPlatform.linux => File("doc/marketing_goldens/platform_adaptive_gallery/icons/ubuntu-brands.svg"),
TargetPlatform.fuchsia => throw UnimplementedError(),
};
Loading