ui/refactor/coherence-1 #187
@ -121,4 +121,11 @@ class TextWrapper {
 | 
				
			|||||||
  /// that, the selection color defaults to [DefaultSelectionStyle.defaultColor]
 | 
					  /// that, the selection color defaults to [DefaultSelectionStyle.defaultColor]
 | 
				
			||||||
  /// (semi-transparent grey).
 | 
					  /// (semi-transparent grey).
 | 
				
			||||||
  final Color? selectionColor;
 | 
					  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 textColor = MultiColor.single(theme.textTheme.bodyMedium?.color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final style = SymbolButtonStyle(
 | 
					    final style = SymbolButtonStyle(
 | 
				
			||||||
      labelStyle:
 | 
					      labelStyle: theme.textTheme.labelLarge?.copyWith(color: textColor.color),
 | 
				
			||||||
          theme.textTheme.labelLarge?.copyWith(color: textColor.color),
 | 
					 | 
				
			||||||
      dimension: theme.buttonTheme.height * 1.5,
 | 
					      dimension: theme.buttonTheme.height * 1.5,
 | 
				
			||||||
      radius: (theme.buttonTheme.shape is RoundedRectangleBorder)
 | 
					      radius: (theme.buttonTheme.shape is RoundedRectangleBorder)
 | 
				
			||||||
          ? (theme.buttonTheme.shape as RoundedRectangleBorder).borderRadius
 | 
					          ? (theme.buttonTheme.shape as RoundedRectangleBorder).borderRadius
 | 
				
			||||||
 | 
				
			|||||||
@ -17,5 +17,6 @@
 | 
				
			|||||||
export './card_component.dart';
 | 
					export './card_component.dart';
 | 
				
			||||||
export './information_card_component.dart';
 | 
					export './information_card_component.dart';
 | 
				
			||||||
export './portfolio_card_component.dart';
 | 
					export './portfolio_card_component.dart';
 | 
				
			||||||
 | 
					export './pricing_card_component.dart';
 | 
				
			||||||
export './quote_card_component.dart';
 | 
					export './quote_card_component.dart';
 | 
				
			||||||
export './skill_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:gap/gap.dart';
 | 
				
			||||||
import 'package:wyatt_ui_kit_example/cards/information_card/information_cards.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/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/quote_card/quote_cards.dart';
 | 
				
			||||||
import 'package:wyatt_ui_kit_example/cards/skill_card/skill_cards.dart';
 | 
					import 'package:wyatt_ui_kit_example/cards/skill_card/skill_cards.dart';
 | 
				
			||||||
import 'package:wyatt_ui_kit_example/demo_page.dart';
 | 
					import 'package:wyatt_ui_kit_example/demo_page.dart';
 | 
				
			||||||
@ -24,6 +25,8 @@ class Cards extends DemoPage {
 | 
				
			|||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          const Gap(20),
 | 
					          const Gap(20),
 | 
				
			||||||
 | 
					          const PricingCards(),
 | 
				
			||||||
 | 
					          const Gap(20),
 | 
				
			||||||
          const InformationCards(),
 | 
					          const InformationCards(),
 | 
				
			||||||
          const Gap(20),
 | 
					          const Gap(20),
 | 
				
			||||||
          const PortfolioCards(),
 | 
					          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
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) => SelectionArea(
 | 
					  Widget build(BuildContext context) => SelectionArea(
 | 
				
			||||||
    child: ListView(
 | 
					        child: ListView(
 | 
				
			||||||
          cacheExtent: 1000,
 | 
					          cacheExtent: 1000,
 | 
				
			||||||
          children: [
 | 
					          children: [
 | 
				
			||||||
            const Gap(20),
 | 
					            const Gap(20),
 | 
				
			||||||
@ -61,5 +61,5 @@ class RichTextBuilders extends DemoPage {
 | 
				
			|||||||
            const Gap(20),
 | 
					            const Gap(20),
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
  );
 | 
					      );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,9 @@ abstract class Constants {
 | 
				
			|||||||
  static const blue3 = Color(0xFF1A84F7);
 | 
					  static const blue3 = Color(0xFF1A84F7);
 | 
				
			||||||
  static const blue4 = Color(0xFF1344E4);
 | 
					  static const blue4 = Color(0xFF1344E4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static const blue1Btn = Color(0xFF3C97FB);
 | 
				
			||||||
 | 
					  static const blue2Btn = Color(0xFF446DF4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static const grey1 = Color(0xFF60656A);
 | 
					  static const grey1 = Color(0xFF60656A);
 | 
				
			||||||
  static const grey2 = Color(0xFF383C40);
 | 
					  static const grey2 = Color(0xFF383C40);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -37,10 +40,15 @@ abstract class Constants {
 | 
				
			|||||||
  static const red1 = Color(0xFFFB5E3C);
 | 
					  static const red1 = Color(0xFFFB5E3C);
 | 
				
			||||||
  static const red2 = Color(0xFFF44464);
 | 
					  static const red2 = Color(0xFFF44464);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static const purple1 = Color(0xFFB79EFF);
 | 
				
			||||||
 | 
					  static const purple2 = Color(0xFF6865F2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static const blueGradient = [blue1, blue2];
 | 
					  static const blueGradient = [blue1, blue2];
 | 
				
			||||||
 | 
					  static const blueBtnGradient = [blue1Btn, blue2Btn];
 | 
				
			||||||
  static const blueDarkGradient = [blue3, blue4];
 | 
					  static const blueDarkGradient = [blue3, blue4];
 | 
				
			||||||
  static const greyGradient = [grey1, grey2];
 | 
					  static const greyGradient = [grey1, grey2];
 | 
				
			||||||
  static const greyDarkGradient = [grey3, grey4];
 | 
					  static const greyDarkGradient = [grey3, grey4];
 | 
				
			||||||
  static const greenGradient = [green1, green2];
 | 
					  static const greenGradient = [green1, green2];
 | 
				
			||||||
  static const redGradient = [red1, red2];
 | 
					  static const redGradient = [red1, red2];
 | 
				
			||||||
 | 
					  static const purpleGradient = [purple1, purple2];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,5 +16,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export './information_card/information_card.dart';
 | 
					export './information_card/information_card.dart';
 | 
				
			||||||
export './portfolio_card/portfolio_card.dart';
 | 
					export './portfolio_card/portfolio_card.dart';
 | 
				
			||||||
 | 
					export './pricing_card/pricing_card.dart';
 | 
				
			||||||
export './quote_card/quote_card.dart';
 | 
					export './quote_card/quote_card.dart';
 | 
				
			||||||
export './skill_card/skill_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,
 | 
					      stroke: 1,
 | 
				
			||||||
      backgroundColors: const MultiColor.single(WyattColors.light),
 | 
					      backgroundColors: const MultiColor.single(WyattColors.light),
 | 
				
			||||||
      borderColors: WyattColors.lightGradient,
 | 
					      borderColors: WyattColors.lightGradient,
 | 
				
			||||||
      titleStyle: theme.textTheme.titleLarge,
 | 
					      titleStyle: theme.textTheme.titleLarge?.copyWith(
 | 
				
			||||||
 | 
					        fontSize: 26,
 | 
				
			||||||
 | 
					        fontWeight: FontWeight.w600,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
      subtitleStyle: theme.textTheme.titleMedium,
 | 
					      subtitleStyle: theme.textTheme.titleMedium,
 | 
				
			||||||
      bodyStyle: theme.textTheme.bodyMedium?.copyWith(
 | 
					      bodyStyle: theme.textTheme.bodyMedium?.copyWith(
 | 
				
			||||||
        height: 1.5,
 | 
					        height: 1.5,
 | 
				
			||||||
@ -76,7 +79,10 @@ class CardThemeExtensionImpl extends CardThemeExtension {
 | 
				
			|||||||
      stroke: 1,
 | 
					      stroke: 1,
 | 
				
			||||||
      backgroundColors: WyattColors.grayBgOpacityGradient,
 | 
					      backgroundColors: WyattColors.grayBgOpacityGradient,
 | 
				
			||||||
      borderColors: WyattColors.grayGradient,
 | 
					      borderColors: WyattColors.grayGradient,
 | 
				
			||||||
      titleStyle: theme.textTheme.titleLarge,
 | 
					      titleStyle: theme.textTheme.titleLarge?.copyWith(
 | 
				
			||||||
 | 
					        fontSize: 26,
 | 
				
			||||||
 | 
					        fontWeight: FontWeight.w600,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
      subtitleStyle: theme.textTheme.titleMedium,
 | 
					      subtitleStyle: theme.textTheme.titleMedium,
 | 
				
			||||||
      bodyStyle: theme.textTheme.bodyMedium?.copyWith(
 | 
					      bodyStyle: theme.textTheme.bodyMedium?.copyWith(
 | 
				
			||||||
        height: 1.5,
 | 
					        height: 1.5,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user