Skip to content

Commit

Permalink
Create alert component
Browse files Browse the repository at this point in the history
  • Loading branch information
tilucasoli committed Feb 7, 2024
1 parent b52a5b0 commit 7ebf90b
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 14 deletions.
37 changes: 37 additions & 0 deletions demo/lib/components/alert.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:mix/mix.dart';
import 'package:remix_ui/remix_ui.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;

@widgetbook.UseCase(
name: 'interactive playground',
type: RemixAlert,
)
Widget buildCheckboxUseCase(BuildContext context) {
return Center(
child: SizedBox(
width: 300,
child: RemixAlert(
title: StyledText(
context.knobs.string(
label: 'Title',
initialValue: 'Error',
),
),
subtitle: StyledText(
context.knobs.string(
label: 'Subtitle',
initialValue: 'Your session has expired. Please log in again.',
),
),
leading: context.knobs.boolean(
label: 'Leading',
initialValue: false,
)
? const StyledIcon(Icons.warning_amber_rounded)
: null,
),
),
);
}
41 changes: 27 additions & 14 deletions demo/lib/main.directories.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,40 @@
// **************************************************************************

// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:demo/components/avatar.dart' as _i2;
import 'package:demo/components/badge.dart' as _i3;
import 'package:demo/components/button.dart' as _i4;
import 'package:demo/components/checkbox.dart' as _i5;
import 'package:demo/components/list_tile.dart' as _i6;
import 'package:demo/components/radio.dart' as _i7;
import 'package:demo/components/switch.dart' as _i8;
import 'package:demo/components/alert.dart' as _i2;
import 'package:demo/components/avatar.dart' as _i3;
import 'package:demo/components/badge.dart' as _i4;
import 'package:demo/components/button.dart' as _i5;
import 'package:demo/components/checkbox.dart' as _i6;
import 'package:demo/components/list_tile.dart' as _i7;
import 'package:demo/components/radio.dart' as _i8;
import 'package:demo/components/switch.dart' as _i9;
import 'package:widgetbook/widgetbook.dart' as _i1;

final directories = <_i1.WidgetbookNode>[
_i1.WidgetbookFolder(
name: 'components',
children: [
_i1.WidgetbookFolder(
name: 'alert',
children: [
_i1.WidgetbookLeafComponent(
name: 'RemixAlert',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i2.buildCheckboxUseCase,
),
)
],
),
_i1.WidgetbookFolder(
name: 'avatar',
children: [
_i1.WidgetbookLeafComponent(
name: 'RemixAvatar',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i2.buildCheckboxUseCase,
builder: _i3.buildCheckboxUseCase,
),
)
],
Expand All @@ -41,7 +54,7 @@ final directories = <_i1.WidgetbookNode>[
name: 'RemixBadge',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i3.buildCheckboxUseCase,
builder: _i4.buildCheckboxUseCase,
),
)
],
Expand All @@ -53,7 +66,7 @@ final directories = <_i1.WidgetbookNode>[
name: 'RemixButton',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i4.buildButtonUseCase,
builder: _i5.buildButtonUseCase,
),
)
],
Expand All @@ -65,7 +78,7 @@ final directories = <_i1.WidgetbookNode>[
name: 'RemixCheckbox',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i5.buildCheckboxUseCase,
builder: _i6.buildCheckboxUseCase,
),
)
],
Expand All @@ -77,7 +90,7 @@ final directories = <_i1.WidgetbookNode>[
name: 'RemixListTile',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i6.buildCheckboxUseCase,
builder: _i7.buildCheckboxUseCase,
),
)
],
Expand All @@ -89,7 +102,7 @@ final directories = <_i1.WidgetbookNode>[
name: 'RemixRadio',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i7.buildRadioUseCase,
builder: _i8.buildRadioUseCase,
),
)
],
Expand All @@ -101,7 +114,7 @@ final directories = <_i1.WidgetbookNode>[
name: 'RemixSwitch',
useCase: _i1.WidgetbookUseCase(
name: 'interactive playground',
builder: _i8.buildRadioUseCase,
builder: _i9.buildRadioUseCase,
),
)
],
Expand Down
67 changes: 67 additions & 0 deletions lib/components/alert/alert.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:mix/mix.dart';
import 'package:remix_ui/components/alert/alert.style.dart';
import 'package:remix_ui/components/card/card.style.dart';

import '../../utils/component_recipe.dart';

class RemixAlert extends StatelessWidget
implements RemixComponentRecipe<AlertStyles> {
const RemixAlert({
super.key,
this.leading,
this.title,
this.subtitle,
this.style,
this.variants = const [],
});

final Widget? leading;
final Widget? title;
final Widget? subtitle;

@override
final AlertStyles? style;

@override
final List<Variant> variants;

AlertStyles buildStyle(List<Variant> variants) {
final result = style == null ? AlertStyles.base() : style!;
return result.applyVariants(variants);
}

@override
Widget build(BuildContext context) {
final style = buildStyle(variants);

return HBox(
style: style.outerRowContainer,
children: [
if (leading != null)
MixProvider.build(
context,
style: style.icon,
builder: (_) => leading!,
),
VBox(
style: style.innerColumnContainer,
children: [
if (title != null)
MixProvider.build(
context,
style: style.title,
builder: (_) => title!,
),
if (subtitle != null)
MixProvider.build(
context,
style: style.subtitle,
builder: (_) => subtitle!,
),
],
),
],
);
}
}
104 changes: 104 additions & 0 deletions lib/components/alert/alert.style.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import 'package:mix/mix.dart';

class AlertStyles extends StyleRecipe<AlertStyles> {
const AlertStyles({
this.outerRowContainer = const Style.empty(),
this.innerColumnContainer = const Style.empty(),
this.title = const Style.empty(),
this.subtitle = const Style.empty(),
this.icon = const Style.empty(),
});

final Style outerRowContainer;
final Style innerColumnContainer;
final Style title;
final Style subtitle;
final Style icon;

factory AlertStyles.base() {
return AlertStyles(
outerRowContainer: _outerRowContainer(),
innerColumnContainer: _innerColumnContainer(),
title: _title(),
subtitle: _subtitle(),
icon: _icon(),
);
}

@override
AlertStyles applyVariants(List<Variant> variants) {
return AlertStyles(
outerRowContainer: outerRowContainer.applyVariants(variants),
innerColumnContainer: innerColumnContainer.applyVariants(variants),
title: title.applyVariants(variants),
subtitle: subtitle.applyVariants(variants),
icon: icon.applyVariants(variants),
);
}

@override
AlertStyles merge(AlertStyles? other) {
if (other == null) return this;
return copyWith(
outerRowContainer: outerRowContainer.merge(other.outerRowContainer),
innerColumnContainer:
innerColumnContainer.merge(other.innerColumnContainer),
title: title.merge(other.title),
subtitle: subtitle.merge(other.subtitle),
icon: icon.merge(other.icon),
);
}

@override
AlertStyles copyWith({
Style? outerRowContainer,
Style? innerColumnContainer,
Style? title,
Style? subtitle,
Style? icon,
}) {
return AlertStyles(
outerRowContainer: outerRowContainer ?? this.outerRowContainer,
innerColumnContainer: innerColumnContainer ?? this.innerColumnContainer,
title: title ?? this.title,
subtitle: subtitle ?? this.subtitle,
icon: icon ?? this.icon,
);
}
}

Style _outerRowContainer() => Style(
flex.gap(8),
box.padding(16),
box.borderRadius(8),
box.border.width(1),
box.border.color.redAccent(),
flex.mainAxisSize.min(),
flex.mainAxisAlignment.start(),
flex.crossAxisAlignment.start(),
);

Style _innerColumnContainer() => Style(
flex.gap(2),
flex.mainAxisSize.min(),
flex.mainAxisAlignment.start(),
flex.crossAxisAlignment.start(),
flexible.expanded(),
);

Style _title() => Style(
text.style.fontSize(14),
text.style.fontWeight.w600(),
text.style.color.redAccent(),
);

Style _subtitle() => Style(
text.style.fontSize(14),
text.style.fontWeight.normal(),
text.style.color.redAccent(),
);

Style _icon() => Style(
icon.size(20),
icon.color.redAccent(),
);
2 changes: 2 additions & 0 deletions lib/remix_ui.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
library remix_ui;

export 'components/alert/alert.dart';
export 'components/alert/alert.style.dart';
export 'components/button/button.dart';
export 'components/button/button.style.dart';
export 'components/button/button.variants.dart';
Expand Down

0 comments on commit 7ebf90b

Please sign in to comment.