diff --git a/example/lib/src/storybook/common/widgets/colors_page_options.dart b/example/lib/src/storybook/common/colors_page_options.dart similarity index 100% rename from example/lib/src/storybook/common/widgets/colors_page_options.dart rename to example/lib/src/storybook/common/colors_page_options.dart diff --git a/example/lib/src/storybook/common/pages/colors_page.dart b/example/lib/src/storybook/common/pages/colors_page.dart index db21919e..06947aa0 100644 --- a/example/lib/src/storybook/common/pages/colors_page.dart +++ b/example/lib/src/storybook/common/pages/colors_page.dart @@ -1,6 +1,6 @@ import 'package:example/src/storybook/common/color_options.dart'; +import 'package:example/src/storybook/common/colors_page_options.dart'; import 'package:example/src/storybook/common/constants.dart'; -import 'package:example/src/storybook/common/widgets/colors_page_options.dart'; import 'package:example/src/storybook/common/widgets/page_footer.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; @@ -109,8 +109,8 @@ class ColorsPage extends StatelessWidget { ), ); - return RichText( - text: TextSpan( + return Text.rich( + TextSpan( style: textStyle, children: spans, ), @@ -210,13 +210,14 @@ class ColorsPage extends StatelessWidget { Container( height: _colorContainerSizeValue, width: colorContainerWidth, - decoration: ShapeDecoration( - color: getColor(context, moonColor), - shape: ContinuousRectangleBorder( - borderRadius: BorderRadius.circular(16.0), - side: BorderSide( - color: context.moonColors!.beerus, - ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16.0), + border: Border.all(color: context.moonColors!.beerus), + ), + child: DecoratedBox( + decoration: BoxDecoration( + color: getColor(context, moonColor), + borderRadius: BorderRadius.circular(15.0), ), ), ), @@ -241,46 +242,48 @@ class ColorsPage extends StatelessWidget { right: 24, bottom: 16.0, ), - child: Center( - child: SizedBox( - width: largeScreenWidth, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: mediumScreenWidth, + child: SelectionArea( + child: Center( + child: SizedBox( + width: largeScreenWidth, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: mediumScreenWidth, + ), + child: Column( + children: [ + _buildSectionHeader( + context, + ColorsPageSection.header, + ), + const SizedBox(height: 24.0), + _buildSectionHeader( + context, + ColorsPageSection.mainColors, + ), + _buildMainColorsSection(context), + const SizedBox(height: 48.0), + _buildSectionHeader( + context, + ColorsPageSection.supportiveColors, + ), + _buildSupportiveColorsSection(context), + ], + ), ), - child: Column( - children: [ - _buildSectionHeader( - context, - ColorsPageSection.header, - ), - const SizedBox(height: 24.0), - _buildSectionHeader( - context, - ColorsPageSection.mainColors, - ), - _buildMainColorsSection(context), - const SizedBox(height: 48.0), - _buildSectionHeader( - context, - ColorsPageSection.supportiveColors, - ), - _buildSupportiveColorsSection(context), - ], + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: _getFooterWidth(context), + ), + child: const Center( + child: PageFooter(), + ), ), - ), - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: _getFooterWidth(context), - ), - child: const Center( - child: PageFooter(), - ), - ), - ], + ], + ), ), ), ), diff --git a/example/lib/src/storybook/common/pages/home_page.dart b/example/lib/src/storybook/common/pages/home_page.dart index 09cc1036..31f56830 100644 --- a/example/lib/src/storybook/common/pages/home_page.dart +++ b/example/lib/src/storybook/common/pages/home_page.dart @@ -52,7 +52,7 @@ class HomePage extends StatelessWidget { ), Text( HomePageContentType.headerTitle.text, - style: typography.heading.text64.copyWith(height: 1.1), + style: typography.heading.text64, ), const SizedBox(height: 24.0), Text( @@ -64,7 +64,7 @@ class HomePage extends StatelessWidget { const SizedBox(height: 72.0), Text( HomePageContentType.bodyTitle.text, - style: typography.heading.text40.copyWith(height: 1.1), + style: typography.heading.text40, ), ], ), @@ -96,7 +96,8 @@ class HomePage extends StatelessWidget { return MoonButton( width: double.infinity, - backgroundColor: isGitHub ? Colors.deepPurple : Colors.orange, + backgroundColor: + isGitHub ? context.moonColors!.piccolo : context.moonColors!.krillin, onTap: () => launchURL(socialMedia.url), leading: SvgPicture.asset( socialMedia.buttonIconPath, @@ -196,8 +197,7 @@ class HomePage extends StatelessWidget { component.description, maxLines: isExtraSmallScreen ? 3 : 2, overflow: TextOverflow.ellipsis, - style: context.moonTypography!.heading.text14 - .copyWith(height: 1.6), + style: context.moonTypography!.heading.text14, ), ], ), @@ -227,27 +227,30 @@ class HomePage extends StatelessWidget { right: 24, bottom: 16.0, ), - child: Center( - child: SizedBox( - width: largeScreenWidth, - child: Column( - crossAxisAlignment: layoutWidth > mediumScreenWidth - ? CrossAxisAlignment.start - : CrossAxisAlignment.center, - children: [ - _buildHeaderSection(context, showLogo), - const SizedBox(height: 48.0), - LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return Column( - children: [ - _buildCards(context, constraints.maxWidth), - const PageFooter(), - ], - ); - }, - ), - ], + child: SelectionArea( + child: Center( + child: SizedBox( + width: largeScreenWidth, + child: Column( + crossAxisAlignment: layoutWidth > mediumScreenWidth + ? CrossAxisAlignment.start + : CrossAxisAlignment.center, + children: [ + _buildHeaderSection(context, showLogo), + const SizedBox(height: 48.0), + LayoutBuilder( + builder: + (BuildContext context, BoxConstraints constraints) { + return Column( + children: [ + _buildCards(context, constraints.maxWidth), + const PageFooter(), + ], + ); + }, + ), + ], + ), ), ), ), diff --git a/example/lib/src/storybook/common/pages/typography_page.dart b/example/lib/src/storybook/common/pages/typography_page.dart new file mode 100644 index 00000000..d3daefc5 --- /dev/null +++ b/example/lib/src/storybook/common/pages/typography_page.dart @@ -0,0 +1,144 @@ +import 'package:example/src/storybook/common/constants.dart'; +import 'package:example/src/storybook/common/typography_page_options.dart'; +import 'package:example/src/storybook/common/widgets/page_footer.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:moon_design/moon_design.dart'; + +class TypographyPage extends StatelessWidget { + static const path = '/typography'; + + const TypographyPage({super.key}); + + Widget _buildSectionHeader( + BuildContext context, + TypographyPageSection section, + ) { + final bool isHeader = section == TypographyPageSection.typography; + final bool showLogo = + MediaQuery.of(context).size.width < storybookAutoLayoutThreshold; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (isHeader && showLogo) + Padding( + padding: const EdgeInsets.only(left: 12.0, bottom: 24.0), + child: SvgPicture.asset( + 'assets/svg/moon-logo-long.svg', + height: 16.0, + ), + ), + Text( + section.titleText, + style: isHeader + ? context.moonTypography!.heading.text40 + : context.moonTypography!.heading.text24, + ), + const SizedBox(height: 24), + if (section.bodyText.isNotEmpty) + Text( + section.bodyText, + style: context.moonTypography!.body.text16, + ), + ], + ); + } + + Widget _buildTypographyContainer(BuildContext context, MoonTextStyle style) { + return Container( + width: double.infinity, + padding: const EdgeInsets.all(24.0), + decoration: BoxDecoration( + color: context.moonColors!.gohan, + borderRadius: BorderRadius.circular(16.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: List.generate( + MoonTextSize.values.length * 2 - 1, + (int index) { + final int derivedIndex = index ~/ 2; + + return index.isEven + ? Text( + MoonTextSize.values[derivedIndex].name, + style: style == MoonTextStyle.body + ? getBodyTextStyle( + context, + MoonTextSize.values[derivedIndex], + ) + : getHeadingTextStyle( + context, + MoonTextSize.values[derivedIndex], + ), + ) + : const SizedBox(height: 8.0); + }, + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final bool showLogo = + MediaQuery.of(context).size.width < storybookAutoLayoutThreshold; + + return Scaffold( + backgroundColor: Colors.white, + body: SingleChildScrollView( + padding: EdgeInsets.only( + top: showLogo ? 40.0 : 80, + left: 24, + right: 24, + bottom: 16.0, + ), + child: SelectionArea( + child: Center( + child: SizedBox( + width: largeScreenWidth, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: mediumScreenWidth, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionHeader( + context, + TypographyPageSection.typography, + ), + const SizedBox(height: 48.0), + _buildSectionHeader( + context, + TypographyPageSection.body, + ), + _buildTypographyContainer(context, MoonTextStyle.body), + const SizedBox(height: 48.0), + _buildSectionHeader( + context, + TypographyPageSection.heading, + ), + _buildTypographyContainer( + context, + MoonTextStyle.heading, + ), + const Center( + child: PageFooter(), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/example/lib/src/storybook/common/typography_page_options.dart b/example/lib/src/storybook/common/typography_page_options.dart new file mode 100644 index 00000000..793eec77 --- /dev/null +++ b/example/lib/src/storybook/common/typography_page_options.dart @@ -0,0 +1,91 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:moon_design/moon_design.dart'; + +enum MoonTextStyle { + body, + heading, +} + +enum MoonTextSize { + size6, + size8, + size9, + size10, + size12, + size14, + size16, + size18, + size20, + size24, + size32, + size40, + size48, + size56, + size64, + size72; + + String get name { + final String rawName = toString().split('.').last; + return rawName.replaceFirst('size', 'Size '); + } +} + +TextStyle getBodyTextStyle(BuildContext context, MoonTextSize textSize) => + switch (textSize) { + MoonTextSize.size6 => context.moonTypography!.body.text6, + MoonTextSize.size8 => context.moonTypography!.body.text8, + MoonTextSize.size9 => context.moonTypography!.body.text9, + MoonTextSize.size10 => context.moonTypography!.body.text10, + MoonTextSize.size12 => context.moonTypography!.body.text12, + MoonTextSize.size14 => context.moonTypography!.body.text14, + MoonTextSize.size16 => context.moonTypography!.body.text16, + MoonTextSize.size18 => context.moonTypography!.body.text18, + MoonTextSize.size20 => context.moonTypography!.body.text20, + MoonTextSize.size24 => context.moonTypography!.body.text24, + MoonTextSize.size32 => context.moonTypography!.body.text32, + MoonTextSize.size40 => context.moonTypography!.body.text40, + MoonTextSize.size48 => context.moonTypography!.body.text48, + MoonTextSize.size56 => context.moonTypography!.body.text56, + MoonTextSize.size64 => context.moonTypography!.body.text64, + MoonTextSize.size72 => context.moonTypography!.body.text72, + }; + +TextStyle getHeadingTextStyle(BuildContext context, MoonTextSize textSize) => + switch (textSize) { + MoonTextSize.size6 => context.moonTypography!.heading.text6, + MoonTextSize.size8 => context.moonTypography!.heading.text8, + MoonTextSize.size9 => context.moonTypography!.heading.text9, + MoonTextSize.size10 => context.moonTypography!.heading.text10, + MoonTextSize.size12 => context.moonTypography!.heading.text12, + MoonTextSize.size14 => context.moonTypography!.heading.text14, + MoonTextSize.size16 => context.moonTypography!.heading.text16, + MoonTextSize.size18 => context.moonTypography!.heading.text18, + MoonTextSize.size20 => context.moonTypography!.heading.text20, + MoonTextSize.size24 => context.moonTypography!.heading.text24, + MoonTextSize.size32 => context.moonTypography!.heading.text32, + MoonTextSize.size40 => context.moonTypography!.heading.text40, + MoonTextSize.size48 => context.moonTypography!.heading.text48, + MoonTextSize.size56 => context.moonTypography!.heading.text56, + MoonTextSize.size64 => context.moonTypography!.heading.text64, + MoonTextSize.size72 => context.moonTypography!.heading.text72, + }; + +enum TypographyPageSection { + typography, + body, + heading; + + String get titleText => switch (this) { + typography => 'Typography', + body => 'Body', + heading => 'Heading', + }; + + String get bodyText => switch (this) { + typography => 'Moon typography includes body and heading text styles. ' + 'The body and header text styles have a set font size, while the ' + 'heading text style also includes a semibold font weight.', + _ => '', + }; +} diff --git a/example/lib/src/storybook/routing/app_router.dart b/example/lib/src/storybook/routing/app_router.dart index 9e1c6485..ea2f1e14 100644 --- a/example/lib/src/storybook/routing/app_router.dart +++ b/example/lib/src/storybook/routing/app_router.dart @@ -1,5 +1,6 @@ import 'package:example/src/storybook/common/pages/colors_page.dart'; import 'package:example/src/storybook/common/pages/home_page.dart'; +import 'package:example/src/storybook/common/pages/typography_page.dart'; import 'package:example/src/storybook/common/widgets/routing_error_widget.dart'; import 'package:example/src/storybook/stories/composites/combobox_multi_select.dart'; import 'package:example/src/storybook/stories/composites/combobox_single_select.dart'; @@ -93,6 +94,12 @@ GoRouter router = GoRouter( child: ColorsPage(), ), ), + GoRoute( + path: TypographyPage.path, + pageBuilder: (BuildContext _, GoRouterState __) => const NoTransitionPage( + child: TypographyPage(), + ), + ), // Stories. GoRoute( diff --git a/example/lib/src/storybook/routing/route_aware_stories.dart b/example/lib/src/storybook/routing/route_aware_stories.dart index cf7b00f4..58138591 100644 --- a/example/lib/src/storybook/routing/route_aware_stories.dart +++ b/example/lib/src/storybook/routing/route_aware_stories.dart @@ -1,5 +1,6 @@ import 'package:example/src/storybook/common/pages/colors_page.dart'; import 'package:example/src/storybook/common/pages/home_page.dart'; +import 'package:example/src/storybook/common/pages/typography_page.dart'; import 'package:example/src/storybook/routing/app_router.dart'; import 'package:example/src/storybook/stories/composites/combobox_multi_select.dart'; import 'package:example/src/storybook/stories/composites/combobox_single_select.dart'; @@ -51,13 +52,18 @@ final List routeAwareStories = [ router: router, isPage: true, ), - Story.asRoute( name: 'Colors', routePath: ColorsPage.path, router: router, isPage: true, ), + Story.asRoute( + name: 'Typography', + routePath: TypographyPage.path, + router: router, + isPage: true, + ), // Composite stories. Story.asRoute(