Skip to content

Commit

Permalink
feat: ✨ addon routing
Browse files Browse the repository at this point in the history
  • Loading branch information
jenshor committed Aug 24, 2022
1 parent f2e0196 commit 8cfd368
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 164 deletions.
8 changes: 4 additions & 4 deletions examples/widgetbook_example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ packages:
name: go_router
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.6"
version: "4.2.8"
intl:
dependency: "direct main"
description:
Expand Down Expand Up @@ -256,7 +256,7 @@ packages:
path: "../../packages/widgetbook"
relative: true
source: path
version: "2.3.0"
version: "2.4.1"
widgetbook_models:
dependency: "direct overridden"
description:
Expand All @@ -265,5 +265,5 @@ packages:
source: path
version: "0.0.7"
sdks:
dart: ">=2.17.0-0 <3.0.0"
flutter: ">=2.0.0"
dart: ">=2.17.0 <3.0.0"
flutter: ">=3.0.0"
8 changes: 8 additions & 0 deletions packages/widgetbook/lib/src/addons/addon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@ class WidgetbookAddOn {
required this.builder,
required this.providerBuilder,
required this.selectionCount,
required this.getQueryParameter,
});

// TODO if we make this a builder, we can access buildcontext
final Widget icon;

final String name;

final Widget Function(
BuildContext context,
Map<String, dynamic> routerData,
Widget child,
) wrapperBuilder;

final Widget Function(
BuildContext context,
) builder;
Expand All @@ -27,5 +32,8 @@ class WidgetbookAddOn {
BuildContext context,
int index,
) providerBuilder;

final int Function(BuildContext context) selectionCount;

final String Function(BuildContext context) getQueryParameter;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:widgetbook/src/addons/localization_addon/localization_data.dart'
import 'package:widgetbook/src/addons/localization_addon/localization_provider.dart';
import 'package:widgetbook/src/addons/localization_addon/localization_selection.dart';
import 'package:widgetbook/src/addons/localization_addon/localization_selection_provider.dart';
import 'package:widgetbook/src/navigation/router.dart';

export './localization_data.dart';
export './localization_selection.dart';
Expand All @@ -16,15 +17,23 @@ class LocalizationAddon extends WidgetbookAddOn {
required LocalizationSelection data,
}) : super(
icon: const Icon(Icons.translate),
name: 'Localization',
wrapperBuilder: (context, child) =>
_wrapperBuilder(context, child, data),
name: 'localization',
wrapperBuilder: (context, routerData, child) =>
_wrapperBuilder(context, child, routerData, data),
builder: _builder,
providerBuilder: _providerBuilder,
selectionCount: _selectionCount,
getQueryParameter: _getQueryParameter,
);
}

String _getQueryParameter(BuildContext context) {
final selectedItems =
context.read<LocalizationSelectionProvider>().value.activeLocales;

return selectedItems.map((e) => e.languageCode).join(',');
}

int _selectionCount(BuildContext context) {
return context
.read<LocalizationSelectionProvider>()
Expand All @@ -45,6 +54,7 @@ Widget _builder(BuildContext context) {
onTap: () {
context.read<LocalizationSelectionProvider>().tapped(item);
context.read<AddOnProvider>().update();
navigate(context);
},
);
},
Expand All @@ -61,10 +71,28 @@ Widget _builder(BuildContext context) {
Widget _wrapperBuilder(
BuildContext context,
Widget child,
Map<String, dynamic> routerData,
LocalizationSelection data,
) {
final activeLocalesString = routerData['locales'] as String?;
final selectedLocales = <Locale>[];
if (activeLocalesString != null) {
final activeLocales = activeLocalesString.split(',');
final mapLocales = {for (var e in data.locales) e.languageCode: e};

for (final activeLocale in activeLocales) {
if (mapLocales.containsKey(activeLocale)) {
selectedLocales.add(mapLocales[activeLocale]!);
}
}
}

final initialData = selectedLocales.isNotEmpty
? data.copyWith(activeLocales: selectedLocales.toSet())
: data;

return ChangeNotifierProvider(
create: (_) => LocalizationSelectionProvider(data),
create: (_) => LocalizationSelectionProvider(initialData),
child: child,
);
}
Expand Down
12 changes: 11 additions & 1 deletion packages/widgetbook/lib/src/addons/theme_addon/theme_addon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,30 @@ import 'package:widgetbook/src/addons/addon_provider.dart';
import 'package:widgetbook/src/addons/theme_addon/theme_provider.dart';
import 'package:widgetbook/src/addons/theme_addon/theme_selection.dart';
import 'package:widgetbook/src/addons/theme_addon/theme_selection_provider.dart';
import 'package:widgetbook/src/navigation/router.dart';

class ThemeAddon extends WidgetbookAddOn {
ThemeAddon({
required List<ThemeData> themes,
}) : super(
icon: const Icon(Icons.theater_comedy),
name: 'themes',
wrapperBuilder: (context, child) =>
wrapperBuilder: (context, routerData, child) =>
_wrapperBuilder(context, child, themes),
builder: _builder,
providerBuilder: _providerBuilder,
selectionCount: _selectionCount,
getQueryParameter: _getQueryParameter,
);
}

String _getQueryParameter(BuildContext context) {
final selectedItems =
context.read<ThemeSelectionProvider>().value.activeThemes;

return selectedItems.map((e) => e).join(',');
}

int _selectionCount(BuildContext context) {
return context.read<ThemeSelectionProvider>().value.activeThemes.length;
}
Expand All @@ -37,6 +46,7 @@ Widget _builder(BuildContext context) {
onTap: () {
context.read<ThemeSelectionProvider>().tapped(item);
context.read<AddOnProvider>().update();
navigate(context);
},
);
},
Expand Down
90 changes: 16 additions & 74 deletions packages/widgetbook/lib/src/navigation/router.dart
Original file line number Diff line number Diff line change
@@ -1,58 +1,26 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:widgetbook/src/extensions/enum_extension.dart';
import 'package:provider/provider.dart';
import 'package:widgetbook/src/addons/addon_provider.dart';
import 'package:widgetbook/src/navigation/preview_provider.dart';
import 'package:widgetbook/src/widgetbook_page.dart';
import 'package:widgetbook/src/workbench/workbench_provider.dart';

void refreshRoute<CustomTheme>(
GoRouter router, {
required WorkbenchProvider<CustomTheme> workbenchProvider,
required PreviewProvider previewProvider,
}) {
final previewState = previewProvider.state;
final workbenchState = workbenchProvider.state;

final queryParameters = <String, String>{};

if (workbenchState.hasSelectedTheme) {
queryParameters.putIfAbsent(
'theme',
() => workbenchState.theme!.name,
);
}

if (workbenchState.hasSelectedDevice) {
queryParameters.putIfAbsent(
'device',
() => workbenchState.device!.name,
);
}

if (workbenchState.hasSelectedTextScaleFactor) {
queryParameters.putIfAbsent(
'text-scale-factor',
() => workbenchState.textScaleFactor!.toStringAsFixed(1),
);
}

queryParameters
..putIfAbsent(
'orientation',
() => workbenchState.orientation.toShortString(),
)
..putIfAbsent(
'frame',
() => workbenchState.frame.name,
);
void navigate(BuildContext context) {
final addons = context.read<AddOnProvider>().value;
final queryParameters = {
for (final addon in addons) addon.name: addon.getQueryParameter(context)
};

if (previewState.isUseCaseSelected) {
queryParameters.putIfAbsent(
'path',
() => previewState.selectedUseCase!.path,
);
final usecase = context.read<PreviewProvider>().state.selectedUseCase;
if (usecase != null) {
queryParameters.putIfAbsent('path', () => usecase.path);
}

router.goNamed('/', queryParams: queryParameters);
context.goNamed(
'/',
queryParams: queryParameters,
);
}

bool _parseBoolQueryParameter({
Expand All @@ -72,19 +40,8 @@ GoRouter createRouter<CustomTheme>({
}) {
final router = GoRouter(
redirect: (routerState) {
final theme = routerState.queryParams['theme'];
final device = routerState.queryParams['device'];
final textScaleFactor = routerState.queryParams['text-scale-factor'];
final orientation = routerState.queryParams['orientation'];
final frame = routerState.queryParams['frame'];
final path = routerState.queryParams['path'];

workbenchProvider
..setThemeByName(theme)
..setDeviceByName(device)
..setTextScaleFactorByName(textScaleFactor)
..setOrientationByName(orientation)
..setFrameByName(frame);
previewProvider.selectUseCaseByPath(path);
return null;
},
Expand All @@ -104,28 +61,13 @@ GoRouter createRouter<CustomTheme>({
child: WidgetbookPage<CustomTheme>(
disableNavigation: disableNavigation,
disableProperties: disableProperties,
routerData: state.queryParams,
),
);
},
),
],
);

previewProvider.addListener(() {
refreshRoute(
router,
workbenchProvider: workbenchProvider,
previewProvider: previewProvider,
);
});

workbenchProvider.addListener(() {
refreshRoute(
router,
workbenchProvider: workbenchProvider,
previewProvider: previewProvider,
);
});

return router;
}
14 changes: 0 additions & 14 deletions packages/widgetbook/lib/src/navigation/routes.dart

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ Widget _defaultAppBuilderMethod(BuildContext context, Widget child) {
AppBuilderFunction get materialAppBuilder =>
(BuildContext context, Widget child) {
final _router = getRouter(child);
return MaterialApp.router(
return MaterialApp(
theme: context.theme,
locale: context.localization.activeLocale,
supportedLocales: context.localization.supportedLocales,
localizationsDelegates: context.localization.localizationsDelegates,
debugShowCheckedModeBanner: false,
routerDelegate: _router.routerDelegate,
routeInformationParser: _router.routeInformationParser,
home: child,
);
};

Expand Down
15 changes: 1 addition & 14 deletions packages/widgetbook/lib/src/widgetbook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ class _WidgetbookState<CustomTheme> extends State<Widgetbook<CustomTheme>> {
),
],
child: MaterialApp.router(
routeInformationProvider: goRouter.routeInformationProvider,
routeInformationParser: goRouter.routeInformationParser,
routerDelegate: goRouter.routerDelegate,
title: widget.appInfo.name,
Expand All @@ -340,18 +341,4 @@ class _WidgetbookState<CustomTheme> extends State<Widgetbook<CustomTheme>> {
),
);
}

WidgetbookUseCase? selectStoryFromPath(
String? path,
List<WidgetbookUseCase> stories,
) {
final storyPath = path?.replaceFirst('/stories/', '') ?? '';
WidgetbookUseCase? story;
for (final element in stories) {
if (element.path == storyPath) {
story = element;
}
}
return story;
}
}
Loading

0 comments on commit 8cfd368

Please sign in to comment.