diff --git a/.github/actions/publish/action.yml b/.github/actions/publish/action.yml index 835a8a48..295a8203 100644 --- a/.github/actions/publish/action.yml +++ b/.github/actions/publish/action.yml @@ -15,7 +15,7 @@ runs: - name: Setup Flutter uses: subosito/flutter-action@v2 with: - flutter-version: 3.24.2 + flutter-version: 3.27.1 - name: Get ID Token uses: actions/github-script@v6 diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 19e7126e..b944516e 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -6,7 +6,7 @@ runs: - name: Set up Flutter uses: subosito/flutter-action@ea686d7c56499339ad176e9f19c516ff6cf05a31 with: - flutter-version: 3.24.2 + flutter-version: 3.27.1 cache: true - name: Set up environment paths diff --git a/.github/workflows/clean-azure-blob.yml b/.github/workflows/clean-azure-blob.yml index 937a8d91..42374946 100644 --- a/.github/workflows/clean-azure-blob.yml +++ b/.github/workflows/clean-azure-blob.yml @@ -1,13 +1,13 @@ -name: clean-azure-blob +name: Clean Widgetbook Azure Blob on: workflow_dispatch: permissions: - id-token: write # This is required for requesting the JWT - contents: read # This is required for actions/checkout + id-token: write + contents: read jobs: - deploy_widgetbook_azure: + clean-azure-blob: runs-on: ubuntu-latest steps: @@ -21,8 +21,20 @@ jobs: tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - name: Clean widgetbook blob folder + - name: List blobs before cleanup uses: azure/CLI@v2 with: inlineScript: | - az storage blob delete-batch --source mews-ui-widgetbook --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login + az storage blob list --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login --container-name mews-ui-widgetbook --output table + + - name: Clean Widgetbook blob folder + uses: azure/CLI@v2 + with: + inlineScript: | + az storage blob delete-batch --source mews-ui-widgetbook --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login --pattern "*" + + - name: List blobs after cleanup + uses: azure/CLI@v2 + with: + inlineScript: | + az storage blob list --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login --container-name mews-ui-widgetbook --output table diff --git a/.github/workflows/deploy-widgetbook-azure.yml b/.github/workflows/deploy-widgetbook-azure.yml index 044992b7..f6d10f8a 100644 --- a/.github/workflows/deploy-widgetbook-azure.yml +++ b/.github/workflows/deploy-widgetbook-azure.yml @@ -14,6 +14,7 @@ permissions: jobs: deploy_widgetbook_azure: + name: Build and deploy optimus_widgetbook to Azure runs-on: ubuntu-latest steps: @@ -32,7 +33,7 @@ jobs: - name: Build Web run: | - melos exec --scope="optimus_widgetbook" -- "flutter build web" + melos exec --scope="optimus_widgetbook" -- "flutter build web --base-href '/app/'" - name: Modify manifest.json run: | @@ -44,8 +45,19 @@ jobs: inlineScript: | az storage blob upload --overwrite true --container-name mews-ui-widgetbook --file optimus_widgetbook/build/web/manifest.json --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login - - name: Upload to blob storage release folder + - name: Upload index.html to the release folder uses: azure/CLI@v2 with: inlineScript: | - az storage blob upload-batch --overwrite true --destination mews-ui-widgetbook/release --source optimus_widgetbook/build/web --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login + az storage blob upload --overwrite true --container-name mews-ui-widgetbook --file optimus_widgetbook/build/web/index.html --name release/index.html --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login + + - name: Remove uploaded files before the batch upload + run: | + rm optimus_widgetbook/build/web/manifest.json + rm optimus_widgetbook/build/web/index.html + + - name: Upload assets to the app folder + uses: azure/CLI@v2 + with: + inlineScript: | + az storage blob upload-batch --overwrite true --destination mews-ui-widgetbook/release/app --source optimus_widgetbook/build/web --account-name ${{ secrets.AZURE_ACCOUNT_NAME }} --auth-mode login diff --git a/kiosk_mode/example/pubspec.yaml b/kiosk_mode/example/pubspec.yaml index 0747818f..0d131bef 100644 --- a/kiosk_mode/example/pubspec.yaml +++ b/kiosk_mode/example/pubspec.yaml @@ -16,6 +16,6 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mews_pedantic: ^0.34.0 + mews_pedantic: ^0.35.0 flutter: uses-material-design: true diff --git a/kiosk_mode/pubspec.yaml b/kiosk_mode/pubspec.yaml index 4ddc9747..9fe3a636 100644 --- a/kiosk_mode/pubspec.yaml +++ b/kiosk_mode/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mews_pedantic: ^0.34.0 + mews_pedantic: ^0.35.0 flutter: plugin: platforms: diff --git a/mews_pedantic/CHANGELOG.md b/mews_pedantic/CHANGELOG.md index 7dfd05c1..da66260c 100644 --- a/mews_pedantic/CHANGELOG.md +++ b/mews_pedantic/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.35.0 + +> Note: This release has breaking changes. + + - **BREAKING** **FEAT**: [DX-3716] Upgrade to DCM 1.26.0. + ## 0.34.0 > Note: This release has breaking changes. diff --git a/mews_pedantic/pubspec.yaml b/mews_pedantic/pubspec.yaml index 19e109bd..b9df8be6 100644 --- a/mews_pedantic/pubspec.yaml +++ b/mews_pedantic/pubspec.yaml @@ -1,6 +1,6 @@ name: mews_pedantic description: Dart and Flutter static analysis and lint rules incorporated in Mews. -version: 0.34.0 +version: 0.35.0 repository: https://github.com/MewsSystems/mews-flutter environment: diff --git a/optimus/CHANGELOG.md b/optimus/CHANGELOG.md index e2466e6a..a6269f4c 100644 --- a/optimus/CHANGELOG.md +++ b/optimus/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.38.3+1 + + - **FIX**: Fix linter issues. + ## 0.38.3 - **FEAT**: [DX-3575] Add groups support to OptimusSelectInputFormField (#715). diff --git a/optimus/example/pubspec.yaml b/optimus/example/pubspec.yaml index 730ed1f8..782af767 100644 --- a/optimus/example/pubspec.yaml +++ b/optimus/example/pubspec.yaml @@ -15,4 +15,4 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mews_pedantic: ^0.34.0 + mews_pedantic: ^0.35.0 diff --git a/optimus/lib/src/avatar/avatar.dart b/optimus/lib/src/avatar/avatar.dart index d3dfb784..a4cb9c9b 100644 --- a/optimus/lib/src/avatar/avatar.dart +++ b/optimus/lib/src/avatar/avatar.dart @@ -15,6 +15,7 @@ class OptimusAvatar extends StatelessWidget { this.badgeUrl, this.isIndicatorVisible = false, this.size = OptimusWidgetSize.medium, + this.alignment = AlignmentDirectional.center, }); /// The title of the avatar. The title is displayed when the image is not @@ -38,6 +39,10 @@ class OptimusAvatar extends StatelessWidget { /// The size of the avatar. final OptimusWidgetSize size; + /// The alignment of th Avatar inside its Stack. Defaults to + /// [AlignmentDirectional.center]. + final AlignmentDirectional alignment; + bool get _isVisibleForSize => size == OptimusWidgetSize.medium || size == OptimusWidgetSize.large; @@ -57,6 +62,7 @@ class OptimusAvatar extends StatelessWidget { return Stack( clipBehavior: Clip.none, + alignment: alignment, children: [ _CircleImage( imageUrl: imageUrl, diff --git a/optimus/lib/src/common/field_wrapper.dart b/optimus/lib/src/common/field_wrapper.dart index c01d03df..7a4f039c 100644 --- a/optimus/lib/src/common/field_wrapper.dart +++ b/optimus/lib/src/common/field_wrapper.dart @@ -503,7 +503,7 @@ class _ColoredTransitionState extends State<_ColoredTransition> { color: widget.state == OptimusStatusBarState.empty ? _previousState .getStatusBarColor(context.tokens) - .withOpacity(0.5) + .withValues(alpha: 0.5) : widget.state.getStatusBarColor(context.tokens), ), ); diff --git a/optimus/lib/src/common/gesture_detector.dart b/optimus/lib/src/common/gesture_detector.dart index df81432a..fa2cd46f 100644 --- a/optimus/lib/src/common/gesture_detector.dart +++ b/optimus/lib/src/common/gesture_detector.dart @@ -5,16 +5,20 @@ class AllowMultipleRawGestureDetector extends RawGestureDetector { AllowMultipleRawGestureDetector({ super.key, GestureTapCallback? onTap, + GestureTapDownCallback? onTapDown, + super.behavior = HitTestBehavior.opaque, super.child, }) : super( - behavior: HitTestBehavior.opaque, gestures: { AllowMultipleGestureRecognizer: GestureRecognizerFactoryWithHandlers< AllowMultipleGestureRecognizer>( AllowMultipleGestureRecognizer.new, - (AllowMultipleGestureRecognizer instance) => - instance.onTap = onTap, + (AllowMultipleGestureRecognizer instance) { + instance + ..onTap = onTap + ..onTapDown = onTapDown; + }, ), }, ); diff --git a/optimus/lib/src/common/state_property.dart b/optimus/lib/src/common/state_property.dart deleted file mode 100644 index 3ea11d5a..00000000 --- a/optimus/lib/src/common/state_property.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class InteractiveStateColor extends WidgetStateProperty { - InteractiveStateColor({ - required this.defaultColor, - required this.disabled, - required this.pressed, - required this.hovered, - }); - - final Color disabled; - final Color pressed; - final Color hovered; - final Color defaultColor; - - @override - Color resolve(Set states) { - if (states.isDisabled) return disabled; - if (states.isPressed) return pressed; - if (states.isHovered) return hovered; - - return defaultColor; - } -} - -extension States on Set { - bool get isDisabled => contains(WidgetState.disabled); - bool get isPressed => contains(WidgetState.pressed); - bool get isHovered => contains(WidgetState.hovered); -} diff --git a/optimus/lib/src/dropdown/dropdown_select.dart b/optimus/lib/src/dropdown/dropdown_select.dart index aa29545b..cb3100f3 100644 --- a/optimus/lib/src/dropdown/dropdown_select.dart +++ b/optimus/lib/src/dropdown/dropdown_select.dart @@ -94,7 +94,8 @@ class DropdownSelect extends StatefulWidget { State> createState() => _DropdownSelectState(); } -class _DropdownSelectState extends State> { +class _DropdownSelectState extends State> + with WidgetsBindingObserver { final _fieldBoxKey = GlobalKey(); FocusNode? _focusNode; @@ -111,6 +112,7 @@ class _DropdownSelectState extends State> { @override void initState() { super.initState(); + WidgetsBinding.instance.addObserver(this); _effectiveFocusNode.addListener(_onFocusChanged); } @@ -120,8 +122,22 @@ class _DropdownSelectState extends State> { } } + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + super.didChangeAppLifecycleState(state); + switch (state) { + case AppLifecycleState.paused: + case AppLifecycleState.detached: + _removeOverlay(); + case AppLifecycleState.resumed: + case AppLifecycleState.inactive: + case AppLifecycleState.hidden: + } + } + @override void dispose() { + WidgetsBinding.instance.removeObserver(this); _effectiveFocusNode.removeListener(_onFocusChanged); _focusNode?.dispose(); _controller?.dispose(); @@ -262,7 +278,7 @@ class _DropdownSelectState extends State> { } } - return GestureDetector( + return AllowMultipleRawGestureDetector( key: const Key('OptimusDropdownOverlay'), behavior: HitTestBehavior.translucent, onTapDown: handleTapDown, diff --git a/optimus/lib/src/lists/list_tile.dart b/optimus/lib/src/lists/list_tile.dart index b7b3d059..72e08517 100644 --- a/optimus/lib/src/lists/list_tile.dart +++ b/optimus/lib/src/lists/list_tile.dart @@ -26,6 +26,8 @@ class OptimusListTile extends StatelessWidget { this.onTap, this.fontVariant = FontVariant.normal, this.contentPadding, + this.prefixSize = OptimusPrefixSize.medium, + this.prefixVerticalAlignment, }); /// Communicates the subject of the list item. @@ -43,6 +45,14 @@ class OptimusListTile extends StatelessWidget { /// The Widget to be displayed on the leading position. Typically an [Icon]. final Widget? prefix; + /// The size of the prefix widget. Defaults to [OptimusPrefixSize.medium]. + final OptimusPrefixSize prefixSize; + + /// The vertical alignment of the prefix. By default it would align to the top, + /// but if there is a [suffix] is would align to the center. Providing + /// prefixVerticalAlignment will override the alignment. + final OptimusPrefixVerticalAlignment? prefixVerticalAlignment; + /// The Widget to be displayed on the tailoring position. Typically an [Icon]. final Widget? suffix; @@ -65,6 +75,12 @@ class OptimusListTile extends StatelessWidget { /// will be used. final EdgeInsets? contentPadding; + OptimusPrefixVerticalAlignment get _prefixVerticalAlignment => + prefixVerticalAlignment ?? + (subtitle != null + ? OptimusPrefixVerticalAlignment.start + : OptimusPrefixVerticalAlignment.center); + EdgeInsets _getContentPadding(OptimusTokens tokens) => contentPadding ?? EdgeInsets.symmetric( @@ -75,8 +91,6 @@ class OptimusListTile extends StatelessWidget { @override Widget build(BuildContext context) { final tokens = context.tokens; - final info = this.info; - final subtitle = this.subtitle; return BaseListTile( onTap: onTap, @@ -85,47 +99,47 @@ class OptimusListTile extends StatelessWidget { child: Stack( children: [ if (prefix case final prefix?) - Padding( - padding: EdgeInsetsDirectional.only( - top: subtitle != null ? tokens.spacing100 : tokens.spacing25, - ), - child: _Prefix(prefix: prefix), + Positioned( + top: tokens.spacing0, + bottom: _prefixVerticalAlignment.getBottom(tokens), + child: _Prefix(prefix: prefix, size: prefixSize), ), Row( - children: [ - if (prefix != null) SizedBox(width: context.prefixWidth), + children: [ + if (prefix != null) + SizedBox(width: prefixSize.getWidth(tokens)), Expanded( child: Padding( padding: EdgeInsets.only(right: tokens.spacing100), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ Flexible( - flex: 8, child: _Title( title: title, fontVariant: fontVariant, ), ), - if (info != null) - Flexible(flex: 2, child: _Info(info: info)), + if (info case final info?) + Flexible(child: _Info(info: info)), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: subtitle != null - ? _Subtitle( - subtitle: subtitle, - fontVariant: fontVariant, - ) - : const SizedBox.shrink(), - ), + children: [ + if (subtitle case final subtitle?) + Expanded( + child: _Subtitle( + subtitle: subtitle, + fontVariant: fontVariant, + ), + ) + else + const Spacer(), if (infoWidget case final infoWidget?) infoWidget, ], ), @@ -143,17 +157,25 @@ class OptimusListTile extends StatelessWidget { } } +enum OptimusPrefixVerticalAlignment { center, start } + +enum OptimusPrefixSize { medium, large } + class _Prefix extends StatelessWidget { - const _Prefix({required this.prefix}); + const _Prefix({ + required this.prefix, + this.size = OptimusPrefixSize.medium, + }); final Widget prefix; + final OptimusPrefixSize size; @override Widget build(BuildContext context) { final tokens = context.tokens; return SizedBox( - width: context.prefixWidth, + width: size.getWidth(tokens), child: Padding( padding: EdgeInsets.only(right: tokens.spacing100), child: OptimusTypography( @@ -188,14 +210,10 @@ class _Title extends StatelessWidget { final FontVariant fontVariant; @override - Widget build(BuildContext context) { - final tokens = context.tokens; - - return OptimusTypography( - resolveStyle: (_) => fontVariant.getPrimaryStyle(tokens), - child: title, - ); - } + Widget build(BuildContext context) => OptimusTypography( + resolveStyle: (_) => fontVariant.getPrimaryStyle(context.tokens), + child: title, + ); } class _Info extends StatelessWidget { @@ -226,6 +244,16 @@ class _Subtitle extends StatelessWidget { ); } -extension on BuildContext { - double get prefixWidth => tokens.spacing400; +extension on OptimusPrefixSize { + double getWidth(OptimusTokens tokens) => switch (this) { + OptimusPrefixSize.medium => tokens.sizing400, + OptimusPrefixSize.large => tokens.sizing600, + }; +} + +extension on OptimusPrefixVerticalAlignment { + double? getBottom(OptimusTokens tokens) => switch (this) { + OptimusPrefixVerticalAlignment.center => tokens.spacing0, + OptimusPrefixVerticalAlignment.start => null, + }; } diff --git a/optimus/lib/src/lists/nav_list_tile.dart b/optimus/lib/src/lists/nav_list_tile.dart index 5064ff4c..2935c358 100644 --- a/optimus/lib/src/lists/nav_list_tile.dart +++ b/optimus/lib/src/lists/nav_list_tile.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:optimus/optimus.dart'; import 'package:optimus/src/common/gesture_wrapper.dart'; -import 'package:optimus/src/common/state_property.dart'; import 'package:optimus/src/lists/base_list_tile.dart'; /// Lists are vertically organized groups of data. Optimized for reading @@ -83,12 +82,12 @@ class _OptimusNavListTileState extends State } } - InteractiveStateColor get _backgroundColor => InteractiveStateColor( - defaultColor: tokens.backgroundInteractiveNeutralSubtleDefault, - disabled: Colors.transparent, - pressed: tokens.backgroundInteractiveNeutralSubtleActive, - hovered: tokens.backgroundInteractiveNeutralSubtleHover, - ); + WidgetStateColor get _backgroundColor => WidgetStateColor.fromMap({ + WidgetState.disabled: Colors.transparent, + WidgetState.pressed: tokens.backgroundInteractiveNeutralSubtleActive, + WidgetState.hovered: tokens.backgroundInteractiveNeutralSubtleHover, + WidgetState.any: tokens.backgroundInteractiveNeutralSubtleDefault, + }); void _handleHoverChanged(bool isHovered) { setState(() => _controller.update(WidgetState.hovered, isHovered)); diff --git a/optimus/lib/src/radio/radio_circle.dart b/optimus/lib/src/radio/radio_circle.dart index 9b90b63c..7045de71 100644 --- a/optimus/lib/src/radio/radio_circle.dart +++ b/optimus/lib/src/radio/radio_circle.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:optimus/optimus.dart'; -import 'package:optimus/src/common/state_property.dart'; class RadioCircle extends StatelessWidget { const RadioCircle({ @@ -13,28 +12,28 @@ class RadioCircle extends StatelessWidget { final bool isSelected; final WidgetStatesController controller; - InteractiveStateColor _getBorderColor(OptimusTokens tokens) => - InteractiveStateColor( - defaultColor: isSelected - ? tokens.backgroundInteractivePrimaryDefault - : tokens.borderInteractiveSecondaryDefault, - disabled: + WidgetStateColor _getBorderColor(OptimusTokens tokens) => + WidgetStateColor.fromMap({ + WidgetState.disabled: isSelected ? tokens.backgroundDisabled : tokens.borderDisabled, - pressed: isSelected + WidgetState.pressed: isSelected ? tokens.backgroundInteractivePrimaryActive : tokens.borderInteractiveSecondaryActive, - hovered: isSelected + WidgetState.hovered: isSelected ? tokens.backgroundInteractivePrimaryHover : tokens.borderInteractiveSecondaryHover, - ); + WidgetState.any: isSelected + ? tokens.backgroundInteractivePrimaryDefault + : tokens.borderInteractiveSecondaryDefault, + }); - InteractiveStateColor _getFillColor(OptimusTokens tokens) => - InteractiveStateColor( - defaultColor: tokens.backgroundInteractiveNeutralSubtleDefault, - disabled: tokens.backgroundInteractiveNeutralSubtleDefault, - pressed: tokens.backgroundInteractiveNeutralSubtleActive, - hovered: tokens.backgroundInteractiveNeutralSubtleHover, - ); + WidgetStateColor _getFillColor(OptimusTokens tokens) => + WidgetStateColor.fromMap({ + WidgetState.disabled: tokens.backgroundInteractiveNeutralSubtleDefault, + WidgetState.pressed: tokens.backgroundInteractiveNeutralSubtleActive, + WidgetState.hovered: tokens.backgroundInteractiveNeutralSubtleHover, + WidgetState.any: tokens.backgroundInteractiveNeutralSubtleDefault, + }); @override Widget build(BuildContext context) { diff --git a/optimus/lib/src/selection_card.dart b/optimus/lib/src/selection_card.dart index 5707cc71..3a274c3a 100644 --- a/optimus/lib/src/selection_card.dart +++ b/optimus/lib/src/selection_card.dart @@ -3,7 +3,6 @@ import 'package:flutter/widgets.dart'; import 'package:optimus/optimus.dart'; import 'package:optimus/src/checkbox/checkbox_tick.dart'; import 'package:optimus/src/common/gesture_wrapper.dart'; -import 'package:optimus/src/common/state_property.dart'; import 'package:optimus/src/radio/radio_circle.dart'; enum OptimusSelectionCardVariant { vertical, horizontal } @@ -75,45 +74,41 @@ class _OptimusSelectionCardState extends State super.dispose(); } - InteractiveStateColor get _backgroundColor => InteractiveStateColor( - defaultColor: widget.isSelected - ? tokens.backgroundInteractiveSecondaryDefault - : tokens.backgroundStaticFlat, - disabled: tokens.backgroundStaticFlat, - pressed: widget.isSelected + WidgetStateColor get _backgroundColor => WidgetStateColor.fromMap({ + WidgetState.disabled: tokens.backgroundStaticFlat, + WidgetState.pressed: widget.isSelected ? tokens.backgroundInteractiveSecondaryActive : tokens.backgroundStaticFlat, - hovered: widget.isSelected + WidgetState.hovered: widget.isSelected ? tokens.backgroundInteractiveSecondaryHover : tokens.backgroundStaticFlat, - ); + WidgetState.any: widget.isSelected + ? tokens.backgroundInteractiveSecondaryDefault + : tokens.backgroundStaticFlat, + }); - InteractiveStateColor get _borderColor => InteractiveStateColor( - defaultColor: widget.isSelected - ? tokens.borderInteractivePrimaryDefault - : tokens.borderInteractiveSecondaryDefault, - disabled: tokens.borderDisabled, - pressed: widget.isSelected + WidgetStateColor get _borderColor => WidgetStateColor.fromMap({ + WidgetState.disabled: tokens.borderDisabled, + WidgetState.pressed: widget.isSelected ? tokens.borderInteractivePrimaryActive : tokens.borderInteractiveSecondaryActive, - hovered: widget.isSelected + WidgetState.hovered: widget.isSelected ? tokens.borderInteractivePrimaryHover : tokens.borderInteractiveSecondaryHover, - ); + WidgetState.any: widget.isSelected + ? tokens.borderInteractivePrimaryDefault + : tokens.borderInteractiveSecondaryDefault, + }); - InteractiveStateColor get _titleColor => InteractiveStateColor( - defaultColor: tokens.textStaticPrimary, - disabled: tokens.textDisabled, - pressed: tokens.textStaticPrimary, - hovered: tokens.textStaticPrimary, - ); + WidgetStateColor get _titleColor => WidgetStateColor.fromMap({ + WidgetState.disabled: tokens.textDisabled, + WidgetState.any: tokens.textStaticPrimary, + }); - InteractiveStateColor get _descriptionColor => InteractiveStateColor( - defaultColor: tokens.textStaticTertiary, - disabled: tokens.textDisabled, - pressed: tokens.textStaticTertiary, - hovered: tokens.textStaticTertiary, - ); + WidgetStateColor get _descriptionColor => WidgetStateColor.fromMap({ + WidgetState.disabled: tokens.textDisabled, + WidgetState.any: tokens.textStaticTertiary, + }); @override void didUpdateWidget(covariant OptimusSelectionCard oldWidget) { diff --git a/optimus/lib/src/tabs.dart b/optimus/lib/src/tabs.dart index da0134b1..d515a983 100644 --- a/optimus/lib/src/tabs.dart +++ b/optimus/lib/src/tabs.dart @@ -35,7 +35,6 @@ class OptimusTab extends StatelessWidget { final tokens = context.tokens; return Container( - padding: EdgeInsets.symmetric(horizontal: tokens.spacing150), height: tokens.sizing600, constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity), child: Row( @@ -72,12 +71,25 @@ class OptimusTabBar extends StatelessWidget { required this.tabs, required this.pages, this.tabController, + this.isScrollable = false, + this.tabPadding, }); + /// The list of child tabs. final List tabs; + + /// The list of child pages. final List pages; + + /// The optional tab controller, for adding listeners and control the tab flow. final TabController? tabController; + /// Defines if the [OptimusTabBar] is scrollable. The scroll is enabled in the horizontal axis only. + final bool isScrollable; + + /// A padding between tabs. If not provided, the default padding will be used. + final EdgeInsets? tabPadding; + Decoration _buildIndicator(OptimusTokens tokens) => UnderlineTabIndicator( borderSide: BorderSide( color: tokens.borderInteractivePrimaryDefault, @@ -86,6 +98,11 @@ class OptimusTabBar extends StatelessWidget { insets: const EdgeInsets.only(bottom: -1), ); + TabAlignment? get _tabAlignment => isScrollable ? null : TabAlignment.fill; + + EdgeInsets _getLabelPadding(OptimusTokens tokens) => + tabPadding ?? EdgeInsets.symmetric(horizontal: tokens.spacing150); + @override Widget build(BuildContext context) { final tokens = context.tokens; @@ -94,7 +111,7 @@ class OptimusTabBar extends StatelessWidget { return DefaultTabController( length: tabs.length, child: Column( - children: [ + children: [ DecoratedBox( decoration: BoxDecoration( border: Border( @@ -115,8 +132,10 @@ class OptimusTabBar extends StatelessWidget { unselectedLabelStyle: textStyle, labelStyle: textStyle, splashBorderRadius: null, + isScrollable: isScrollable, splashFactory: NoSplash.splashFactory, - labelPadding: EdgeInsets.zero, + labelPadding: _getLabelPadding(tokens), + tabAlignment: _tabAlignment, ), ), ), diff --git a/optimus/lib/src/theme/optimus_tokens.dart b/optimus/lib/src/theme/optimus_tokens.dart index 74a54614..8f71434f 100644 --- a/optimus/lib/src/theme/optimus_tokens.dart +++ b/optimus/lib/src/theme/optimus_tokens.dart @@ -10,7 +10,7 @@ import 'package:theme_tailor_annotation/theme_tailor_annotation.dart'; // // Do not edit directly -// Generated on Mon, 25 Nov 2024 17:43:45 GMT +// Generated on Tue, 04 Feb 2025 11:35:50 GMT part 'optimus_tokens.tailor.dart'; @@ -407,16 +407,15 @@ class OptimusTokens extends ThemeExtension required this.spacing800, required this.spacing900, required this.spacingBase, - required this.focusOffset, - required this.shadow0, - required this.shadow100, - required this.shadow200, - required this.shadow300, required this.fontFamilyUi, required this.fontWeight300, required this.fontWeight400, required this.fontWeight500, required this.fontWeight600, + required this.shadow0, + required this.shadow100, + required this.shadow200, + required this.shadow300, required this.textDecorationUnderline, }); @@ -1202,17 +1201,6 @@ class OptimusTokens extends ThemeExtension @override final double spacingBase; - @override - final List focusOffset; - @override - final List shadow0; - @override - final List shadow100; - @override - final List shadow200; - @override - final List shadow300; - @override final String fontFamilyUi; @@ -1225,6 +1213,15 @@ class OptimusTokens extends ThemeExtension @override final FontWeight fontWeight600; + @override + final List shadow0; + @override + final List shadow100; + @override + final List shadow200; + @override + final List shadow300; + @override final TextDecoration textDecorationUnderline; @@ -1662,16 +1659,15 @@ class OptimusTokens extends ThemeExtension spacing800: DesignTokensLight.spacing800, spacing900: DesignTokensLight.spacing900, spacingBase: DesignTokensLight.spacingBase, - focusOffset: DesignTokensLight.focusOffset, - shadow0: DesignTokensLight.shadow0, - shadow100: DesignTokensLight.shadow100, - shadow200: DesignTokensLight.shadow200, - shadow300: DesignTokensLight.shadow300, fontFamilyUi: DesignTokensLight.fontFamilyUi, fontWeight300: DesignTokensLight.fontWeight300, fontWeight400: DesignTokensLight.fontWeight400, fontWeight500: DesignTokensLight.fontWeight500, fontWeight600: DesignTokensLight.fontWeight600, + shadow0: DesignTokensLight.shadow0, + shadow100: DesignTokensLight.shadow100, + shadow200: DesignTokensLight.shadow200, + shadow300: DesignTokensLight.shadow300, textDecorationUnderline: DesignTokensLight.textDecorationUnderline, ); @@ -2103,16 +2099,15 @@ class OptimusTokens extends ThemeExtension spacing800: DesignTokensDark.spacing800, spacing900: DesignTokensDark.spacing900, spacingBase: DesignTokensDark.spacingBase, - focusOffset: DesignTokensDark.focusOffset, - shadow0: DesignTokensDark.shadow0, - shadow100: DesignTokensDark.shadow100, - shadow200: DesignTokensDark.shadow200, - shadow300: DesignTokensDark.shadow300, fontFamilyUi: DesignTokensDark.fontFamilyUi, fontWeight300: DesignTokensDark.fontWeight300, fontWeight400: DesignTokensDark.fontWeight400, fontWeight500: DesignTokensDark.fontWeight500, fontWeight600: DesignTokensDark.fontWeight600, + shadow0: DesignTokensDark.shadow0, + shadow100: DesignTokensDark.shadow100, + shadow200: DesignTokensDark.shadow200, + shadow300: DesignTokensDark.shadow300, textDecorationUnderline: DesignTokensDark.textDecorationUnderline, ); } diff --git a/optimus/lib/src/theme/optimus_tokens.tailor.dart b/optimus/lib/src/theme/optimus_tokens.tailor.dart index 68f0a702..4465b498 100644 --- a/optimus/lib/src/theme/optimus_tokens.tailor.dart +++ b/optimus/lib/src/theme/optimus_tokens.tailor.dart @@ -398,16 +398,15 @@ mixin _$OptimusTokensTailorMixin on ThemeExtension { double get spacing800; double get spacing900; double get spacingBase; - List get focusOffset; - List get shadow0; - List get shadow100; - List get shadow200; - List get shadow300; String get fontFamilyUi; FontWeight get fontWeight300; FontWeight get fontWeight400; FontWeight get fontWeight500; FontWeight get fontWeight600; + List get shadow0; + List get shadow100; + List get shadow200; + List get shadow300; TextDecoration get textDecorationUnderline; @override @@ -801,16 +800,15 @@ mixin _$OptimusTokensTailorMixin on ThemeExtension { double? spacing800, double? spacing900, double? spacingBase, - List? focusOffset, - List? shadow0, - List? shadow100, - List? shadow200, - List? shadow300, String? fontFamilyUi, FontWeight? fontWeight300, FontWeight? fontWeight400, FontWeight? fontWeight500, FontWeight? fontWeight600, + List? shadow0, + List? shadow100, + List? shadow200, + List? shadow300, TextDecoration? textDecorationUnderline, }) { return OptimusTokens( @@ -1403,16 +1401,15 @@ mixin _$OptimusTokensTailorMixin on ThemeExtension { spacing800: spacing800 ?? this.spacing800, spacing900: spacing900 ?? this.spacing900, spacingBase: spacingBase ?? this.spacingBase, - focusOffset: focusOffset ?? this.focusOffset, - shadow0: shadow0 ?? this.shadow0, - shadow100: shadow100 ?? this.shadow100, - shadow200: shadow200 ?? this.shadow200, - shadow300: shadow300 ?? this.shadow300, fontFamilyUi: fontFamilyUi ?? this.fontFamilyUi, fontWeight300: fontWeight300 ?? this.fontWeight300, fontWeight400: fontWeight400 ?? this.fontWeight400, fontWeight500: fontWeight500 ?? this.fontWeight500, fontWeight600: fontWeight600 ?? this.fontWeight600, + shadow0: shadow0 ?? this.shadow0, + shadow100: shadow100 ?? this.shadow100, + shadow200: shadow200 ?? this.shadow200, + shadow300: shadow300 ?? this.shadow300, textDecorationUnderline: textDecorationUnderline ?? this.textDecorationUnderline, ); @@ -2166,16 +2163,15 @@ mixin _$OptimusTokensTailorMixin on ThemeExtension { spacing800: t < 0.5 ? spacing800 : other.spacing800, spacing900: t < 0.5 ? spacing900 : other.spacing900, spacingBase: t < 0.5 ? spacingBase : other.spacingBase, - focusOffset: t < 0.5 ? focusOffset : other.focusOffset, - shadow0: t < 0.5 ? shadow0 : other.shadow0, - shadow100: t < 0.5 ? shadow100 : other.shadow100, - shadow200: t < 0.5 ? shadow200 : other.shadow200, - shadow300: t < 0.5 ? shadow300 : other.shadow300, fontFamilyUi: t < 0.5 ? fontFamilyUi : other.fontFamilyUi, fontWeight300: t < 0.5 ? fontWeight300 : other.fontWeight300, fontWeight400: t < 0.5 ? fontWeight400 : other.fontWeight400, fontWeight500: t < 0.5 ? fontWeight500 : other.fontWeight500, fontWeight600: t < 0.5 ? fontWeight600 : other.fontWeight600, + shadow0: t < 0.5 ? shadow0 : other.shadow0, + shadow100: t < 0.5 ? shadow100 : other.shadow100, + shadow200: t < 0.5 ? shadow200 : other.shadow200, + shadow300: t < 0.5 ? shadow300 : other.shadow300, textDecorationUnderline: t < 0.5 ? textDecorationUnderline : other.textDecorationUnderline, ); @@ -2603,16 +2599,15 @@ mixin _$OptimusTokensTailorMixin on ThemeExtension { const DeepCollectionEquality().equals(spacing800, other.spacing800) && const DeepCollectionEquality().equals(spacing900, other.spacing900) && const DeepCollectionEquality().equals(spacingBase, other.spacingBase) && - const DeepCollectionEquality().equals(focusOffset, other.focusOffset) && - const DeepCollectionEquality().equals(shadow0, other.shadow0) && - const DeepCollectionEquality().equals(shadow100, other.shadow100) && - const DeepCollectionEquality().equals(shadow200, other.shadow200) && - const DeepCollectionEquality().equals(shadow300, other.shadow300) && const DeepCollectionEquality().equals(fontFamilyUi, other.fontFamilyUi) && const DeepCollectionEquality().equals(fontWeight300, other.fontWeight300) && const DeepCollectionEquality().equals(fontWeight400, other.fontWeight400) && const DeepCollectionEquality().equals(fontWeight500, other.fontWeight500) && const DeepCollectionEquality().equals(fontWeight600, other.fontWeight600) && + const DeepCollectionEquality().equals(shadow0, other.shadow0) && + const DeepCollectionEquality().equals(shadow100, other.shadow100) && + const DeepCollectionEquality().equals(shadow200, other.shadow200) && + const DeepCollectionEquality().equals(shadow300, other.shadow300) && const DeepCollectionEquality().equals(textDecorationUnderline, other.textDecorationUnderline)); } @@ -3016,16 +3011,15 @@ mixin _$OptimusTokensTailorMixin on ThemeExtension { const DeepCollectionEquality().hash(spacing800), const DeepCollectionEquality().hash(spacing900), const DeepCollectionEquality().hash(spacingBase), - const DeepCollectionEquality().hash(focusOffset), - const DeepCollectionEquality().hash(shadow0), - const DeepCollectionEquality().hash(shadow100), - const DeepCollectionEquality().hash(shadow200), - const DeepCollectionEquality().hash(shadow300), const DeepCollectionEquality().hash(fontFamilyUi), const DeepCollectionEquality().hash(fontWeight300), const DeepCollectionEquality().hash(fontWeight400), const DeepCollectionEquality().hash(fontWeight500), const DeepCollectionEquality().hash(fontWeight600), + const DeepCollectionEquality().hash(shadow0), + const DeepCollectionEquality().hash(shadow100), + const DeepCollectionEquality().hash(shadow200), + const DeepCollectionEquality().hash(shadow300), const DeepCollectionEquality().hash(textDecorationUnderline), ]); } diff --git a/optimus/lib/src/tokens/tokens_dark.dart b/optimus/lib/src/tokens/tokens_dark.dart index 0a189c63..975dc8c2 100644 --- a/optimus/lib/src/tokens/tokens_dark.dart +++ b/optimus/lib/src/tokens/tokens_dark.dart @@ -4,7 +4,7 @@ // ignore_for_file: avoid-duplicate-constant-values // Do not edit directly -// Generated on Mon, 25 Nov 2024 17:43:45 GMT +// Generated on Tue, 04 Feb 2025 11:35:50 GMT import 'package:flutter/widgets.dart'; @@ -531,18 +531,13 @@ abstract final class DesignTokensDark { static const double spacing900 = 72; static const double spacingBase = 8; - static const List focusOffset = [ - BoxShadow( - offset: Offset.zero, - spreadRadius: 2, - color: Color(0xFFFFFFFF), - ), - BoxShadow( - offset: Offset.zero, - spreadRadius: 4, - color: Color(0xFF524FF2), - ), - ]; + static const String fontFamilyUi = 'Inter'; + + static const FontWeight fontWeight300 = FontWeight.w300; + static const FontWeight fontWeight400 = FontWeight.w400; + static const FontWeight fontWeight500 = FontWeight.w500; + static const FontWeight fontWeight600 = FontWeight.w600; + static const List shadow0 = [ BoxShadow( offset: Offset.zero, @@ -592,13 +587,6 @@ abstract final class DesignTokensDark { ), ]; - static const String fontFamilyUi = 'Inter'; - - static const FontWeight fontWeight300 = FontWeight.w300; - static const FontWeight fontWeight400 = FontWeight.w400; - static const FontWeight fontWeight500 = FontWeight.w500; - static const FontWeight fontWeight600 = FontWeight.w600; - static const TextDecoration textDecorationUnderline = TextDecoration.underline; diff --git a/optimus/lib/src/tokens/tokens_light.dart b/optimus/lib/src/tokens/tokens_light.dart index feafd264..4f20e8a0 100644 --- a/optimus/lib/src/tokens/tokens_light.dart +++ b/optimus/lib/src/tokens/tokens_light.dart @@ -4,7 +4,7 @@ // ignore_for_file: avoid-duplicate-constant-values // Do not edit directly -// Generated on Mon, 25 Nov 2024 17:43:45 GMT +// Generated on Tue, 04 Feb 2025 11:35:50 GMT import 'package:flutter/widgets.dart'; @@ -531,18 +531,13 @@ abstract final class DesignTokensLight { static const double spacing900 = 72; static const double spacingBase = 8; - static const List focusOffset = [ - BoxShadow( - offset: Offset.zero, - spreadRadius: 2, - color: Color(0xFFFFFFFF), - ), - BoxShadow( - offset: Offset.zero, - spreadRadius: 4, - color: Color(0xFF1613D7), - ), - ]; + static const String fontFamilyUi = 'Inter'; + + static const FontWeight fontWeight300 = FontWeight.w300; + static const FontWeight fontWeight400 = FontWeight.w400; + static const FontWeight fontWeight500 = FontWeight.w500; + static const FontWeight fontWeight600 = FontWeight.w600; + static const List shadow0 = [ BoxShadow( offset: Offset.zero, @@ -592,13 +587,6 @@ abstract final class DesignTokensLight { ), ]; - static const String fontFamilyUi = 'Inter'; - - static const FontWeight fontWeight300 = FontWeight.w300; - static const FontWeight fontWeight400 = FontWeight.w400; - static const FontWeight fontWeight500 = FontWeight.w500; - static const FontWeight fontWeight600 = FontWeight.w600; - static const TextDecoration textDecorationUnderline = TextDecoration.underline; diff --git a/optimus/pubspec.yaml b/optimus/pubspec.yaml index 7d905f2b..2a3b01c4 100644 --- a/optimus/pubspec.yaml +++ b/optimus/pubspec.yaml @@ -1,20 +1,20 @@ name: optimus description: Optimus is a design system for mobile platforms (and web in future) used internally in Mews. -version: 0.38.3 +version: 0.38.3+1 repository: https://github.com/MewsSystems/mews-flutter environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.24.0" + flutter: ">=3.27.0" dependencies: dfunc: ^0.10.0 flutter: sdk: flutter - flutter_slidable: ">=1.2.0 <4.0.0" + flutter_slidable: ">=1.2.0 <5.0.0" flutter_svg: ^2.0.7 freezed_annotation: ">=1.0.0 <3.0.0" - intl: ">=0.17.0 <0.20.0" + intl: ">=0.17.0 <0.21.0" optimus_icons: ^0.1.1+2 theme_tailor_annotation: "^3.0.0" @@ -23,7 +23,7 @@ dev_dependencies: flutter_test: sdk: flutter freezed: ">=1.0.0 <3.0.0" - mews_pedantic: ^0.34.0 + mews_pedantic: ^0.35.0 theme_tailor: "^3.0.0" flutter: assets: diff --git a/optimus_icons/pubspec.yaml b/optimus_icons/pubspec.yaml index 712e57e9..075d56e8 100644 --- a/optimus_icons/pubspec.yaml +++ b/optimus_icons/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mews_pedantic: ^0.34.0 + mews_pedantic: ^0.35.0 path: ^1.9.0 flutter: diff --git a/optimus_widgetbook/lib/components/list/list_tile.dart b/optimus_widgetbook/lib/components/list/list_tile.dart index 05592dd4..d1b3ca89 100644 --- a/optimus_widgetbook/lib/components/list/list_tile.dart +++ b/optimus_widgetbook/lib/components/list/list_tile.dart @@ -24,7 +24,18 @@ Widget createDefaultStyle(BuildContext context) { label: 'Font variant', initialOption: FontVariant.normal, options: FontVariant.values, - labelBuilder: (value) => value.name, + labelBuilder: enumLabelBuilder, + ); + final prefixSize = k.list( + label: 'Prefix Size', + options: OptimusPrefixSize.values, + initialOption: OptimusPrefixSize.medium, + labelBuilder: enumLabelBuilder, + ); + final prefixAlignment = k.listOrNull( + label: 'Prefix Alignment', + options: OptimusPrefixVerticalAlignment.values, + labelBuilder: enumOrNullLabelBuilder, ); return SingleChildScrollView( @@ -38,10 +49,12 @@ Widget createDefaultStyle(BuildContext context) { : null, info: info.isNotEmpty ? Text(info) : null, fontVariant: fontVariant, - prefix: prefix != null ? Icon(prefix.data) : null, - suffix: suffix != null ? Icon(suffix.data) : null, - infoWidget: infoWidget != null ? Icon(infoWidget.data) : null, + prefix: iconOrNull(prefix), + suffix: iconOrNull(suffix), + infoWidget: iconOrNull(infoWidget), onTap: ignore, + prefixSize: prefixSize, + prefixVerticalAlignment: prefixAlignment, ), ) .toList(), diff --git a/optimus_widgetbook/lib/components/media/avatar.dart b/optimus_widgetbook/lib/components/media/avatar.dart index ddf90057..6ff3b4a3 100644 --- a/optimus_widgetbook/lib/components/media/avatar.dart +++ b/optimus_widgetbook/lib/components/media/avatar.dart @@ -1,4 +1,4 @@ -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:optimus/optimus.dart'; import 'package:optimus_widgetbook/utils.dart'; import 'package:widgetbook/widgetbook.dart'; @@ -17,8 +17,26 @@ Widget createDefaultStyle(BuildContext context) { final isErrorLoading = k.boolean(label: 'Error loading', initialValue: false); final title = k.string(label: 'Title', initialValue: 'User'); final useBadge = k.boolean(label: 'Use badge', initialValue: false); + final alignment = k.list( + label: 'Alignment', + initialOption: AlignmentDirectional.center, + options: [ + AlignmentDirectional.center, + AlignmentDirectional.bottomCenter, + AlignmentDirectional.bottomEnd, + AlignmentDirectional.bottomStart, + AlignmentDirectional.centerEnd, + AlignmentDirectional.centerStart, + AlignmentDirectional.topCenter, + AlignmentDirectional.topEnd, + AlignmentDirectional.topStart, + ], + ); - return Center( + return Container( + width: context.tokens.sizing800, + height: context.tokens.sizing800, + color: Colors.blueGrey, child: OptimusAvatar( title: title, imageUrl: useImage @@ -29,6 +47,7 @@ Widget createDefaultStyle(BuildContext context) { isIndicatorVisible: hasIndicator, size: size, badgeUrl: useBadge ? _badgeUrl : null, + alignment: alignment, ), ); } diff --git a/optimus_widgetbook/lib/components/tab/tabs.dart b/optimus_widgetbook/lib/components/tab/tabs.dart index 52723bb6..9d3fb020 100644 --- a/optimus_widgetbook/lib/components/tab/tabs.dart +++ b/optimus_widgetbook/lib/components/tab/tabs.dart @@ -13,11 +13,13 @@ Widget createDefaultStyle(BuildContext context) { final knobs = context.knobs; final icon = knobs.optimusIconOrNullKnob(label: 'Icon'); final badge = knobs.string(label: 'Badge'); + final isScrollable = knobs.boolean(label: 'Scrollable', initialValue: false); return Container( color: OptimusTheme.of(context).colors.success500t16, constraints: const BoxConstraints(maxWidth: _tabBarWidth, maxHeight: 200), child: OptimusTabBar( + isScrollable: isScrollable, tabs: _items .map( (i) => OptimusTab( diff --git a/optimus_widgetbook/lib/utils.dart b/optimus_widgetbook/lib/utils.dart index bb0f0f49..4f4dd43c 100644 --- a/optimus_widgetbook/lib/utils.dart +++ b/optimus_widgetbook/lib/utils.dart @@ -1,3 +1,4 @@ +import 'package:dfunc/dfunc.dart'; import 'package:flutter/widgets.dart'; import 'package:optimus/optimus.dart'; import 'package:widgetbook/widgetbook.dart'; @@ -13,17 +14,18 @@ final List alignments = [ Alignment.bottomRight, ]; -const longText = ''' -Nascetur nec convallis tempor sagittis ligula. Mauris aenean curae vestibulum -aenean fames posuere consequat turpis. Cursus lectus rutrum dolor condimentum -rhoncus tincidunt rutrum. Hac amet class vivamus rhoncus condimentum; penatibus -risus magnis. Penatibus nulla venenatis nulla praesent mauris. Morbi feugiat -rhoncus ridiculus varius faucibus commodo tincidunt ipsum molestie. Volutpat -semper aptent viverra facilisi nam nibh suscipit purus himenaeos. Himenaeos -quisque ultrices condimentum mauris a diam.'''; +const longText = + 'Nascetur nec convallis tempor sagittis ligula. Mauris aenean curae vestibulum aenean fames posuere consequat turpis. Cursus lectus rutrumdolor condimentum rhoncus tincidunt rutrum. Hac amet class vivamus rhoncus condimentum; penatibus risus magnis. Penatibus nulla venenatis nulla praesent mauris. Morbi feugiat rhoncus ridiculus varius faucibus commodo tincidunt ipsum molestie. Volutpat semper aptent viverra facilisi nam nibh suscipit purus himenaeos. Himenaeos quisque ultrices condimentum mauris a diam.'; final stubDate = DateTime(2012, 4, 3); +String enumOrNullLabelBuilder(T? value) => value?.name ?? ''; + +String enumLabelBuilder(T value) => value.name; + +Icon? iconOrNull(IconDetails? details) => + details?.let((details) => Icon(details.data)); + extension KnobsBuilderExt on KnobsBuilder { OptimusWidgetSize get widgetSizeKnob => list( label: 'Size', diff --git a/optimus_widgetbook/pubspec.yaml b/optimus_widgetbook/pubspec.yaml index 443727c2..9e4db9d1 100644 --- a/optimus_widgetbook/pubspec.yaml +++ b/optimus_widgetbook/pubspec.yaml @@ -19,7 +19,7 @@ dev_dependencies: build_runner: ^2.4.12 flutter_test: sdk: flutter - mews_pedantic: ^0.34.0 + mews_pedantic: ^0.35.0 widgetbook_generator: ^3.9.0 flutter: uses-material-design: true diff --git a/optimus_widgetbook/web/index.html b/optimus_widgetbook/web/index.html index b692ae8f..a8e32646 100644 --- a/optimus_widgetbook/web/index.html +++ b/optimus_widgetbook/web/index.html @@ -15,10 +15,10 @@ the `--base-href` argument provided to `flutter build`. --> - + - + diff --git a/pubspec.lock b/pubspec.lock index 4c81fec3..30218132 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,34 +13,34 @@ packages: dependency: transitive description: name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.6.0" async: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" charcode: dependency: transitive description: name: charcode - sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 + sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" cli_launcher: dependency: transitive description: @@ -53,18 +53,18 @@ packages: dependency: transitive description: name: cli_util - sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.4.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" conventional_commit: dependency: transitive description: @@ -93,66 +93,66 @@ packages: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" http: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.2" http_parser: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" io: dependency: transitive description: name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" json_annotation: dependency: transitive description: name: json_annotation - sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.8.1" + version: "4.9.0" matcher: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.17" melos: dependency: "direct dev" description: name: melos - sha256: "3f22f6cc629d72acf3acc8a7f8563384550290fa30790efa328c9cf606aa17d7" + sha256: "96e64bbade5712c3f010137e195bca9f1b351fac34ab1f322af492ae34032067" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.4.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.16.0" mustache_template: dependency: transitive description: @@ -165,18 +165,18 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.1" platform: dependency: transitive description: name: platform - sha256: "57c07bf82207aee366dfaa3867b3164e4f03a238a461a11b0e8a3a510d51203d" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.6" pool: dependency: transitive description: @@ -205,10 +205,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" pub_updater: dependency: transitive description: @@ -229,66 +229,66 @@ packages: dependency: transitive description: name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" source_span: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.4" typed_data: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" uri: dependency: transitive description: @@ -297,21 +297,29 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" yaml: dependency: transitive description: name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.3" yaml_edit: dependency: transitive description: name: yaml_edit - sha256: "1579d4a0340a83cf9e4d580ea51a16329c916973bffd5bd4b45e911b25d46bfd" + sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.2" sdks: - dart: ">=3.0.0 <4.0.0" + dart: ">=3.5.0 <4.0.0" diff --git a/remote_logger/pubspec.yaml b/remote_logger/pubspec.yaml index f2126c50..6e846aca 100644 --- a/remote_logger/pubspec.yaml +++ b/remote_logger/pubspec.yaml @@ -14,6 +14,6 @@ dependencies: dev_dependencies: build_runner: ^2.4.8 - mews_pedantic: ^0.34.0 + mews_pedantic: ^0.35.0 mockito: ^5.4.4 test: ^1.25.2