forked from mirrors/material_3_expressive
Add Widgetbook setup with theme configuration, analysis options, and initial component use cases
This commit is contained in:
parent
d3ad4b9c9d
commit
80ca8f665a
46 changed files with 6031 additions and 2 deletions
186
widgetbook/lib/slider_m3e/slider_m3e_usecases.dart
Normal file
186
widgetbook/lib/slider_m3e/slider_m3e_usecases.dart
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:slider_m3e/slider_m3e.dart';
|
||||
import 'package:widgetbook/widgetbook.dart';
|
||||
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
|
||||
|
||||
Widget _buildSliderM3EDemo(
|
||||
BuildContext context, {
|
||||
double? forcedMin,
|
||||
double? forcedMax,
|
||||
int? forcedDivisions,
|
||||
bool disabled = false,
|
||||
bool zeroRange = false,
|
||||
}) {
|
||||
// Critical params via knobs
|
||||
final minKnob = forcedMin ??
|
||||
context.knobs.double.slider(
|
||||
label: 'min',
|
||||
initialValue: 0,
|
||||
min: -100,
|
||||
max: 100,
|
||||
divisions: 40,
|
||||
);
|
||||
final maxKnob = forcedMax ??
|
||||
context.knobs.double.slider(
|
||||
label: 'max',
|
||||
initialValue: 100,
|
||||
min: -100,
|
||||
max: 200,
|
||||
divisions: 60,
|
||||
);
|
||||
|
||||
double min = minKnob;
|
||||
double max = maxKnob;
|
||||
|
||||
// Special handling when zeroRange is requested
|
||||
if (zeroRange) {
|
||||
// Force min == max and disable interactions to avoid semantic division by zero
|
||||
final fixed = context.knobs.double.slider(
|
||||
label: 'fixed value (min==max)',
|
||||
initialValue: 50,
|
||||
min: -100,
|
||||
max: 100,
|
||||
divisions: 40,
|
||||
);
|
||||
min = fixed;
|
||||
max = fixed;
|
||||
}
|
||||
|
||||
if (min >= max) {
|
||||
// Guard against invalid ranges; ensure there is at least a small span
|
||||
max = min + 1;
|
||||
}
|
||||
|
||||
final value = context.knobs.double.slider(
|
||||
label: 'value',
|
||||
initialValue: (min + max) / 2,
|
||||
min: min,
|
||||
max: max,
|
||||
divisions: 100,
|
||||
);
|
||||
|
||||
final divisions = forcedDivisions ??
|
||||
context.knobs.intOrNull.slider(
|
||||
label: 'divisions',
|
||||
initialValue: null,
|
||||
min: 1,
|
||||
max: 20,
|
||||
divisions: 19,
|
||||
);
|
||||
|
||||
// Visual params via knobs
|
||||
final size = context.knobs.object.dropdown<SliderM3ESize>(
|
||||
label: 'size',
|
||||
initialOption: SliderM3ESize.medium,
|
||||
options: SliderM3ESize.values,
|
||||
labelBuilder: (v) => v.name,
|
||||
);
|
||||
final emphasis = context.knobs.object.dropdown<SliderM3EEmphasis>(
|
||||
label: 'emphasis',
|
||||
initialOption: SliderM3EEmphasis.primary,
|
||||
options: SliderM3EEmphasis.values,
|
||||
labelBuilder: (v) => v.name,
|
||||
);
|
||||
final shape = context.knobs.object.dropdown<SliderM3EShapeFamily>(
|
||||
label: 'shapeFamily',
|
||||
initialOption: SliderM3EShapeFamily.round,
|
||||
options: SliderM3EShapeFamily.values,
|
||||
labelBuilder: (v) => v.name,
|
||||
);
|
||||
final density = context.knobs.object.dropdown<SliderM3EDensity>(
|
||||
label: 'density',
|
||||
initialOption: SliderM3EDensity.regular,
|
||||
options: SliderM3EDensity.values,
|
||||
labelBuilder: (v) => v.name,
|
||||
);
|
||||
|
||||
final showValueIndicator = context.knobs.boolean(
|
||||
label: 'showValueIndicator',
|
||||
initialValue: false,
|
||||
);
|
||||
final withStartIcon = context.knobs.boolean(
|
||||
label: 'startIcon',
|
||||
initialValue: false,
|
||||
);
|
||||
final withEndIcon = context.knobs.boolean(
|
||||
label: 'endIcon',
|
||||
initialValue: false,
|
||||
);
|
||||
|
||||
// Content params
|
||||
final label = context.knobs.stringOrNull(
|
||||
label: 'label',
|
||||
initialValue: null,
|
||||
);
|
||||
// Avoid semantic callback when zeroRange to prevent divide-by-zero in tokens formatting
|
||||
final semanticLabel = zeroRange
|
||||
? null
|
||||
: context.knobs.stringOrNull(
|
||||
label: 'semanticLabel',
|
||||
initialValue: 'Progress',
|
||||
);
|
||||
|
||||
final onChanged = disabled
|
||||
? null
|
||||
: (double v) => print('SliderM3E onChanged -> $v');
|
||||
final onChangeStart = disabled
|
||||
? null
|
||||
: (double v) => print('SliderM3E onChangeStart -> $v');
|
||||
final onChangeEnd = disabled
|
||||
? null
|
||||
: (double v) => print('SliderM3E onChangeEnd -> $v');
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: SliderM3E(
|
||||
value: value,
|
||||
onChanged: onChanged,
|
||||
onChangeStart: onChangeStart,
|
||||
onChangeEnd: onChangeEnd,
|
||||
min: min,
|
||||
max: max,
|
||||
divisions: divisions,
|
||||
label: label,
|
||||
semanticLabel: semanticLabel,
|
||||
size: size,
|
||||
emphasis: emphasis,
|
||||
shapeFamily: shape,
|
||||
density: density,
|
||||
showValueIndicator: showValueIndicator,
|
||||
startIcon: withStartIcon ? const Icon(Icons.remove) : null,
|
||||
endIcon: withEndIcon ? const Icon(Icons.add) : null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@UseCase(name: 'default', type: SliderM3E)
|
||||
Widget buildSliderM3EDefaultUseCase(BuildContext context) {
|
||||
return _buildSliderM3EDemo(context);
|
||||
}
|
||||
|
||||
@UseCase(name: 'discrete', type: SliderM3E)
|
||||
Widget buildSliderM3EDiscreteUseCase(BuildContext context) {
|
||||
// Provide a default divisions count; still knob-customizable via 'divisions'
|
||||
return _buildSliderM3EDemo(context, forcedDivisions: 5);
|
||||
}
|
||||
|
||||
@UseCase(name: 'disabled', type: SliderM3E)
|
||||
Widget buildSliderM3EDisabledUseCase(BuildContext context) {
|
||||
return _buildSliderM3EDemo(context, disabled: true);
|
||||
}
|
||||
|
||||
@UseCase(name: 'extremes_0_to_100', type: SliderM3E)
|
||||
Widget buildSliderM3EExtremes0100UseCase(BuildContext context) {
|
||||
return _buildSliderM3EDemo(context, forcedMin: 0, forcedMax: 100);
|
||||
}
|
||||
|
||||
@UseCase(name: 'negative_range', type: SliderM3E)
|
||||
Widget buildSliderM3ENegativeRangeUseCase(BuildContext context) {
|
||||
return _buildSliderM3EDemo(context, forcedMin: -100, forcedMax: 0);
|
||||
}
|
||||
|
||||
@UseCase(name: 'min_equals_max', type: SliderM3E)
|
||||
Widget buildSliderM3EMinEqualsMaxUseCase(BuildContext context) {
|
||||
// Show a zero-range slider (min == max), interactions disabled to avoid semantic math
|
||||
return _buildSliderM3EDemo(context, zeroRange: true, disabled: true);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue