-
Notifications
You must be signed in to change notification settings - Fork 80
Initial Implementation for Rating Widget and Change EmptyPage to InitialPage on Samples #503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… sample and change EmptyPage to InitialPage showing all the routes available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 4 out of 11 changed files in this pull request and generated no comments.
Files not reviewed (7)
- forui/lib/forui.dart: Language not supported
- forui/lib/src/widgets/rating/rating.dart: Language not supported
- forui/lib/src/widgets/rating/rating_content.dart: Language not supported
- forui/lib/widgets/rating.dart: Language not supported
- forui/test/src/widgets/rating/rating_golden_test.dart: Language not supported
- samples/lib/main.dart: Language not supported
- samples/lib/widgets/rating.dart: Language not supported
This should complete #328 with additional caveats :
|
Documentation Preview
You're seeing this because the docs/samples were updated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
Just a heads up, we probably won't be able to fully review this until next week as we're got quite a packed week ahead of us.
} | ||
|
||
@override | ||
Widget build(BuildContext context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use FTappable
to manage the tapping/hovering logic.
final int count; | ||
|
||
/// Called when the rating value changes. | ||
final ValueChanged<double>? onStateChanged; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be onChange
, onStateChange
is meant for WidgetState
changes.
final FocusNode? focusNode; | ||
|
||
/// {@macro forui.foundation.doc_templates.onFocusChange} | ||
final ValueChanged<bool>? onFocusChange; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably add a onHoverChange
, I think you can use FButton
as a reference.
/// The spacing between rating icons. | ||
final double spacing; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be in the style.
this.filledIcon = const Icon(FIcons.star, color: Color(0xFFFFD700)), // Gold | ||
this.emptyIcon = const Icon(FIcons.starOff, color: Color(0xFFBDBDBD)), // Gray |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should move the color to inside the style. Generally for icons, we wrap them in a IconTheme
inside the build method, e.g. IconTheme(style.iconThemeData, child: filledIcon)
.
..add(IntProperty('count', count)) | ||
..add(FlagProperty('enabled', value: enabled, ifTrue: 'enabled')) | ||
..add(DiagnosticsProperty('style', style)) | ||
..add(ObjectFlagProperty<ValueChanged<double>?>.has('onStateChanged', onStateChanged)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
..add(ObjectFlagProperty<ValueChanged<double>?>.has('onStateChanged', onStateChanged)) | |
..add(ObjectFlagProperty.has('onStateChanged', onStateChanged)) |
Generally we don't specify the generic type for diagnostic properties.
..add(DiagnosticsProperty('style', style)) | ||
..add(ObjectFlagProperty<ValueChanged<double>?>.has('onStateChanged', onStateChanged)) | ||
..add(StringProperty('semanticsLabel', semanticsLabel)) | ||
..add(DiagnosticsProperty<bool>('autofocus', autofocus)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
..add(DiagnosticsProperty<bool>('autofocus', autofocus)) | |
..add(FlagProperty('autofocus', value: autofocus, ifTrue: 'autofocus')) |
double _calculateRating(double dx, double totalWidth) { | ||
if (totalWidth <= 0) { | ||
return 0; | ||
} | ||
|
||
final itemWidth = totalWidth / widget.count; | ||
final x = dx.clamp(0.0, totalWidth); | ||
final index = x ~/ itemWidth; | ||
final localPosition = x - (index * itemWidth); | ||
|
||
double rating = index + 1.0; | ||
if (widget.halfFilledIcon != null && localPosition < itemWidth / 2) { | ||
rating -= 0.5; | ||
} | ||
|
||
return rating.clamp(0.0, widget.count.toDouble()); | ||
} | ||
|
||
void _handleHover(PointerHoverEvent event) { | ||
final box = context.findRenderObject() as RenderBox?; | ||
if (box == null) { | ||
return; | ||
} | ||
|
||
final localPosition = box.globalToLocal(event.position); | ||
setState(() => _hoverValue = _calculateRating(localPosition.dx, box.size.width)); | ||
} | ||
|
||
void _handleTap(TapUpDetails details) { | ||
final box = context.findRenderObject()! as RenderBox; | ||
final localPosition = box.globalToLocal(details.globalPosition); | ||
final rating = _calculateRating(localPosition.dx, box.size.width); | ||
|
||
widget.onStateChanged?.call(rating); | ||
setState(() => _isHovering = false); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally, I think we should try to avoid using retrieving the renderbox like this. Perhaps, you can use the PointerEnterEvent
passed into MouseRegion.onEnter
to calculate the size?
I think there's something similar for tap gestures too.
/// A line calendar displays dates in a single horizontal, scrollable line. | ||
/// | ||
/// See https://forui.dev/docs/data/line-calendar for working examples. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docs need to be updated.
final class FRatingStyle with Diagnosticable, _$FRatingStyleFunctions { | ||
/// The color of the rating icons. | ||
@override | ||
final Color? color; | ||
|
||
/// The size of the rating icons. | ||
@override | ||
final double? size; | ||
|
||
/// Creates a [FRatingStyle]. | ||
const FRatingStyle({this.color, this.size}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these properties can be merged into a IconThemeData
. IconThemeData
can then be wrapped inside a FWidgetStateMap
to account for the various states, i.e. selected & unselected.
I think you can reference FTileContentStyle
.
It's ok. I'll be busy till weekend anyways. |
Btw.. I suggest that this should be delayed until 0.12. Seeing how @Pante refactored the nested header. It seems like I need to be guided more. Not a good programmer here lol, plus I need the header update soon for my future app. |
No worries! On another note, we're planning to release 0.11.0 on 1st May. |
Describe the changes
Checklist