This commit is contained in:
parent
01a5619dc5
commit
bfbeabe7ec
@ -121,4 +121,11 @@ class TextWrapper {
|
||||
/// that, the selection color defaults to [DefaultSelectionStyle.defaultColor]
|
||||
/// (semi-transparent grey).
|
||||
final Color? selectionColor;
|
||||
|
||||
@override
|
||||
String toString() => 'TextWrapper(data: $data, style: $style, '
|
||||
'gradientColors: $gradientColors, textAlign: $textAlign, '
|
||||
'textDirection: $textDirection, softWrap: $softWrap, '
|
||||
'overflow: $overflow, maxLines: $maxLines, '
|
||||
'selectionColor: $selectionColor)';
|
||||
}
|
||||
|
@ -40,8 +40,7 @@ class SymbolButtonThemeExtensionDefault extends SymbolButtonThemeExtension {
|
||||
final textColor = MultiColor.single(theme.textTheme.bodyMedium?.color);
|
||||
|
||||
final style = SymbolButtonStyle(
|
||||
labelStyle:
|
||||
theme.textTheme.labelLarge?.copyWith(color: textColor.color),
|
||||
labelStyle: theme.textTheme.labelLarge?.copyWith(color: textColor.color),
|
||||
dimension: theme.buttonTheme.height * 1.5,
|
||||
radius: (theme.buttonTheme.shape is RoundedRectangleBorder)
|
||||
? (theme.buttonTheme.shape as RoundedRectangleBorder).borderRadius
|
||||
|
@ -17,5 +17,6 @@
|
||||
export './card_component.dart';
|
||||
export './information_card_component.dart';
|
||||
export './portfolio_card_component.dart';
|
||||
export './pricing_card_component.dart';
|
||||
export './quote_card_component.dart';
|
||||
export './skill_card_component.dart';
|
||||
|
@ -0,0 +1,99 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:wyatt_component_copy_with_extension/wyatt_component_copy_with_extension.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
|
||||
part 'pricing_card_component.g.dart';
|
||||
|
||||
class PricingLine {
|
||||
const PricingLine({
|
||||
required this.data,
|
||||
this.icon,
|
||||
});
|
||||
|
||||
final TextWrapper data;
|
||||
final Widget? icon;
|
||||
|
||||
@override
|
||||
String toString() => 'PricingLine(data: $data, icon: $icon)';
|
||||
}
|
||||
|
||||
class Pricing {
|
||||
const Pricing({
|
||||
required this.price,
|
||||
this.period,
|
||||
this.hasAsterisk = false,
|
||||
});
|
||||
|
||||
final TextWrapper price;
|
||||
final TextWrapper? period;
|
||||
|
||||
/// If [hasAsterisk] is true then the price will be displayed with
|
||||
/// an asterisk to emphasize that it is a special price.
|
||||
final bool hasAsterisk;
|
||||
}
|
||||
|
||||
@ComponentProxyExtension()
|
||||
abstract class PricingCardComponent extends CardComponent
|
||||
with CopyWithMixin<$PricingCardComponentCWProxy> {
|
||||
const PricingCardComponent({
|
||||
this.axis,
|
||||
this.title,
|
||||
this.pricing,
|
||||
this.description,
|
||||
this.features,
|
||||
this.cta,
|
||||
super.radius,
|
||||
super.padding,
|
||||
super.borderColors,
|
||||
super.backgroundColors,
|
||||
super.stroke,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
super.shadow,
|
||||
super.titleStyle,
|
||||
super.subtitleStyle,
|
||||
super.bodyStyle,
|
||||
super.background,
|
||||
super.key,
|
||||
});
|
||||
|
||||
/// Axis of the card
|
||||
///
|
||||
/// If [axis] is [Axis.horizontal] then only the first icon will be displayed.
|
||||
/// Used in header of the card.
|
||||
final Axis? axis;
|
||||
|
||||
/// Title of the card
|
||||
///
|
||||
/// If [axis] is [Axis.vertical] then icon of the title will be displayed
|
||||
/// above the title.
|
||||
final PricingLine? title;
|
||||
|
||||
/// Pricing of the card
|
||||
final Pricing? pricing;
|
||||
|
||||
/// Description of the card
|
||||
final TextWrapper? description;
|
||||
|
||||
/// List of special features of the card
|
||||
final List<PricingLine>? features;
|
||||
|
||||
/// CTA of the card
|
||||
final Widget? cta;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'pricing_card_component.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ComponentProxyGenerator
|
||||
// **************************************************************************
|
||||
|
||||
abstract class $PricingCardComponentCWProxy {
|
||||
PricingCardComponent axis(Axis? axis);
|
||||
PricingCardComponent title(PricingLine? title);
|
||||
PricingCardComponent pricing(Pricing? pricing);
|
||||
PricingCardComponent description(TextWrapper? description);
|
||||
PricingCardComponent features(List<PricingLine>? features);
|
||||
PricingCardComponent cta(Widget? cta);
|
||||
PricingCardComponent radius(BorderRadiusGeometry? radius);
|
||||
PricingCardComponent padding(EdgeInsetsGeometry? padding);
|
||||
PricingCardComponent borderColors(MultiColor? borderColors);
|
||||
PricingCardComponent backgroundColors(MultiColor? backgroundColors);
|
||||
PricingCardComponent stroke(double? stroke);
|
||||
PricingCardComponent minSize(Size? minSize);
|
||||
PricingCardComponent maxSize(Size? maxSize);
|
||||
PricingCardComponent shadow(BoxShadow? shadow);
|
||||
PricingCardComponent titleStyle(TextStyle? titleStyle);
|
||||
PricingCardComponent subtitleStyle(TextStyle? subtitleStyle);
|
||||
PricingCardComponent bodyStyle(TextStyle? bodyStyle);
|
||||
PricingCardComponent background(Widget? background);
|
||||
PricingCardComponent key(Key? key);
|
||||
PricingCardComponent call({
|
||||
Axis? axis,
|
||||
PricingLine? title,
|
||||
Pricing? pricing,
|
||||
TextWrapper? description,
|
||||
List<PricingLine>? features,
|
||||
Widget? cta,
|
||||
BorderRadiusGeometry? radius,
|
||||
EdgeInsetsGeometry? padding,
|
||||
MultiColor? borderColors,
|
||||
MultiColor? backgroundColors,
|
||||
double? stroke,
|
||||
Size? minSize,
|
||||
Size? maxSize,
|
||||
BoxShadow? shadow,
|
||||
TextStyle? titleStyle,
|
||||
TextStyle? subtitleStyle,
|
||||
TextStyle? bodyStyle,
|
||||
Widget? background,
|
||||
Key? key,
|
||||
});
|
||||
}
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_ui_kit_example/cards/information_card/information_cards.dart';
|
||||
import 'package:wyatt_ui_kit_example/cards/portfolio_card/portfolio_cards.dart';
|
||||
import 'package:wyatt_ui_kit_example/cards/pricing_card/pricing_cards.dart';
|
||||
import 'package:wyatt_ui_kit_example/cards/quote_card/quote_cards.dart';
|
||||
import 'package:wyatt_ui_kit_example/cards/skill_card/skill_cards.dart';
|
||||
import 'package:wyatt_ui_kit_example/demo_page.dart';
|
||||
@ -24,6 +25,8 @@ class Cards extends DemoPage {
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
const PricingCards(),
|
||||
const Gap(20),
|
||||
const InformationCards(),
|
||||
const Gap(20),
|
||||
const PortfolioCards(),
|
||||
|
@ -0,0 +1,148 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
import 'package:wyatt_ui_kit_example/theme/constants.dart';
|
||||
|
||||
class PricingCards extends StatelessWidget {
|
||||
const PricingCards({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
children: [
|
||||
Text(
|
||||
'Pricing Cards',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const Gap(20),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
PricingCard(
|
||||
title: const PricingLine(
|
||||
data: TextWrapper('Lorem Ipsum'),
|
||||
icon: Icon(
|
||||
Icons.ac_unit_rounded,
|
||||
),
|
||||
),
|
||||
pricing: const Pricing(
|
||||
price: TextWrapper('450€'),
|
||||
period: TextWrapper('/ jour'),
|
||||
hasAsterisk: true,
|
||||
),
|
||||
description: const TextWrapper(
|
||||
'Cupidatat reprehenderit aliqua eiusmod Lorem. '
|
||||
'Qui ipsum id ea ea nulla labore aute ullamco aute '
|
||||
'quis elit ut amet velit. Incididunt fugiat proident '
|
||||
'proident deserunt tempor Lorem cillum qui do '
|
||||
'ullamco Lorem magna ipsum. Ullamco cupidatat velit '),
|
||||
features: const [
|
||||
PricingLine(
|
||||
icon: Icon(
|
||||
Icons.ac_unit_rounded,
|
||||
),
|
||||
data: TextWrapper(
|
||||
'Nulla labore aliquip dolor aliqua elit anim quis non officia laboris ad.',
|
||||
),
|
||||
),
|
||||
PricingLine(
|
||||
icon: Icon(
|
||||
Icons.ac_unit_rounded,
|
||||
),
|
||||
data: TextWrapper(
|
||||
'Eu pariatur non et sint minim aute pariatur amet officia.',
|
||||
),
|
||||
),
|
||||
],
|
||||
cta: context.components.flatButtonComponent.call(
|
||||
label: const TextWrapper(
|
||||
'Contactez-nous',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
normalStyle: FlatButtonThemeExtensionImpl.dark(
|
||||
theme: Theme.of(context),
|
||||
).normalStyle?.copyWith(
|
||||
backgroundColors:
|
||||
const MultiColor(Constants.blueBtnGradient),
|
||||
borderColors:
|
||||
const MultiColor(Constants.blueBtnGradient),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
PricingCard(
|
||||
title: const PricingLine(
|
||||
data: TextWrapper('Lorem Ipsum'),
|
||||
icon: Icon(
|
||||
Icons.ac_unit_rounded,
|
||||
),
|
||||
),
|
||||
pricing: const Pricing(
|
||||
price: TextWrapper('350€'),
|
||||
period: TextWrapper('/ jour'),
|
||||
hasAsterisk: true,
|
||||
),
|
||||
features: const [
|
||||
PricingLine(
|
||||
icon: Icon(
|
||||
Icons.ac_unit_rounded,
|
||||
),
|
||||
data: TextWrapper(
|
||||
'Nulla labore aliquip dolor aliqua elit anim quis non officia laboris ad.',
|
||||
),
|
||||
),
|
||||
PricingLine(
|
||||
icon: Icon(
|
||||
Icons.ac_unit_rounded,
|
||||
),
|
||||
data: TextWrapper(
|
||||
'Eu pariatur non et sint minim aute pariatur amet officia.',
|
||||
),
|
||||
),
|
||||
PricingLine(
|
||||
icon: Icon(
|
||||
Icons.ac_unit_rounded,
|
||||
),
|
||||
data: TextWrapper(
|
||||
'Nulla labore aliquip dolor aliqua elit anim quis non officia laboris ad.',
|
||||
),
|
||||
),
|
||||
],
|
||||
cta: context.components.flatButtonComponent.call(
|
||||
label: const TextWrapper(
|
||||
'Contactez-nous',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
normalStyle: FlatButtonThemeExtensionImpl.dark(
|
||||
theme: Theme.of(context),
|
||||
).normalStyle?.copyWith(
|
||||
backgroundColors:
|
||||
const MultiColor(Constants.purpleGradient),
|
||||
borderColors:
|
||||
const MultiColor(Constants.purpleGradient),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(20),
|
||||
],
|
||||
);
|
||||
}
|
@ -27,7 +27,7 @@ class RichTextBuilders extends DemoPage {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => SelectionArea(
|
||||
child: ListView(
|
||||
child: ListView(
|
||||
cacheExtent: 1000,
|
||||
children: [
|
||||
const Gap(20),
|
||||
@ -61,5 +61,5 @@ class RichTextBuilders extends DemoPage {
|
||||
const Gap(20),
|
||||
],
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ abstract class Constants {
|
||||
static const blue3 = Color(0xFF1A84F7);
|
||||
static const blue4 = Color(0xFF1344E4);
|
||||
|
||||
static const blue1Btn = Color(0xFF3C97FB);
|
||||
static const blue2Btn = Color(0xFF446DF4);
|
||||
|
||||
static const grey1 = Color(0xFF60656A);
|
||||
static const grey2 = Color(0xFF383C40);
|
||||
|
||||
@ -37,10 +40,15 @@ abstract class Constants {
|
||||
static const red1 = Color(0xFFFB5E3C);
|
||||
static const red2 = Color(0xFFF44464);
|
||||
|
||||
static const purple1 = Color(0xFFB79EFF);
|
||||
static const purple2 = Color(0xFF6865F2);
|
||||
|
||||
static const blueGradient = [blue1, blue2];
|
||||
static const blueBtnGradient = [blue1Btn, blue2Btn];
|
||||
static const blueDarkGradient = [blue3, blue4];
|
||||
static const greyGradient = [grey1, grey2];
|
||||
static const greyDarkGradient = [grey3, grey4];
|
||||
static const greenGradient = [green1, green2];
|
||||
static const redGradient = [red1, red2];
|
||||
static const purpleGradient = [purple1, purple2];
|
||||
}
|
||||
|
@ -16,5 +16,6 @@
|
||||
|
||||
export './information_card/information_card.dart';
|
||||
export './portfolio_card/portfolio_card.dart';
|
||||
export './pricing_card/pricing_card.dart';
|
||||
export './quote_card/quote_card.dart';
|
||||
export './skill_card/skill_card.dart';
|
||||
|
@ -0,0 +1,136 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_component_copy_with_extension/wyatt_component_copy_with_extension.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/pricing_card/widgets/pricing_card_features.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/pricing_card/widgets/pricing_card_titles.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_text.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_wrapper.dart';
|
||||
import 'package:wyatt_ui_kit/src/core/design_system/colors.dart';
|
||||
import 'package:wyatt_ui_kit/wyatt_ui_kit.dart';
|
||||
|
||||
part 'pricing_card.g.dart';
|
||||
|
||||
const _bodyTopSpacing = 25.0;
|
||||
|
||||
@ComponentCopyWithExtension()
|
||||
class PricingCard extends PricingCardComponent with $PricingCardCWMixin {
|
||||
const PricingCard({
|
||||
super.axis,
|
||||
super.title,
|
||||
super.pricing,
|
||||
super.description,
|
||||
super.features,
|
||||
super.cta,
|
||||
super.radius,
|
||||
super.padding,
|
||||
super.borderColors,
|
||||
super.backgroundColors,
|
||||
super.stroke,
|
||||
super.minSize,
|
||||
super.maxSize,
|
||||
super.shadow,
|
||||
super.titleStyle,
|
||||
super.subtitleStyle,
|
||||
super.bodyStyle,
|
||||
super.background,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeTitleStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
titleStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.titleStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).titleStyle,
|
||||
],
|
||||
);
|
||||
|
||||
final themePricingStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
pricing?.price.style,
|
||||
context.textTheme.bodyMedium
|
||||
?.copyWith(fontSize: 50, fontWeight: FontWeight.bold),
|
||||
],
|
||||
);
|
||||
|
||||
final themePeriodStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
subtitleStyle,
|
||||
context.textTheme.bodyMedium?.copyWith(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: WyattColors.gray1,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
final themeBodyStyle = ThemeHelper.maybeGetElement<TextStyle, TextStyle>(
|
||||
[
|
||||
bodyStyle,
|
||||
Theme.of(context).extension<CardThemeExtension>()?.bodyStyle,
|
||||
CardThemeExtensionDefault.from(Theme.of(context)).bodyStyle,
|
||||
],
|
||||
);
|
||||
|
||||
return CardWrapper(
|
||||
background: background,
|
||||
padding: padding,
|
||||
radius: radius,
|
||||
backgroundColors: backgroundColors,
|
||||
borderColors: borderColors,
|
||||
shadow: shadow,
|
||||
stroke: stroke,
|
||||
maxSize: maxSize,
|
||||
minSize: minSize,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
PricingCardTitles(
|
||||
axis: axis,
|
||||
title: title,
|
||||
pricing: pricing,
|
||||
titleStyle: themeTitleStyle,
|
||||
pricingStyle: themePricingStyle,
|
||||
periodStyle: themePeriodStyle,
|
||||
),
|
||||
const Gap(_bodyTopSpacing),
|
||||
if (description != null) ...[
|
||||
CardText.fromWrapper(
|
||||
description!,
|
||||
style: themeBodyStyle,
|
||||
),
|
||||
const Gap(_bodyTopSpacing),
|
||||
],
|
||||
if (features != null) ...[
|
||||
PricingCardFeatures(
|
||||
features: features,
|
||||
bodyStyle: themeBodyStyle,
|
||||
),
|
||||
const Gap(_bodyTopSpacing),
|
||||
],
|
||||
if (cta != null) ...[
|
||||
SelectionContainer.disabled(child: cta!),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'pricing_card.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ComponentCopyWithGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class $PricingCardCWProxyImpl implements $PricingCardComponentCWProxy {
|
||||
const $PricingCardCWProxyImpl(this._value);
|
||||
final PricingCard _value;
|
||||
@override
|
||||
PricingCard axis(Axis? axis) => this(axis: axis);
|
||||
@override
|
||||
PricingCard title(PricingLine? title) => this(title: title);
|
||||
@override
|
||||
PricingCard pricing(Pricing? pricing) => this(pricing: pricing);
|
||||
@override
|
||||
PricingCard description(TextWrapper? description) =>
|
||||
this(description: description);
|
||||
@override
|
||||
PricingCard features(List<PricingLine>? features) => this(features: features);
|
||||
@override
|
||||
PricingCard cta(Widget? cta) => this(cta: cta);
|
||||
@override
|
||||
PricingCard radius(BorderRadiusGeometry? radius) => this(radius: radius);
|
||||
@override
|
||||
PricingCard padding(EdgeInsetsGeometry? padding) => this(padding: padding);
|
||||
@override
|
||||
PricingCard borderColors(MultiColor? borderColors) =>
|
||||
this(borderColors: borderColors);
|
||||
@override
|
||||
PricingCard backgroundColors(MultiColor? backgroundColors) =>
|
||||
this(backgroundColors: backgroundColors);
|
||||
@override
|
||||
PricingCard stroke(double? stroke) => this(stroke: stroke);
|
||||
@override
|
||||
PricingCard minSize(Size? minSize) => this(minSize: minSize);
|
||||
@override
|
||||
PricingCard maxSize(Size? maxSize) => this(maxSize: maxSize);
|
||||
@override
|
||||
PricingCard shadow(BoxShadow? shadow) => this(shadow: shadow);
|
||||
@override
|
||||
PricingCard titleStyle(TextStyle? titleStyle) => this(titleStyle: titleStyle);
|
||||
@override
|
||||
PricingCard subtitleStyle(TextStyle? subtitleStyle) =>
|
||||
this(subtitleStyle: subtitleStyle);
|
||||
@override
|
||||
PricingCard bodyStyle(TextStyle? bodyStyle) => this(bodyStyle: bodyStyle);
|
||||
@override
|
||||
PricingCard background(Widget? background) => this(background: background);
|
||||
@override
|
||||
PricingCard key(Key? key) => this(key: key);
|
||||
@override
|
||||
PricingCard call({
|
||||
Axis? axis,
|
||||
PricingLine? title,
|
||||
Pricing? pricing,
|
||||
TextWrapper? description,
|
||||
List<PricingLine>? features,
|
||||
Widget? cta,
|
||||
BorderRadiusGeometry? radius,
|
||||
EdgeInsetsGeometry? padding,
|
||||
MultiColor? borderColors,
|
||||
MultiColor? backgroundColors,
|
||||
double? stroke,
|
||||
Size? minSize,
|
||||
Size? maxSize,
|
||||
BoxShadow? shadow,
|
||||
TextStyle? titleStyle,
|
||||
TextStyle? subtitleStyle,
|
||||
TextStyle? bodyStyle,
|
||||
Widget? background,
|
||||
Key? key,
|
||||
}) =>
|
||||
PricingCard(
|
||||
axis: axis ?? _value.axis,
|
||||
title: title ?? _value.title,
|
||||
pricing: pricing ?? _value.pricing,
|
||||
description: description ?? _value.description,
|
||||
features: features ?? _value.features,
|
||||
cta: cta ?? _value.cta,
|
||||
radius: radius ?? _value.radius,
|
||||
padding: padding ?? _value.padding,
|
||||
borderColors: borderColors ?? _value.borderColors,
|
||||
backgroundColors: backgroundColors ?? _value.backgroundColors,
|
||||
stroke: stroke ?? _value.stroke,
|
||||
minSize: minSize ?? _value.minSize,
|
||||
maxSize: maxSize ?? _value.maxSize,
|
||||
shadow: shadow ?? _value.shadow,
|
||||
titleStyle: titleStyle ?? _value.titleStyle,
|
||||
subtitleStyle: subtitleStyle ?? _value.subtitleStyle,
|
||||
bodyStyle: bodyStyle ?? _value.bodyStyle,
|
||||
background: background ?? _value.background,
|
||||
key: key ?? _value.key,
|
||||
);
|
||||
}
|
||||
|
||||
mixin $PricingCardCWMixin on Component {
|
||||
$PricingCardComponentCWProxy get copyWith =>
|
||||
$PricingCardCWProxyImpl(this as PricingCard);
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_text.dart';
|
||||
|
||||
class PricingCardFeatures extends StatelessWidget {
|
||||
const PricingCardFeatures({
|
||||
super.key,
|
||||
this.features,
|
||||
this.bodyStyle,
|
||||
});
|
||||
|
||||
/// List of special features of the card
|
||||
final List<PricingLine>? features;
|
||||
|
||||
/// Body style of the card.
|
||||
final TextStyle? bodyStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
children: features!
|
||||
.map(
|
||||
(feature) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: features?.indexOf(feature) == 0 ? 0 : 10,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
if (feature.icon != null) ...[
|
||||
feature.icon!,
|
||||
],
|
||||
const Gap(10),
|
||||
Expanded(
|
||||
child: CardText.fromWrapper(
|
||||
feature.data,
|
||||
style: bodyStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
|
||||
import 'package:wyatt_ui_kit/src/components/cards/widgets/card_text.dart';
|
||||
|
||||
const _titlesLineSpacing = 5.0;
|
||||
const _bodyTopSpacing = 25.0;
|
||||
|
||||
class PricingCardTitles extends StatelessWidget {
|
||||
const PricingCardTitles({
|
||||
this.axis,
|
||||
this.title,
|
||||
this.pricing,
|
||||
this.titleStyle,
|
||||
this.pricingStyle,
|
||||
this.periodStyle,
|
||||
super.key,
|
||||
});
|
||||
|
||||
/// The axis of the card header.
|
||||
final Axis? axis;
|
||||
|
||||
/// Title of the card
|
||||
///
|
||||
/// If [axis] is [Axis.vertical] then icon of the title will be displayed
|
||||
/// above the title.
|
||||
final PricingLine? title;
|
||||
|
||||
/// Pricing of the card
|
||||
final Pricing? pricing;
|
||||
|
||||
/// Styles the title of the card.
|
||||
final TextStyle? titleStyle;
|
||||
|
||||
/// Styles the pricing of the card.
|
||||
final TextStyle? pricingStyle;
|
||||
|
||||
/// Styles the period of the card.
|
||||
final TextStyle? periodStyle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final price = (pricing != null)
|
||||
? CardText.fromWrapper(
|
||||
pricing!.price,
|
||||
style: pricingStyle,
|
||||
textType: TextType.title,
|
||||
)
|
||||
: null;
|
||||
|
||||
final period = ((pricing != null) && (pricing?.period != null))
|
||||
? CardText.fromWrapper(
|
||||
pricing!.period!,
|
||||
style: periodStyle,
|
||||
textType: TextType.subtitle,
|
||||
)
|
||||
: null;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
if (title != null) ...[
|
||||
if (axis == Axis.vertical) ...[
|
||||
if (title?.icon != null) ...[
|
||||
title!.icon!,
|
||||
const Gap(_titlesLineSpacing),
|
||||
],
|
||||
CardText.fromWrapper(
|
||||
title!.data,
|
||||
style: titleStyle,
|
||||
textType: TextType.title,
|
||||
),
|
||||
const Gap(_bodyTopSpacing),
|
||||
] else ...[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (title?.icon != null) ...[
|
||||
title!.icon!,
|
||||
const Gap(_titlesLineSpacing),
|
||||
],
|
||||
CardText.fromWrapper(
|
||||
title!.data,
|
||||
style: titleStyle,
|
||||
textType: TextType.title,
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(_bodyTopSpacing),
|
||||
]
|
||||
],
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
if (price != null) ...[
|
||||
TextSpan(
|
||||
text: price.text.data,
|
||||
style: price.text.style,
|
||||
)
|
||||
],
|
||||
if (pricing?.hasAsterisk ?? false) ...[
|
||||
WidgetSpan(
|
||||
child: Transform.translate(
|
||||
offset: const Offset(5, -15),
|
||||
child: const Text(
|
||||
'* ',
|
||||
style: TextStyle(fontSize: 18),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (period != null) ...[
|
||||
TextSpan(
|
||||
text: period.text.data,
|
||||
style: period.text.style,
|
||||
)
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -50,7 +50,10 @@ class CardThemeExtensionImpl extends CardThemeExtension {
|
||||
stroke: 1,
|
||||
backgroundColors: const MultiColor.single(WyattColors.light),
|
||||
borderColors: WyattColors.lightGradient,
|
||||
titleStyle: theme.textTheme.titleLarge,
|
||||
titleStyle: theme.textTheme.titleLarge?.copyWith(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
subtitleStyle: theme.textTheme.titleMedium,
|
||||
bodyStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
height: 1.5,
|
||||
@ -76,7 +79,10 @@ class CardThemeExtensionImpl extends CardThemeExtension {
|
||||
stroke: 1,
|
||||
backgroundColors: WyattColors.grayBgOpacityGradient,
|
||||
borderColors: WyattColors.grayGradient,
|
||||
titleStyle: theme.textTheme.titleLarge,
|
||||
titleStyle: theme.textTheme.titleLarge?.copyWith(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
subtitleStyle: theme.textTheme.titleMedium,
|
||||
bodyStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||
height: 1.5,
|
||||
|
Loading…
x
Reference in New Issue
Block a user