From 2e018ef185b01e30a0c2e17da80fba46150c0edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Fri, 19 Jul 2024 20:07:29 +0200 Subject: [PATCH 1/7] small improvements --- app/lib/home_page.dart | 7 +++++++ app/lib/settings/settings_page.dart | 7 ------- passkit_ui/lib/src/pass_sizer.dart | 11 +++++++---- passkit_ui/lib/src/theme/store_card_theme.dart | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/lib/home_page.dart b/app/lib/home_page.dart index 6892dab..4b7acf3 100644 --- a/app/lib/home_page.dart +++ b/app/lib/home_page.dart @@ -7,6 +7,7 @@ import 'package:app/widgets/app_icon.dart'; import 'package:app/widgets/pass_list_tile.dart'; import 'package:desktop_drop/desktop_drop.dart'; import 'package:drift/drift.dart' as drift; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:passkit/passkit.dart'; @@ -62,6 +63,12 @@ class _HomePageState extends State { appBar: AppBar( title: const AppIcon(), centerTitle: true, + leading: kDebugMode + ? IconButton( + onPressed: () => router.push('/examples'), + icon: const Icon(Icons.card_giftcard), + ) + : null, actions: [ IconButton( onPressed: () => pickPass(context), diff --git a/app/lib/settings/settings_page.dart b/app/lib/settings/settings_page.dart index 3726567..8f800c9 100644 --- a/app/lib/settings/settings_page.dart +++ b/app/lib/settings/settings_page.dart @@ -1,7 +1,5 @@ import 'package:app/db/preferences.dart'; -import 'package:app/router.dart'; import 'package:app/widgets/show_about_dialog.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -19,11 +17,6 @@ class _SettingsPageState extends State { appBar: AppBar( title: Text(AppLocalizations.of(context).settings), actions: [ - if (kDebugMode) - IconButton( - onPressed: () => router.push('/examples'), - icon: const Icon(Icons.card_giftcard), - ), IconButton( onPressed: () => showAboutWalletApp(context), icon: const Icon(Icons.info), diff --git a/passkit_ui/lib/src/pass_sizer.dart b/passkit_ui/lib/src/pass_sizer.dart index d975f7a..a1954cc 100644 --- a/passkit_ui/lib/src/pass_sizer.dart +++ b/passkit_ui/lib/src/pass_sizer.dart @@ -5,16 +5,19 @@ class PassSizer extends StatelessWidget { final Widget child; + static const width = 320.0; + static const height = 460.0; + @override Widget build(BuildContext context) { return SizedBox( - height: 460, - width: 320, + height: height, + width: width, child: FittedBox( fit: BoxFit.contain, child: SizedBox( - height: 460, - width: 320, + height: height, + width: width, child: child, ), ), diff --git a/passkit_ui/lib/src/theme/store_card_theme.dart b/passkit_ui/lib/src/theme/store_card_theme.dart index f618142..4d23a44 100644 --- a/passkit_ui/lib/src/theme/store_card_theme.dart +++ b/passkit_ui/lib/src/theme/store_card_theme.dart @@ -52,7 +52,7 @@ class StoreCardTheme extends ThemeExtension ), primaryLabelStyle: TextStyle( color: foregroundColor, - fontSize: 11, + fontSize: 14, fontWeight: FontWeight.w600, ), primaryTextStyle: TextStyle( From 58a1b8e857cddf6a90a13cbed0477141a262f63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Fri, 19 Jul 2024 20:08:04 +0200 Subject: [PATCH 2/7] remove boarding pass icon --- passkit_ui/lib/src/boarding_pass.dart | 115 +++++++++++--------------- 1 file changed, 50 insertions(+), 65 deletions(-) diff --git a/passkit_ui/lib/src/boarding_pass.dart b/passkit_ui/lib/src/boarding_pass.dart index 7b86bbc..7f8bafb 100644 --- a/passkit_ui/lib/src/boarding_pass.dart +++ b/passkit_ui/lib/src/boarding_pass.dart @@ -25,7 +25,6 @@ class BoardingPass extends StatelessWidget { @override Widget build(BuildContext context) { - final devicePixelRatio = MediaQuery.devicePixelRatioOf(context); final theme = Theme.of(context).extension()!; final boardingPass = pass.pass.boardingPass!; @@ -35,79 +34,65 @@ class BoardingPass extends StatelessWidget { color: theme.backgroundColor, child: Padding( padding: const EdgeInsets.all(14.0), - child: Stack( + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - Column( - mainAxisSize: MainAxisSize.min, + HeaderRow( + passTheme: theme, + logoText: pass.pass.logoText, + headerFields: boardingPass.headerFields, + logo: pass.logo, + ), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - HeaderRow( - passTheme: theme, - logoText: pass.pass.logoText, - headerFields: boardingPass.headerFields, - logo: pass.logo, - ), - const SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _FromTo( - data: boardingPass.primaryFields!.first, - theme: theme, - crossAxisAlignment: CrossAxisAlignment.start, - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: TransitTypeWidget( - transitType: boardingPass.transitType, - width: 30, - height: 30, - color: theme.labelColor, - ), - ), - _FromTo( - data: boardingPass.primaryFields![1], - theme: theme, - crossAxisAlignment: CrossAxisAlignment.end, - ), - ], + _FromTo( + data: boardingPass.primaryFields!.first, + theme: theme, + crossAxisAlignment: CrossAxisAlignment.start, ), - const SizedBox(height: 16), - if (boardingPass.auxiliaryFields != null) - _AuxiliaryRow( - auxiliaryRow: pass.pass.boardingPass!.auxiliaryFields!, - theme: theme, + Padding( + padding: const EdgeInsets.all(8.0), + child: TransitTypeWidget( + transitType: boardingPass.transitType, + width: 30, + height: 30, + color: theme.labelColor, ), - const SizedBox(height: 16), - // secondary fields - _AuxiliaryRow( - auxiliaryRow: pass.pass.boardingPass!.secondaryFields!, + ), + _FromTo( + data: boardingPass.primaryFields![1], theme: theme, + crossAxisAlignment: CrossAxisAlignment.end, ), - - const SizedBox(height: 16), - if ((pass.pass.barcodes?.firstOrNull ?? pass.pass.barcode) != - null) ...[ - const Spacer(), - Footer(footer: pass.footer), - const SizedBox(height: 2), - PasskitBarcode( - barcode: (pass.pass.barcodes?.firstOrNull ?? - pass.pass.barcode)!, - fontSize: 12, - ), - ], ], ), - if (pass.icon != null) - // TODO(ueman): check whether this matches Apples design guidelines - Align( - alignment: Alignment.bottomLeft, - child: Image.memory( - pass.icon!.forCorrectPixelRatio(devicePixelRatio), - fit: BoxFit.contain, - height: 15, - ), + const SizedBox(height: 16), + if (boardingPass.auxiliaryFields != null) + _AuxiliaryRow( + auxiliaryRow: pass.pass.boardingPass!.auxiliaryFields!, + theme: theme, ), + const SizedBox(height: 16), + // secondary fields + _AuxiliaryRow( + auxiliaryRow: pass.pass.boardingPass!.secondaryFields!, + theme: theme, + ), + + const SizedBox(height: 16), + if ((pass.pass.barcodes?.firstOrNull ?? pass.pass.barcode) != + null) ...[ + const Spacer(), + Footer(footer: pass.footer), + const SizedBox(height: 2), + PasskitBarcode( + barcode: + (pass.pass.barcodes?.firstOrNull ?? pass.pass.barcode)!, + fontSize: 12, + ), + ], ], ), ), From 8e250cb2bf37ace58692a9a648a44db39240f0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Sat, 20 Jul 2024 08:58:01 +0200 Subject: [PATCH 3/7] wip --- passkit_ui/lib/src/coupon.dart | 82 +++++++-------- passkit_ui/lib/src/store_card.dart | 110 ++++++++++++--------- passkit_ui/lib/src/widgets/header_row.dart | 6 ++ 3 files changed, 106 insertions(+), 92 deletions(-) diff --git a/passkit_ui/lib/src/coupon.dart b/passkit_ui/lib/src/coupon.dart index 0fc4a80..74e1a81 100644 --- a/passkit_ui/lib/src/coupon.dart +++ b/passkit_ui/lib/src/coupon.dart @@ -27,8 +27,7 @@ class Coupon extends StatelessWidget { return ClipPath( clipBehavior: Clip.antiAlias, - clipper: CouponClipper( - Sides.vertical, + clipper: _CouponClipper( heightOfPoint: 8, numberOfPoints: 40, ), @@ -53,10 +52,7 @@ class Coupon extends StatelessWidget { pass.strip!.forCorrectPixelRatio(devicePixelRatio), ), Column( - crossAxisAlignment: coupon - .primaryFields?.firstOrNull?.textAlignment - .toCrossAxisAlign() ?? - CrossAxisAlignment.stretch, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( coupon.primaryFields?.firstOrNull?.formatted() ?? '', @@ -122,37 +118,36 @@ class _AuxiliaryRow extends StatelessWidget { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: auxiliaryRow.map((item) { - return Column( - children: [ - Text( - item.label ?? '', - style: passTheme.auxiliaryLabelStyle, - textAlign: item.textAlignment.toFlutterTextAlign(), - ), - Text( - item.formatted() ?? '', - style: passTheme.auxiliaryTextStyle, - textAlign: item.textAlignment.toFlutterTextAlign(), - ), - ], + return Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + item.label ?? '', + style: passTheme.auxiliaryLabelStyle, + textAlign: item.textAlignment.toFlutterTextAlign(), + ), + Text( + item.formatted() ?? '', + style: passTheme.auxiliaryTextStyle, + textAlign: item.textAlignment.toFlutterTextAlign(), + ), + ], + ), ); }).toList(), ); } } -enum Sides { bottom, vertical } - -class CouponClipper extends CustomClipper { - CouponClipper( - this.side, { +class _CouponClipper extends CustomClipper { + _CouponClipper({ this.heightOfPoint = 12, this.numberOfPoints = 16, }); // final Sides side; final double heightOfPoint; final int numberOfPoints; - final Sides side; @override Path getClip(Size size) { @@ -163,31 +158,28 @@ class CouponClipper extends CustomClipper { double yControlPoint = size.height - heightOfPoint; double increment = size.width / numberOfPoints; - if (side == Sides.bottom || side == Sides.vertical) { - while (x < size.width) { - path.quadraticBezierTo( - x + increment / 2, - yControlPoint, - x + increment, - y, - ); - x += increment; - } + while (x < size.width) { + path.quadraticBezierTo( + x + increment / 2, + yControlPoint, + x + increment, + y, + ); + x += increment; } path.lineTo(size.width, 0.0); - if (side == Sides.vertical) { - while (x > 0) { - path.quadraticBezierTo( - x - increment / 2, - heightOfPoint, - x - increment, - 0, - ); - x -= increment; - } + while (x > 0) { + path.quadraticBezierTo( + x - increment / 2, + heightOfPoint, + x - increment, + 0, + ); + x -= increment; } + path.close(); return path; } diff --git a/passkit_ui/lib/src/store_card.dart b/passkit_ui/lib/src/store_card.dart index 8e72049..68f062c 100644 --- a/passkit_ui/lib/src/store_card.dart +++ b/passkit_ui/lib/src/store_card.dart @@ -13,7 +13,6 @@ import 'package:passkit_ui/src/widgets/header_row.dart'; /// For more information see /// - https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Creating.html#//apple_ref/doc/uid/TP40012195-CH4-SW1 /// - https://developer.apple.com/design/human-interface-guidelines/wallet - class StoreCard extends StatelessWidget { const StoreCard({super.key, required this.pass}); @@ -26,6 +25,10 @@ class StoreCard extends StatelessWidget { final theme = Theme.of(context).extension()!; final storeCard = pass.pass.storeCard!; + const padding = 16.0; + const verticalPadding = EdgeInsets.symmetric(vertical: padding); + const horizontalPadding = EdgeInsets.symmetric(horizontal: padding); + return ClipPath( clipper: const ShapeBorderClipper( shape: ContinuousRectangleBorder( @@ -36,15 +39,18 @@ class StoreCard extends StatelessWidget { child: ColoredBox( color: theme.backgroundColor, child: Padding( - padding: const EdgeInsets.all(16.0), + padding: verticalPadding, child: Column( mainAxisSize: MainAxisSize.min, children: [ - HeaderRow( - passTheme: theme, - headerFields: storeCard.headerFields, - logo: pass.logo, - logoText: pass.pass.logoText, + Padding( + padding: horizontalPadding, + child: HeaderRow( + passTheme: theme, + headerFields: storeCard.headerFields, + logo: pass.logo, + logoText: pass.pass.logoText, + ), ), const SizedBox(height: 16), Stack( @@ -52,38 +58,45 @@ class StoreCard extends StatelessWidget { if (pass.strip != null) Image.memory( pass.strip!.forCorrectPixelRatio(devicePixelRatio), + height: 123, + width: 320, + fit: BoxFit.cover, + ), + Padding( + padding: horizontalPadding.copyWith(top: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + storeCard.primaryFields?.firstOrNull?.formatted() ?? + '', + style: theme.primaryTextStyle, + textAlign: storeCard + .primaryFields?.firstOrNull?.textAlignment + .toFlutterTextAlign(), + ), + Text( + storeCard.primaryFields?.firstOrNull?.label ?? '', + style: theme.primaryLabelStyle, + textAlign: storeCard + .primaryFields?.firstOrNull?.textAlignment + .toFlutterTextAlign(), + ), + ], ), - Column( - crossAxisAlignment: storeCard - .primaryFields?.firstOrNull?.textAlignment - .toCrossAxisAlign() ?? - CrossAxisAlignment.stretch, - children: [ - Text( - storeCard.primaryFields?.firstOrNull?.formatted() ?? '', - style: theme.primaryTextStyle, - textAlign: storeCard - .primaryFields?.firstOrNull?.textAlignment - .toFlutterTextAlign(), - ), - Text( - storeCard.primaryFields?.firstOrNull?.label ?? '', - style: theme.primaryLabelStyle, - textAlign: storeCard - .primaryFields?.firstOrNull?.textAlignment - .toFlutterTextAlign(), - ), - ], ), ], ), const SizedBox(height: 16), - _AuxiliaryRow( - passTheme: theme, - auxiliaryRow: [ - ...?storeCard.secondaryFields, - ...?storeCard.auxiliaryFields, - ], + Padding( + padding: horizontalPadding, + child: _AuxiliaryRow( + passTheme: theme, + auxiliaryRow: [ + ...?storeCard.secondaryFields, + ...?storeCard.auxiliaryFields, + ], + ), ), const SizedBox(height: 16), const Spacer(), @@ -123,19 +136,22 @@ class _AuxiliaryRow extends StatelessWidget { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: auxiliaryRow.map((item) { - return Column( - children: [ - Text( - item.label ?? '', - style: passTheme.auxiliaryLabelStyle, - textAlign: item.textAlignment.toFlutterTextAlign(), - ), - Text( - item.formatted() ?? '', - style: passTheme.auxiliaryTextStyle, - textAlign: item.textAlignment.toFlutterTextAlign(), - ), - ], + return Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + item.label ?? '', + style: passTheme.auxiliaryLabelStyle, + textAlign: item.textAlignment.toFlutterTextAlign(), + ), + Text( + item.formatted() ?? '', + style: passTheme.auxiliaryTextStyle, + textAlign: item.textAlignment.toFlutterTextAlign(), + ), + ], + ), ); }).toList(), ); diff --git a/passkit_ui/lib/src/widgets/header_row.dart b/passkit_ui/lib/src/widgets/header_row.dart index 0243f02..70c07ac 100644 --- a/passkit_ui/lib/src/widgets/header_row.dart +++ b/passkit_ui/lib/src/widgets/header_row.dart @@ -1,5 +1,7 @@ import 'package:flutter/widgets.dart'; import 'package:passkit/passkit.dart'; +import 'package:passkit_ui/src/extensions/pk_text_alignment_extension.dart'; + import 'package:passkit_ui/src/theme/base_pass_theme.dart'; import 'package:passkit_ui/src/widgets/logo.dart'; @@ -38,10 +40,14 @@ class HeaderRow extends StatelessWidget { Text( headerFields?.first.label ?? '', style: passTheme.headerLabelStyle, + textAlign: + headerFields?.first.textAlignment.toFlutterTextAlign(), ), Text( headerFields?.first.value?.toString() ?? '', style: passTheme.headerTextStyle, + textAlign: + headerFields?.first.textAlignment.toFlutterTextAlign(), ), ], ), From 3495ed2c73c2e649e2110ba6f1cc1859eaacd1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Sat, 20 Jul 2024 17:30:54 +0200 Subject: [PATCH 4/7] wip --- passkit_ui/lib/src/event_ticket.dart | 177 ++++++++++-------- .../lib/src/theme/event_ticket_theme.dart | 11 +- 2 files changed, 103 insertions(+), 85 deletions(-) diff --git a/passkit_ui/lib/src/event_ticket.dart b/passkit_ui/lib/src/event_ticket.dart index bd456ec..24a3acf 100644 --- a/passkit_ui/lib/src/event_ticket.dart +++ b/passkit_ui/lib/src/event_ticket.dart @@ -4,8 +4,9 @@ import 'package:flutter/material.dart'; import 'package:passkit/passkit.dart'; import 'package:passkit_ui/passkit_ui.dart'; import 'package:passkit_ui/src/theme/event_ticket_theme.dart'; +import 'package:passkit_ui/src/widgets/header_row.dart'; -/// Event tickets +/// Event ticket /// /// Use the event ticket style to give people entry into events like concerts, /// movies, plays, and sporting events. Typically, each pass corresponds to a @@ -15,8 +16,7 @@ import 'package:passkit_ui/src/theme/event_ticket_theme.dart'; /// An event ticket can display logo, strip, background, or thumbnail images. /// However, if you supply a strip image, don’t include a background or /// thumbnail image. You can also include an extra row of up to four auxiliary -/// fields (for developer guidance, see the `row` property of -/// `PassFields.AuxiliaryFields`). +/// fields (for developer guidance, see the `row` property of [FieldDict.row]). /// /// https://developer.apple.com/design/human-interface-guidelines/wallet#Event-tickets class EventTicket extends StatelessWidget { @@ -67,69 +67,15 @@ class EventTicket extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Row( - mainAxisSize: MainAxisSize.max, - children: [ - Logo(logo: pass.logo), - if (pass.pass.logoText != null) - Text( - pass.pass.logoText!, - style: passTheme.logoTextStyle, - ), - const Spacer(), - // TODO(ueman): The header should be as wide as the thumbnail - Column( - children: [ - Text( - eventTicket.headerFields?.first.label ?? '', - style: passTheme.headerLabelStyle, - ), - Text( - eventTicket.headerFields?.first.value?.toString() ?? - '', - style: passTheme.headerTextStyle, - ), - ], - ), - ], + HeaderRow( + passTheme: passTheme, + headerFields: eventTicket.headerFields, + logo: pass.logo, + logoText: pass.pass.logoText, ), const SizedBox(height: 16), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _AuxiliaryRow( - passTheme: passTheme, - auxiliaryRow: eventTicket.primaryFields!, - ), - // The thumbnail image (`thumbnail.png`) displayed next to the - // fields on the front of the pass. The allotted space is - // 90 x 90 points. The aspect ratio should be in the range of - // 2:3 to 3:2, otherwise the image is cropped. - if (pass.thumbnail != null) - Image.memory( - width: 90, - height: 90, - fit: BoxFit.contain, - pass.thumbnail! - .forCorrectPixelRatio(devicePixelRatio), - ), - ], - ), - if (eventTicket.secondaryFields != null) - _AuxiliaryRow( - passTheme: passTheme, - auxiliaryRow: eventTicket.secondaryFields!, - ), - if (eventTicket.auxiliaryFields != null) ...[ - const SizedBox(height: 16), - _AuxiliaryRow( - passTheme: passTheme, - auxiliaryRow: eventTicket.auxiliaryFields!, - ), - ], - const SizedBox(height: 16), + _ThumbnailRow(pass: pass, passTheme: passTheme), + const Spacer(), if (pass.footer != null) Image.memory( pass.footer!.forCorrectPixelRatio(devicePixelRatio), @@ -154,33 +100,106 @@ class EventTicket extends StatelessWidget { } } -class _AuxiliaryRow extends StatelessWidget { - const _AuxiliaryRow({ +class _ThumbnailRow extends StatelessWidget { + const _ThumbnailRow({required this.pass, required this.passTheme}); + + final PkPass pass; + final EventTicketTheme passTheme; + + @override + Widget build(BuildContext context) { + final eventTicket = pass.pass.eventTicket!; + final devicePixelRatio = MediaQuery.devicePixelRatioOf(context); + + return Column( + children: [ + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (eventTicket.primaryFields != null) + _FieldRow( + passTheme: passTheme, + auxiliaryRow: eventTicket.primaryFields!, + isPrimary: true, + ), + const SizedBox(height: 8), + if (eventTicket.secondaryFields != null) + _FieldRow( + passTheme: passTheme, + auxiliaryRow: eventTicket.secondaryFields!, + ), + ], + ), + ), + // The thumbnail image (`thumbnail.png`) displayed next to the + // fields on the front of the pass. The allotted space is + // 90 x 90 points. The aspect ratio should be in the range of + // 2:3 to 3:2, otherwise the image is cropped. + if (pass.thumbnail != null) + Image.memory( + width: 90, + height: 90, + fit: BoxFit.contain, + pass.thumbnail!.forCorrectPixelRatio(devicePixelRatio), + ), + ], + ), + if (eventTicket.auxiliaryFields != null) ...[ + const SizedBox(height: 16), + _FieldRow( + passTheme: passTheme, + auxiliaryRow: eventTicket.auxiliaryFields!, + ), + ], + ], + ); + } +} + +class _FieldRow extends StatelessWidget { + const _FieldRow({ required this.auxiliaryRow, required this.passTheme, + this.isPrimary = false, }); final List auxiliaryRow; final EventTicketTheme passTheme; + final bool isPrimary; @override Widget build(BuildContext context) { return Row( + mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: auxiliaryRow.map((item) { - return Column( - children: [ - Text( - item.label ?? '', - style: passTheme.secondaryWithStripLabelStyle, - textAlign: item.textAlignment.toFlutterTextAlign(), - ), - Text( - item.formatted() ?? '', - style: passTheme.secondaryWithStripTextStyle, - textAlign: item.textAlignment.toFlutterTextAlign(), - ), - ], + return Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + item.label ?? '', + style: isPrimary + ? passTheme.primaryWithThumbnailLabelStyle + : passTheme.secondaryWithThumbnailLabelStyle, + textAlign: item.textAlignment.toFlutterTextAlign(), + ), + Text( + item.formatted() ?? '', + style: isPrimary + ? passTheme.primaryWithThumbnailTextStyle + : passTheme.secondaryWithThumbnailTextStyle, + textAlign: item.textAlignment.toFlutterTextAlign(), + ), + ], + ), ); }).toList(), ); diff --git a/passkit_ui/lib/src/theme/event_ticket_theme.dart b/passkit_ui/lib/src/theme/event_ticket_theme.dart index 080871a..e3e8452 100644 --- a/passkit_ui/lib/src/theme/event_ticket_theme.dart +++ b/passkit_ui/lib/src/theme/event_ticket_theme.dart @@ -65,12 +65,12 @@ class EventTicketTheme extends ThemeExtension fontSize: 12, height: 0.9, ), - primaryWithStripLabelStyle: TextStyle( + primaryWithStripLabelStyle: labelTextStyle.copyWith( color: foregroundColor, fontSize: 11, fontWeight: FontWeight.w600, ), - primaryWithStripTextStyle: TextStyle( + primaryWithStripTextStyle: foregroundTextStyle.copyWith( color: foregroundColor, fontSize: 50, height: 0.9, @@ -83,14 +83,13 @@ class EventTicketTheme extends ThemeExtension fontSize: 12, height: 0.9, ), - primaryWithThumbnailLabelStyle: TextStyle( - color: foregroundColor, + primaryWithThumbnailLabelStyle: labelTextStyle.copyWith( fontSize: 11, fontWeight: FontWeight.w600, ), - primaryWithThumbnailTextStyle: TextStyle( + primaryWithThumbnailTextStyle: foregroundTextStyle.copyWith( color: foregroundColor, - fontSize: 50, + fontSize: 16, height: 0.9, ), secondaryWithThumbnailLabelStyle: labelTextStyle.copyWith( From fc5a614514a34df5e0a222ae4cfc96ba60cd0e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Sat, 20 Jul 2024 17:32:37 +0200 Subject: [PATCH 5/7] fix store card font size --- passkit_ui/lib/src/theme/store_card_theme.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passkit_ui/lib/src/theme/store_card_theme.dart b/passkit_ui/lib/src/theme/store_card_theme.dart index 4d23a44..78a82bc 100644 --- a/passkit_ui/lib/src/theme/store_card_theme.dart +++ b/passkit_ui/lib/src/theme/store_card_theme.dart @@ -65,7 +65,7 @@ class StoreCardTheme extends ThemeExtension fontWeight: FontWeight.w600, ), auxiliaryTextStyle: foregroundTextStyle.copyWith( - fontSize: 12, + fontSize: 16, height: 0.9, ), ); From 6723500aa029c73e12f9d04576cf32679f330520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Sat, 20 Jul 2024 17:38:06 +0200 Subject: [PATCH 6/7] docs --- passkit_ui/lib/src/pk_pass_widget.dart | 2 ++ passkit_ui/lib/src/store_card.dart | 8 ++++++++ passkit_ui/lib/src/theme/store_card_theme.dart | 1 + 3 files changed, 11 insertions(+) diff --git a/passkit_ui/lib/src/pk_pass_widget.dart b/passkit_ui/lib/src/pk_pass_widget.dart index baefe16..374f7da 100644 --- a/passkit_ui/lib/src/pk_pass_widget.dart +++ b/passkit_ui/lib/src/pk_pass_widget.dart @@ -12,6 +12,8 @@ import 'package:passkit_ui/src/theme/event_ticket_theme.dart'; import 'package:passkit_ui/src/theme/generic_pass_theme.dart'; import 'package:passkit_ui/src/theme/store_card_theme.dart'; +/// A widget which visualizes a [PkPass] file. +/// See the Apple docs for how it looks like: /// https://developer.apple.com/design/human-interface-guidelines/wallet class PkPassWidget extends StatelessWidget { const PkPassWidget({ diff --git a/passkit_ui/lib/src/store_card.dart b/passkit_ui/lib/src/store_card.dart index 68f062c..7457b19 100644 --- a/passkit_ui/lib/src/store_card.dart +++ b/passkit_ui/lib/src/store_card.dart @@ -4,6 +4,14 @@ import 'package:passkit_ui/passkit_ui.dart'; import 'package:passkit_ui/src/theme/store_card_theme.dart'; import 'package:passkit_ui/src/widgets/header_row.dart'; +/// Store card +/// Use the store card style for store loyalty cards, discount cards, +/// points cards, and gift cards. If an account related to a store card carries +/// a balance, the pass usually shows the current balance. +/// +/// A store card can display logo and strip images, and it can have up to four +/// secondary and auxiliary fields, all displayed on one row. +/// /// A store card looks like the following: /// /// ![](https://docs-assets.developer.apple.com/published/f81fefc86a3b46a8052c2164131d2583/store-card@2x.png) diff --git a/passkit_ui/lib/src/theme/store_card_theme.dart b/passkit_ui/lib/src/theme/store_card_theme.dart index 78a82bc..80b9374 100644 --- a/passkit_ui/lib/src/theme/store_card_theme.dart +++ b/passkit_ui/lib/src/theme/store_card_theme.dart @@ -10,6 +10,7 @@ import 'package:passkit_ui/src/theme/base_pass_theme.dart'; /// /// See: /// - https://developer.apple.com/design/human-interface-guidelines/wallet#Store-cards +/// - https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Creating.html#//apple_ref/doc/uid/TP40012195-CH4-SW8 class StoreCardTheme extends ThemeExtension implements BasePassTheme { StoreCardTheme({ From 81e56d2b88fda81940f2339631a24086c9d4b766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Sat, 20 Jul 2024 17:40:52 +0200 Subject: [PATCH 7/7] docs --- passkit_ui/lib/src/pk_pass_widget.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/passkit_ui/lib/src/pk_pass_widget.dart b/passkit_ui/lib/src/pk_pass_widget.dart index 374f7da..2de2407 100644 --- a/passkit_ui/lib/src/pk_pass_widget.dart +++ b/passkit_ui/lib/src/pk_pass_widget.dart @@ -21,6 +21,7 @@ class PkPassWidget extends StatelessWidget { required this.pass, }); + /// The pass that's visualized by this widget. final PkPass pass; @override