WIP: feat(ui): Migrate to new UI implementation

This commit is contained in:
2026-06-22 06:47:16 +04:00
parent 873aa8d7b5
commit bb4334f68d
109 changed files with 13499 additions and 1257 deletions
@@ -0,0 +1,258 @@
import 'package:flutter/material.dart';
import 'package:moonwell_launcher/app/design_system/mw_primitives.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;
@widgetbook.UseCase(name: 'interactive', type: MwButton, path: '[Primitives]')
Widget buildMwButtonInteractiveUseCase(BuildContext context) {
final variant = context.knobs.object.dropdown<MwButtonVariant>(
label: 'variant',
initialOption: MwButtonVariant.primary,
options: MwButtonVariant.values,
labelBuilder: (value) => value.name,
);
return MwButton(
label: context.knobs.string(label: 'label', initialValue: 'Играть'),
icon: context.knobs.boolean(label: 'showIcon', initialValue: true)
? Icons.play_arrow
: null,
variant: variant,
loading: context.knobs.boolean(label: 'loading', initialValue: false),
expand: context.knobs.boolean(label: 'expand', initialValue: false),
onPressed: context.knobs.boolean(label: 'enabled', initialValue: true)
? () => debugPrint('MwButton pressed')
: null,
);
}
@widgetbook.UseCase(name: 'loading', type: MwButton, path: '[Primitives]')
Widget buildMwButtonLoadingUseCase(BuildContext context) {
return MwButton(
label: context.knobs.string(label: 'label', initialValue: 'Загрузка'),
loading: true,
onPressed: () => debugPrint('Loading MwButton pressed'),
);
}
@widgetbook.UseCase(name: 'disabled', type: MwButton, path: '[Primitives]')
Widget buildMwButtonDisabledUseCase(BuildContext context) {
return MwButton(
label: context.knobs.string(label: 'label', initialValue: 'Недоступно'),
onPressed: null,
);
}
@widgetbook.UseCase(
name: 'interactive',
type: MwIconButton,
path: '[Primitives]',
)
Widget buildMwIconButtonInteractiveUseCase(BuildContext context) {
return MwIconButton(
icon: Icons.settings,
tooltip: context.knobs.string(label: 'tooltip', initialValue: 'Настройки'),
selected: context.knobs.boolean(label: 'selected', initialValue: false),
destructive: context.knobs.boolean(
label: 'destructive',
initialValue: false,
),
onPressed: context.knobs.boolean(label: 'enabled', initialValue: true)
? () => debugPrint('MwIconButton pressed')
: null,
);
}
@widgetbook.UseCase(
name: 'interactive',
type: MwTextField,
path: '[Primitives]',
)
Widget buildMwTextFieldInteractiveUseCase(BuildContext context) {
return SizedBox(
width: 380,
child: MwTextField(
label: context.knobs.string(label: 'label', initialValue: 'Логин'),
hint: context.knobs.stringOrNull(
label: 'hint',
initialValue: 'Введите логин',
),
errorText: context.knobs.stringOrNull(
label: 'errorText',
initialValue: null,
),
enabled: context.knobs.boolean(label: 'enabled', initialValue: true),
obscureText: context.knobs.boolean(
label: 'obscureText',
initialValue: false,
),
prefixIcon: context.knobs.boolean(label: 'showIcon', initialValue: true)
? Icons.person_outline
: null,
onSubmitted: (value) => debugPrint('MwTextField submitted: $value'),
),
);
}
@widgetbook.UseCase(name: 'interactive', type: MwCheckbox, path: '[Primitives]')
Widget buildMwCheckboxInteractiveUseCase(BuildContext context) {
return MwCheckbox(
label: context.knobs.string(label: 'label', initialValue: 'Запомнить меня'),
value: context.knobs.boolean(label: 'value', initialValue: false),
onChanged: context.knobs.boolean(label: 'enabled', initialValue: true)
? (value) => debugPrint('MwCheckbox changed: $value')
: null,
);
}
@widgetbook.UseCase(name: 'interactive', type: MwTabs, path: '[Primitives]')
Widget buildMwTabsInteractiveUseCase(BuildContext context) {
return MwTabs(
labels: const ['Новости', 'Обновления', 'Очень длинный раздел'],
selectedIndex: context.knobs.int.slider(
label: 'selectedIndex',
initialValue: 0,
min: 0,
max: 2,
divisions: 2,
),
disabledIndices:
context.knobs.boolean(label: 'disableFutureTabs', initialValue: true)
? const {1, 2}
: const {},
onSelected: (index) => debugPrint('MwTabs selected: $index'),
);
}
@widgetbook.UseCase(name: 'interactive', type: MwBadge, path: '[Primitives]')
Widget buildMwBadgeInteractiveUseCase(BuildContext context) {
return MwBadge(
label: context.knobs.string(label: 'label', initialValue: 'Готово'),
tone: context.knobs.object.dropdown<MwBadgeTone>(
label: 'tone',
initialOption: MwBadgeTone.success,
options: MwBadgeTone.values,
labelBuilder: (value) => value.name,
),
);
}
@widgetbook.UseCase(name: 'interactive', type: MwPanel, path: '[Primitives]')
Widget buildMwPanelInteractiveUseCase(BuildContext context) {
return SizedBox(
width: 420,
child: MwPanel(
level: context.knobs.object.dropdown<MwPanelLevel>(
label: 'level',
initialOption: MwPanelLevel.regular,
options: MwPanelLevel.values,
labelBuilder: (value) => value.name,
),
child: Text(
context.knobs.string(
label: 'content',
initialValue: 'Содержимое панели MoonWell',
),
),
),
);
}
@widgetbook.UseCase(
name: 'interactive',
type: MwProgressBar,
path: '[Primitives]',
)
Widget buildMwProgressBarInteractiveUseCase(BuildContext context) {
return SizedBox(
width: 440,
child: MwProgressBar(
value: context.knobs.boolean(label: 'indeterminate', initialValue: false)
? null
: context.knobs.double.slider(
label: 'value',
initialValue: .46,
min: 0,
max: 1,
divisions: 100,
),
label: context.knobs.stringOrNull(
label: 'label',
initialValue: 'Загрузка файлов',
),
state: context.knobs.object.dropdown<MwProgressState>(
label: 'state',
initialOption: MwProgressState.active,
options: MwProgressState.values,
labelBuilder: (value) => value.name,
),
),
);
}
@widgetbook.UseCase(
name: 'interactive',
type: MwStatusText,
path: '[Primitives]',
)
Widget buildMwStatusTextInteractiveUseCase(BuildContext context) {
return MwStatusText(
text: context.knobs.string(
label: 'text',
initialValue: 'Проверяем локальные файлы…',
),
tone: context.knobs.object.dropdown<MwStatusTone>(
label: 'tone',
initialOption: MwStatusTone.operational,
options: MwStatusTone.values,
labelBuilder: (value) => value.name,
),
monospace: context.knobs.boolean(label: 'monospace', initialValue: false),
);
}
@widgetbook.UseCase(
name: 'interactive',
type: MwStateView,
path: '[Primitives]',
)
Widget buildMwStateViewInteractiveUseCase(BuildContext context) {
final kind = context.knobs.object.dropdown<MwStateKind>(
label: 'kind',
initialOption: MwStateKind.empty,
options: MwStateKind.values,
labelBuilder: (value) => value.name,
);
return MwStateView(
kind: kind,
title: context.knobs.string(
label: 'title',
initialValue: 'Новостей пока нет',
),
description: context.knobs.stringOrNull(
label: 'description',
initialValue: 'Новые публикации появятся здесь.',
),
onRetry: kind == MwStateKind.error
? () => debugPrint('MwStateView retry pressed')
: null,
);
}
@widgetbook.UseCase(
name: 'default',
type: MwDisabledFeature,
path: '[Primitives]',
)
Widget buildMwDisabledFeatureUseCase(BuildContext context) {
return MwDisabledFeature(
message: context.knobs.string(
label: 'message',
initialValue: 'Регистрация появится позже',
),
child: const MwButton(
label: 'Регистрация · скоро',
onPressed: null,
variant: MwButtonVariant.secondary,
),
);
}