Skip to content

Commit

Permalink
feat: [MDS-576] Create DotIndicator widget (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kypsis committed Jul 3, 2023
1 parent 8a41ec7 commit 41b0ab9
Show file tree
Hide file tree
Showing 8 changed files with 459 additions and 0 deletions.
107 changes: 107 additions & 0 deletions example/lib/src/storybook/stories/dot_indicator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import 'package:example/src/storybook/common/color_options.dart';
import 'package:flutter/material.dart';
import 'package:moon_design/moon_design.dart';
import 'package:storybook_flutter/storybook_flutter.dart';

int _selectedDot = 0;

class DotIndicatorStory extends Story {
DotIndicatorStory()
: super(
name: "DotIndicator",
builder: (context) {
final selectedColorsKnob = context.knobs.nullable.options(
label: "selectedColor",
description: "MoonColors variants for MoonDotIndicator selected dot.",
enabled: false,
initial: 0,
// piccolo
options: colorOptions,
);

final selectedColor = colorTable(context)[selectedColorsKnob ?? 40];

final unselectedColorsKnob = context.knobs.nullable.options(
label: "unselectedColor",
description: "MoonColors variants for MoonDotIndicator unselected dots.",
enabled: false,
initial: 0,
// piccolo
options: colorOptions,
);

final unselectedColor = colorTable(context)[unselectedColorsKnob ?? 40];

final sizeKnob = context.knobs.nullable.sliderInt(
label: "size",
description: "MoonDotIndicator dot size.",
enabled: false,
initial: 8,
max: 32,
);

final gapKnob = context.knobs.nullable.sliderInt(
label: "gap",
description: "Gap between MoonDotIndicator dots.",
enabled: false,
initial: 8,
max: 32,
);

return Center(
child: StatefulBuilder(
builder: (context, setState) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 64),
MoonDotIndicator(
selectedDot: _selectedDot,
dotCount: 4,
size: sizeKnob?.toDouble(),
gap: gapKnob?.toDouble(),
selectedColor: selectedColor,
unselectedColor: unselectedColor,
),
const SizedBox(height: 32),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MoonFilledButton(
label: const Text("1"),
onTap: () => setState(() {
_selectedDot = 0;
}),
),
const SizedBox(width: 8),
MoonFilledButton(
label: const Text("2"),
onTap: () => setState(() {
_selectedDot = 1;
}),
),
const SizedBox(width: 8),
MoonFilledButton(
label: const Text("3"),
onTap: () => setState(() {
_selectedDot = 2;
}),
),
const SizedBox(width: 8),
MoonFilledButton(
label: const Text("4"),
onTap: () => setState(() {
_selectedDot = 3;
}),
),
],
),
const SizedBox(height: 64),
],
);
},
),
);
},
);
}
2 changes: 2 additions & 0 deletions example/lib/src/storybook/storybook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:example/src/storybook/stories/checkbox.dart';
import 'package:example/src/storybook/stories/chip.dart';
import 'package:example/src/storybook/stories/circular_loader.dart';
import 'package:example/src/storybook/stories/circular_progress.dart';
import 'package:example/src/storybook/stories/dot_indicator.dart';
import 'package:example/src/storybook/stories/icons.dart';
import 'package:example/src/storybook/stories/linear_loader.dart';
import 'package:example/src/storybook/stories/linear_progress.dart';
Expand Down Expand Up @@ -91,6 +92,7 @@ class StorybookPage extends StatelessWidget {
ChipStory(),
CircularLoaderStory(),
CircularProgressStory(),
DotIndicatorStory(),
IconsStory(),
LinearLoaderStory(),
LinearProgressStory(),
Expand Down
2 changes: 2 additions & 0 deletions lib/moon_design.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export 'package:moon_design/src/theme/button/button_theme.dart';
export 'package:moon_design/src/theme/checkbox/checkbox_theme.dart';
export 'package:moon_design/src/theme/chip/chip_theme.dart';
export 'package:moon_design/src/theme/colors.dart';
export 'package:moon_design/src/theme/dot_indicator/dot_indicator_theme.dart';
export 'package:moon_design/src/theme/effects/effects.dart';
export 'package:moon_design/src/theme/icons/icon_theme.dart';
export 'package:moon_design/src/theme/loaders/circular_loader/circular_loader_theme.dart';
Expand Down Expand Up @@ -66,6 +67,7 @@ export 'package:moon_design/src/widgets/common/icons/icons.dart';
export 'package:moon_design/src/widgets/common/icons/moon_icon.dart';
export 'package:moon_design/src/widgets/common/progress_indicators/circular_progress_indicator.dart';
export 'package:moon_design/src/widgets/common/progress_indicators/linear_progress_indicator.dart';
export 'package:moon_design/src/widgets/dot_indicator/dot_indicator.dart';
export 'package:moon_design/src/widgets/loaders/circular_loader.dart';
export 'package:moon_design/src/widgets/loaders/linear_loader.dart';
export 'package:moon_design/src/widgets/modal/modal.dart';
Expand Down
59 changes: 59 additions & 0 deletions lib/src/theme/dot_indicator/dot_indicator_colors.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'package:moon_design/src/theme/colors.dart';
import 'package:moon_design/src/utils/color_premul_lerp.dart';

@immutable
class MoonDotIndicatorColors extends ThemeExtension<MoonDotIndicatorColors> with DiagnosticableTreeMixin {
static final light = MoonDotIndicatorColors(
selectedColor: MoonColors.light.piccolo,
unselectedColor: MoonColors.light.beerus,
);

static final dark = MoonDotIndicatorColors(
selectedColor: MoonColors.dark.piccolo,
unselectedColor: MoonColors.dark.beerus,
);

/// Selected DotIndicator dot color.
final Color selectedColor;

/// Unselected DotIndicator dot color.
final Color unselectedColor;

const MoonDotIndicatorColors({
required this.selectedColor,
required this.unselectedColor,
});

@override
MoonDotIndicatorColors copyWith({
Color? selectedColor,
Color? unselectedColor,
}) {
return MoonDotIndicatorColors(
selectedColor: selectedColor ?? this.selectedColor,
unselectedColor: unselectedColor ?? this.unselectedColor,
);
}

@override
MoonDotIndicatorColors lerp(ThemeExtension<MoonDotIndicatorColors>? other, double t) {
if (other is! MoonDotIndicatorColors) return this;

return MoonDotIndicatorColors(
selectedColor: colorPremulLerp(selectedColor, other.selectedColor, t)!,
unselectedColor: colorPremulLerp(unselectedColor, other.unselectedColor, t)!,
);
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty("type", "MoonDotIndicatorColors"))
..add(ColorProperty("selectedColor", selectedColor))
..add(ColorProperty("unselectedColor", unselectedColor));
}
}
73 changes: 73 additions & 0 deletions lib/src/theme/dot_indicator/dot_indicator_properties.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'package:moon_design/src/theme/sizes.dart';

@immutable
class MoonDotIndicatorProperties extends ThemeExtension<MoonDotIndicatorProperties> with DiagnosticableTreeMixin {
static final properties = MoonDotIndicatorProperties(
gap: MoonSizes.sizes.x4s,
size: MoonSizes.sizes.x4s,
transitionDuration: const Duration(milliseconds: 200),
transitionCurve: Curves.easeInOutCubic,
);

/// DotIndicator gap between dots.
final double gap;

/// DotIndicator dot size.
final double size;

/// DotIndicator transition duration.
final Duration transitionDuration;

/// DotIndicator transition curve.
final Curve transitionCurve;

const MoonDotIndicatorProperties({
required this.size,
required this.transitionDuration,
required this.transitionCurve,
required this.gap,
});

@override
MoonDotIndicatorProperties copyWith({
double? gap,
double? size,
Duration? transitionDuration,
Curve? transitionCurve,
}) {
return MoonDotIndicatorProperties(
gap: gap ?? this.gap,
size: size ?? this.size,
transitionDuration: transitionDuration ?? this.transitionDuration,
transitionCurve: transitionCurve ?? this.transitionCurve,
);
}

@override
MoonDotIndicatorProperties lerp(ThemeExtension<MoonDotIndicatorProperties>? other, double t) {
if (other is! MoonDotIndicatorProperties) return this;

return MoonDotIndicatorProperties(
gap: lerpDouble(gap, other.gap, t)!,
size: lerpDouble(size, other.size, t)!,
transitionDuration: lerpDuration(transitionDuration, other.transitionDuration, t),
transitionCurve: other.transitionCurve,
);
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty("type", "MoonDotIndicatorProperties"))
..add(DoubleProperty("gap", gap))
..add(DoubleProperty("size", size))
..add(DiagnosticsProperty<Duration>("transitionDuration", transitionDuration))
..add(DiagnosticsProperty<Curve>("transitionCurve", transitionCurve));
}
}
59 changes: 59 additions & 0 deletions lib/src/theme/dot_indicator/dot_indicator_theme.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'package:moon_design/src/theme/dot_indicator/dot_indicator_colors.dart';
import 'package:moon_design/src/theme/dot_indicator/dot_indicator_properties.dart';

@immutable
class MoonDotIndicatorTheme extends ThemeExtension<MoonDotIndicatorTheme> with DiagnosticableTreeMixin {
static final light = MoonDotIndicatorTheme(
colors: MoonDotIndicatorColors.light,
properties: MoonDotIndicatorProperties.properties,
);

static final dark = MoonDotIndicatorTheme(
colors: MoonDotIndicatorColors.dark,
properties: MoonDotIndicatorProperties.properties,
);

/// DotIndicator colors.
final MoonDotIndicatorColors colors;

/// DotIndicator properties.
final MoonDotIndicatorProperties properties;

const MoonDotIndicatorTheme({
required this.colors,
required this.properties,
});

@override
MoonDotIndicatorTheme copyWith({
MoonDotIndicatorColors? colors,
MoonDotIndicatorProperties? properties,
}) {
return MoonDotIndicatorTheme(
colors: colors ?? this.colors,
properties: properties ?? this.properties,
);
}

@override
MoonDotIndicatorTheme lerp(ThemeExtension<MoonDotIndicatorTheme>? other, double t) {
if (other is! MoonDotIndicatorTheme) return this;

return MoonDotIndicatorTheme(
colors: colors.lerp(other.colors, t),
properties: properties.lerp(other.properties, t),
);
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder diagnosticProperties) {
super.debugFillProperties(diagnosticProperties);
diagnosticProperties
..add(DiagnosticsProperty("type", "MoonDotIndicatorTheme"))
..add(DiagnosticsProperty<MoonDotIndicatorColors>("colors", colors))
..add(DiagnosticsProperty<MoonDotIndicatorProperties>("properties", properties));
}
}
Loading

0 comments on commit 41b0ab9

Please sign in to comment.