Skip to content

Commit

Permalink
feat: add time picker theme
Browse files Browse the repository at this point in the history
  • Loading branch information
nank1ro committed Nov 25, 2024
1 parent 9435616 commit 23c55f2
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 19 deletions.
52 changes: 35 additions & 17 deletions lib/src/components/time_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -485,10 +485,15 @@ class _ShadTimePickerState extends State<ShadTimePicker> {
@override
Widget build(BuildContext context) {
final theme = ShadTheme.of(context);
final effectiveAxis = widget.axis ?? Axis.horizontal;
final effectiveSpacing = widget.spacing ?? 0;
final effectiveRunSpacing = widget.runSpacing ?? 0;
final effectiveJumpToNextField = widget.jumpToNextFieldWhenFilled ?? true;
final effectiveAxis =
widget.axis ?? theme.timePickerTheme.axis ?? Axis.horizontal;
final effectiveSpacing =
widget.spacing ?? theme.timePickerTheme.spacing ?? 0;
final effectiveRunSpacing =
widget.runSpacing ?? theme.timePickerTheme.runSpacing ?? 0;
final effectiveJumpToNextField = widget.jumpToNextFieldWhenFilled ??
theme.timePickerTheme.jumpToNextFieldWhenFilled ??
true;
final effectiveHourLabel = widget.hourLabel ?? const Text('Hours');
final effectiveMinuteLabel = widget.minuteLabel ?? const Text('Minutes');
final effectiveSecondLabel = widget.secondLabel ?? const Text('Seconds');
Expand All @@ -503,16 +508,25 @@ class _ShadTimePickerState extends State<ShadTimePicker> {
widget.secondPlaceholder ?? defaultPlaceholder;
final effectivePeriodPlaceholder = widget.periodPlaceholder;

final effectiveAlignment = widget.alignment ?? WrapAlignment.center;
final effectiveRunAlignment = widget.runAlignment ?? WrapAlignment.center;
final effectiveCrossAxisAlignment =
widget.crossAxisAlignment ?? WrapCrossAlignment.center;

final effectivePeriodHeight = widget.periodHeight ?? 50;
final effectivePeriodMinWidth = widget.periodMinWidth ?? 65;
final effectiveGap = widget.gap ?? 2;
final effectiveFieldWidth = widget.fieldWidth ?? 58;
final effectiveAlignment = widget.alignment ??
theme.timePickerTheme.alignment ??
WrapAlignment.center;
final effectiveRunAlignment = widget.runAlignment ??
theme.timePickerTheme.runAlignment ??
WrapAlignment.center;
final effectiveCrossAxisAlignment = widget.crossAxisAlignment ??
theme.timePickerTheme.crossAxisAlignment ??
WrapCrossAlignment.center;

final effectivePeriodHeight =
widget.periodHeight ?? theme.timePickerTheme.periodHeight ?? 50;
final effectivePeriodMinWidth =
widget.periodMinWidth ?? theme.timePickerTheme.periodMinWidth ?? 65;
final effectiveGap = widget.gap ?? theme.timePickerTheme.gap ?? 2;
final effectiveFieldWidth =
widget.fieldWidth ?? theme.timePickerTheme.fieldWidth ?? 58;
final effectiveFieldPadding = widget.fieldPadding ??
theme.timePickerTheme.fieldPadding ??
const EdgeInsets.symmetric(horizontal: 12, vertical: 8);

final effectiveStyle = theme.textTheme.muted
Expand All @@ -521,10 +535,13 @@ class _ShadTimePickerState extends State<ShadTimePicker> {
fontSize: 16,
height: 24 / 16,
)
.merge(theme.timePickerTheme.style)
.merge(widget.style);

final effectiveLabelStyle =
theme.textTheme.small.copyWith(fontSize: 12).merge(widget.labelStyle);
final effectiveLabelStyle = theme.textTheme.small
.copyWith(fontSize: 12)
.merge(theme.timePickerTheme.labelStyle)
.merge(widget.labelStyle);

return Wrap(
direction: effectiveAxis,
Expand Down Expand Up @@ -793,8 +810,9 @@ class ShadTimePickerTextEditingController extends TextEditingController {
fontSize: 16,
height: 24 / 16,
);
final effectivePlaceholderStyle =
defaultPlaceholderStyle.merge(placeholderStyle);
final effectivePlaceholderStyle = defaultPlaceholderStyle
.merge(theme.timePickerTheme.placeholderStyle)
.merge(placeholderStyle);

final intValue = int.tryParse(value.text);
if (intValue == null) return const TextSpan();
Expand Down
213 changes: 213 additions & 0 deletions lib/src/theme/components/time_picker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import 'dart:ui';

import 'package:flutter/material.dart';

@immutable
class ShadTimePickerTheme {
const ShadTimePickerTheme({
this.merge = true,
this.axis,
this.spacing,
this.runSpacing,
this.jumpToNextFieldWhenFilled,
this.alignment,
this.runAlignment,
this.crossAxisAlignment,
this.initialDayPeriod,
this.periodHeight,
this.periodMinWidth,
this.gap,
this.style,
this.placeholderStyle,
this.labelStyle,
this.fieldWidth,
this.fieldPadding,
});

final bool merge;

/// {@macro ShadTimePicker.axis}
final Axis? axis;

/// {@macro ShadTimePicker.spacing}
final double? spacing;

/// {@macro ShadTimePicker.runSpacing}
final double? runSpacing;

/// {@macro ShadTimePicker.jumpToNextFieldWhenFilled}
final bool? jumpToNextFieldWhenFilled;

/// {@macro ShadTimePicker.alignment}
final WrapAlignment? alignment;

/// {@macro ShadTimePicker.runAlignment}
final WrapAlignment? runAlignment;

/// {@macro ShadTimePicker.crossAxisAlignment}
final WrapCrossAlignment? crossAxisAlignment;

/// {@macro ShadTimePicker.initialDayPeriod}
final DayPeriod? initialDayPeriod;

/// {@macro ShadTimePicker.periodHeight}
final double? periodHeight;

/// {@macro ShadTimePicker.periodMinWidth}
final double? periodMinWidth;

/// {@macro ShadTimePicker.gap}
final double? gap;

/// {@macro ShadTimePicker.style}
final TextStyle? style;

/// {@macro ShadTimePicker.placeholderStyle}
final TextStyle? placeholderStyle;

/// {@macro ShadTimePicker.labelStyle}
final TextStyle? labelStyle;

/// {@macro ShadTimePicker.fieldWidth}
final double? fieldWidth;

/// {@macro ShadTimePicker.fieldPadding}
final EdgeInsets? fieldPadding;

static ShadTimePickerTheme lerp(
ShadTimePickerTheme a,
ShadTimePickerTheme b,
double t,
) {
if (identical(a, b)) return a;
return ShadTimePickerTheme(
merge: b.merge,
axis: t < 0.5 ? a.axis : b.axis,
spacing: lerpDouble(a.spacing, b.spacing, t),
runSpacing: lerpDouble(a.runSpacing, b.runSpacing, t),
jumpToNextFieldWhenFilled:
t < 0.5 ? a.jumpToNextFieldWhenFilled : b.jumpToNextFieldWhenFilled,
alignment: b.alignment ?? a.alignment,
runAlignment: b.runAlignment ?? a.runAlignment,
crossAxisAlignment: b.crossAxisAlignment ?? a.crossAxisAlignment,
initialDayPeriod: b.initialDayPeriod ?? a.initialDayPeriod,
periodHeight: b.periodHeight ?? a.periodHeight,
periodMinWidth: b.periodMinWidth ?? a.periodMinWidth,
gap: b.gap ?? a.gap,
style: b.style ?? a.style,
placeholderStyle: b.placeholderStyle ?? a.placeholderStyle,
labelStyle: b.labelStyle ?? a.labelStyle,
fieldWidth: b.fieldWidth ?? a.fieldWidth,
fieldPadding: b.fieldPadding ?? a.fieldPadding,
);
}

ShadTimePickerTheme copyWith({
bool? merge,
Axis? axis,
double? spacing,
double? runSpacing,
bool? jumpToNextFieldWhenFilled,
WrapAlignment? alignment,
WrapAlignment? runAlignment,
WrapCrossAlignment? crossAxisAlignment,
DayPeriod? initialDayPeriod,
double? periodHeight,
double? periodMinWidth,
double? gap,
TextStyle? style,
TextStyle? placeholderStyle,
TextStyle? labelStyle,
double? fieldWidth,
EdgeInsets? fieldPadding,
}) {
return ShadTimePickerTheme(
merge: merge ?? this.merge,
axis: axis ?? this.axis,
spacing: spacing ?? this.spacing,
runSpacing: runSpacing ?? this.runSpacing,
jumpToNextFieldWhenFilled:
jumpToNextFieldWhenFilled ?? this.jumpToNextFieldWhenFilled,
alignment: alignment ?? this.alignment,
runAlignment: runAlignment ?? this.runAlignment,
crossAxisAlignment: crossAxisAlignment ?? this.crossAxisAlignment,
initialDayPeriod: initialDayPeriod ?? this.initialDayPeriod,
periodHeight: periodHeight ?? this.periodHeight,
periodMinWidth: periodMinWidth ?? this.periodMinWidth,
gap: gap ?? this.gap,
style: style ?? this.style,
placeholderStyle: placeholderStyle ?? this.placeholderStyle,
labelStyle: labelStyle ?? this.labelStyle,
fieldWidth: fieldWidth ?? this.fieldWidth,
fieldPadding: fieldPadding ?? this.fieldPadding,
);
}

ShadTimePickerTheme mergeWith(ShadTimePickerTheme? other) {
if (other == null) return this;
if (!other.merge) return other;
return copyWith(
axis: other.axis,
spacing: other.spacing,
runSpacing: other.runSpacing,
jumpToNextFieldWhenFilled: other.jumpToNextFieldWhenFilled,
alignment: other.alignment,
runAlignment: other.runAlignment,
crossAxisAlignment: other.crossAxisAlignment,
initialDayPeriod: other.initialDayPeriod,
periodHeight: other.periodHeight,
periodMinWidth: other.periodMinWidth,
gap: other.gap,
style: other.style,
placeholderStyle: other.placeholderStyle,
labelStyle: other.labelStyle,
fieldWidth: other.fieldWidth,
fieldPadding: other.fieldPadding,
);
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is ShadTimePickerTheme &&
other.merge == merge &&
other.axis == axis &&
other.spacing == spacing &&
other.runSpacing == runSpacing &&
other.jumpToNextFieldWhenFilled == jumpToNextFieldWhenFilled &&
other.alignment == alignment &&
other.runAlignment == runAlignment &&
other.crossAxisAlignment == crossAxisAlignment &&
other.initialDayPeriod == initialDayPeriod &&
other.periodHeight == periodHeight &&
other.periodMinWidth == periodMinWidth &&
other.gap == gap &&
other.style == style &&
other.placeholderStyle == placeholderStyle &&
other.labelStyle == labelStyle &&
other.fieldWidth == fieldWidth &&
other.fieldPadding == fieldPadding;
}

@override
int get hashCode {
return merge.hashCode ^
axis.hashCode ^
spacing.hashCode ^
runSpacing.hashCode ^
jumpToNextFieldWhenFilled.hashCode ^
alignment.hashCode ^
runAlignment.hashCode ^
crossAxisAlignment.hashCode ^
initialDayPeriod.hashCode ^
periodHeight.hashCode ^
periodMinWidth.hashCode ^
gap.hashCode ^
style.hashCode ^
placeholderStyle.hashCode ^
labelStyle.hashCode ^
fieldWidth.hashCode ^
fieldPadding.hashCode;
}
}
15 changes: 13 additions & 2 deletions lib/src/theme/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import 'package:shadcn_ui/src/theme/components/slider.dart';
import 'package:shadcn_ui/src/theme/components/switch.dart';
import 'package:shadcn_ui/src/theme/components/table.dart';
import 'package:shadcn_ui/src/theme/components/tabs.dart';
import 'package:shadcn_ui/src/theme/components/time_picker.dart';
import 'package:shadcn_ui/src/theme/components/toast.dart';
import 'package:shadcn_ui/src/theme/components/tooltip.dart';
import 'package:shadcn_ui/src/theme/text_theme/theme.dart';
Expand Down Expand Up @@ -86,6 +87,7 @@ class ShadThemeData extends ShadBaseTheme {
ShadContextMenuTheme? contextMenuTheme,
ShadCalendarTheme? calendarTheme,
ShadDatePickerTheme? datePickerTheme,
ShadTimePickerTheme? timePickerTheme,
}) {
final effectiveRadius =
radius ?? const BorderRadius.all(Radius.circular(6));
Expand Down Expand Up @@ -225,6 +227,8 @@ class ShadThemeData extends ShadBaseTheme {
calendarTheme: effectiveVariant.calendarTheme().mergeWith(calendarTheme),
datePickerTheme:
effectiveVariant.datePickerTheme().mergeWith(datePickerTheme),
timePickerTheme:
effectiveVariant.timePickerTheme().mergeWith(timePickerTheme),
);
}

Expand Down Expand Up @@ -276,6 +280,7 @@ class ShadThemeData extends ShadBaseTheme {
required super.contextMenuTheme,
required super.calendarTheme,
required super.datePickerTheme,
required super.timePickerTheme,
});

static ShadThemeData lerp(ShadThemeData a, ShadThemeData b, double t) {
Expand Down Expand Up @@ -374,6 +379,8 @@ class ShadThemeData extends ShadBaseTheme {
ShadCalendarTheme.lerp(a.calendarTheme, b.calendarTheme, t),
datePickerTheme:
ShadDatePickerTheme.lerp(a.datePickerTheme, b.datePickerTheme, t),
timePickerTheme:
ShadTimePickerTheme.lerp(a.timePickerTheme, b.timePickerTheme, t),
);
}

Expand Down Expand Up @@ -428,7 +435,8 @@ class ShadThemeData extends ShadBaseTheme {
other.tabsTheme == tabsTheme &&
other.contextMenuTheme == contextMenuTheme &&
other.calendarTheme == calendarTheme &&
other.datePickerTheme == datePickerTheme;
other.datePickerTheme == datePickerTheme &&
other.timePickerTheme == timePickerTheme;
}

@override
Expand Down Expand Up @@ -479,7 +487,8 @@ class ShadThemeData extends ShadBaseTheme {
tabsTheme.hashCode ^
contextMenuTheme.hashCode ^
calendarTheme.hashCode ^
datePickerTheme.hashCode;
datePickerTheme.hashCode ^
timePickerTheme.hashCode;
}

ShadThemeData copyWith({
Expand Down Expand Up @@ -530,6 +539,7 @@ class ShadThemeData extends ShadBaseTheme {
ShadContextMenuTheme? contextMenuTheme,
ShadCalendarTheme? calendarTheme,
ShadDatePickerTheme? datePickerTheme,
ShadTimePickerTheme? timePickerTheme,
}) {
return ShadThemeData(
colorScheme: colorScheme ?? this.colorScheme,
Expand Down Expand Up @@ -584,6 +594,7 @@ class ShadThemeData extends ShadBaseTheme {
contextMenuTheme: contextMenuTheme ?? this.contextMenuTheme,
calendarTheme: calendarTheme ?? this.calendarTheme,
datePickerTheme: datePickerTheme ?? this.datePickerTheme,
timePickerTheme: timePickerTheme ?? this.timePickerTheme,
);
}
}
Loading

0 comments on commit 23c55f2

Please sign in to comment.