Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding possibility to pin information on preview area #83

Merged
merged 2 commits into from
May 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,54 @@ dashbook
);
});

return Text('Use actions to show the Dialog');
return SizedBox();
});
```

## Example information

More than often, an example may not be intuitive enough and the user may be lost without some instruction on how to interact with it. To mitigate that, text information can be linked to an example to serve as a guide, or really to show any relevant information.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too long line

erickzanardo marked this conversation as resolved.
Show resolved Hide resolved

To do so, simple use the `info` parameter on the `add` method of a story:
erickzanardo marked this conversation as resolved.
Show resolved Hide resolved

```dart
final dashbook = Dashbook();

dashbook
.storiesOf('CustomDialog')
.add('default',
(ctx) {
ctx.action('Open dialog', (context) {
showDialog(
context: context,
builder: (_) => CustomDialog(),
);
});

return SizedBox();
},
info: 'Use the actions button on the side to show the dialog.',
);
```

This will present a small `i` icon on the side toolbar that once clicked will present the information to the user.

Dashbook also offers the possibility to directly show the information on the preview area, removing the necessity for the user to click on the icon. To do so, simple pass `true` to the `pinInfo` parameter.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too long line

erickzanardo marked this conversation as resolved.
Show resolved Hide resolved

```dart
final dashbook = Dashbook();

dashbook
.storiesOf('CustomDialog')
.add('default',
(ctx) {
// omitted ...
},
info: 'Use the actions button on the side to show the dialog.',
pinInfo: true,
);
```

## Preview area

By default Dashbook will provide the whole screen area for the preview, which means that its controll icons will appear floating above the example.
Expand Down
4 changes: 3 additions & 1 deletion example/lib/stories.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ void addStories(Dashbook dashbook) {
);
});

return const Center(child: Text('Use the actions menu to show a Toast'));
return const SizedBox();
},
info: 'Use the actions menu to show a Toast',
pinInfo: true,
);
}
12 changes: 11 additions & 1 deletion lib/src/story.dart
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,15 @@ class Story {
ChapterBuildFunction buildFn, {
String? codeLink,
String? info,
bool pinInfo = false,
}) {
final _chapter = Chapter(
name,
buildFn,
this,
codeLink: codeLink,
info: info,
pinInfo: pinInfo,
);
chapters.add(_chapter);

Expand All @@ -300,10 +302,18 @@ class Chapter {
DashbookContext ctx = DashbookContext();
final String? codeLink;
final String? info;
final bool pinInfo;

final Story story;

Chapter(this.name, this._buildFn, this.story, {this.codeLink, this.info});
Chapter(
this.name,
this._buildFn,
this.story, {
this.codeLink,
this.info,
this.pinInfo = false,
});

Widget widget() {
final w = _buildFn(ctx);
Expand Down
69 changes: 46 additions & 23 deletions lib/src/widgets/preview_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class PreviewContainer extends StatelessWidget {
final DeviceInfo? deviceInfo;
final Orientation? deviceOrientation;
final bool showDeviceFrame;
final String? info;

const PreviewContainer({
required Key key,
Expand All @@ -20,39 +21,61 @@ class PreviewContainer extends StatelessWidget {
required this.showDeviceFrame,
this.deviceInfo,
this.deviceOrientation,
this.info,
}) : super(key: key);

@override
Widget build(BuildContext context) {
final preview = deviceInfo != null
? DevicePreview(
showDeviceFrame: showDeviceFrame,
deviceInfo: deviceInfo!,
deviceOrientation: deviceOrientation!,
child: Container(
decoration: BoxDecoration(
border: usePreviewSafeArea
? Border(
left: BorderSide(
color: Theme.of(context).cardColor,
width: iconSize(context) * 2,
),
right: BorderSide(
color: Theme.of(context).cardColor,
width: iconSize(context) * 2,
),
)
: null,
),
child: child,
),
)
: child;

return Positioned(
top: 0,
bottom: 0,
left: 0,
right: (kIsWeb && isPropertiesOpen) ? sideBarSizeProperties(context) : 0,
child: deviceInfo != null
? DevicePreview(
showDeviceFrame: showDeviceFrame,
deviceInfo: deviceInfo!,
deviceOrientation: deviceOrientation!,
child: Container(
decoration: BoxDecoration(
border: usePreviewSafeArea
? Border(
left: BorderSide(
color: Theme.of(context).cardColor,
width: iconSize(context) * 2,
),
right: BorderSide(
color: Theme.of(context).cardColor,
width: iconSize(context) * 2,
),
)
: null,
child: info == null
? preview
: Stack(
children: [
Positioned.fill(child: preview),
Positioned(
bottom: 6,
left: 6,
right: 6,
child: Center(
child: Card(
child: Padding(
padding: const EdgeInsets.all(8),
child: Text(info!),
),
),
),
),
child: child,
),
)
: child,
],
),
);
}
}
6 changes: 5 additions & 1 deletion lib/src/widgets/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ class _DashbookState extends State<Dashbook> {
deviceInfo: deviceInfo,
deviceOrientation: deviceOrientation,
showDeviceFrame: showDeviceFrame,
info: _currentChapter?.pinInfo == true
? _currentChapter?.info
: null,
child: chapterWidget!,
),
Positioned(
Expand Down Expand Up @@ -293,7 +296,8 @@ class _DashbookState extends State<Dashbook> {
},
),
),
if (_currentChapter?.info != null)
if (_currentChapter?.info != null &&
_currentChapter?.pinInfo == false)
DashbookIcon(
tooltip: 'Instructions',
icon: Icons.info,
Expand Down
9 changes: 9 additions & 0 deletions test/helpers.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:dashbook/dashbook.dart';
import 'package:dashbook/src/widgets/icon.dart';
import 'package:dashbook/src/widgets/keys.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
Expand All @@ -18,3 +19,11 @@ extension WidgetTesterExtension on WidgetTester {
await pumpAndSettle();
}
}

extension CommonFindersX on CommonFinders {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah never seen X been used as a short form of Extension before, is this common? I think I'd prefer the word written out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I didn't know either, but seems to be quite common.

Finder dashbookIconByTooltip(String tooltip) {
return byWidgetPredicate(
(widget) => widget is DashbookIcon && widget.tooltip == tooltip,
);
}
}
69 changes: 69 additions & 0 deletions test/widget/chapter_info_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import 'package:dashbook/dashbook.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import '../helpers.dart';

Dashbook _getDashbookWithIconInfo() {
final dashbook = Dashbook();

dashbook.storiesOf('Text').add(
'default',
(context) => const SizedBox(),
info: 'This is some info',
);

return dashbook;
}

Dashbook _getDashbookWithPinnedInfo() {
final dashbook = Dashbook();

dashbook.storiesOf('Text').add(
'default',
(context) => const SizedBox(),
info: 'Behold! The info is already upon you!',
pinInfo: true,
);

return dashbook;
}

void main() {
group('Chapter Info', () {
testWidgets('shows the info icon', (tester) async {
await tester.pumpDashbook(_getDashbookWithIconInfo());
expect(
find.dashbookIconByTooltip('Instructions'),
findsOneWidget,
);
});

testWidgets(
'show the info dialog when the icon is clicked',
(tester) async {
await tester.pumpDashbook(_getDashbookWithIconInfo());

await tester.tap(
find.dashbookIconByTooltip('Instructions'),
);

await tester.pumpAndSettle();
expect(find.text('This is some info'), findsOneWidget);
},
);

testWidgets(
'show the info dialog when the icon is clicked',
(tester) async {
await tester.pumpDashbook(_getDashbookWithPinnedInfo());

await tester.pumpAndSettle();
expect(
find.text('Behold! The info is already upon you!'),
findsOneWidget,
);
},
);
});
}