using Connected.Annotations; using Connected.Utilities; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; namespace Connected.Components; public partial class Rating : UIComponent { /// /// Space separated class names /// protected string ClassName => new CssBuilder("") .AddClass($"mud-rating-root") .AddClass(Class) .Build(); /// /// User class names for RatingItems, separated by space /// [Parameter] [Category(CategoryTypes.Rating.Appearance)] public string RatingItemsClass { get; set; } /// /// User styles for RatingItems. /// [Parameter] [Category(CategoryTypes.Rating.Appearance)] public string RatingItemsStyle { get; set; } /// /// Input name. If not initialized, name will be random guid. /// [Parameter] [Category(CategoryTypes.Rating.Behavior)] public string Name { get; set; } = Guid.NewGuid().ToString(); /// /// Max value and how many elements to click will be generated. Default: 5 /// [Parameter] [Category(CategoryTypes.Rating.Behavior)] public int MaxValue { get; set; } = 5; /// /// Selected or hovered icon. Default @Icons.Material.Star /// [Parameter] [Category(CategoryTypes.Rating.Appearance)] public string FullIcon { get; set; } = Icons.Material.Filled.Star; /// /// Non selected item icon. Default @Icons.Material.StarBorder /// [Parameter] [Category(CategoryTypes.Rating.Appearance)] public string EmptyIcon { get; set; } = Icons.Material.Filled.StarBorder; /// /// The color of the component. It supports the theme colors. /// [Parameter] [Category(CategoryTypes.Rating.Appearance)] public ThemeColor Color { get; set; } = ThemeColor.Default; /// /// The Size of the icons. /// [Parameter] [Category(CategoryTypes.Rating.Appearance)] public Size Size { get; set; } = Size.Medium; /// /// If true, disables ripple effect. /// [Parameter] [Category(CategoryTypes.Rating.Appearance)] public bool DisableRipple { get; set; } /// /// If true, the controls will be disabled. /// [Parameter] [Category(CategoryTypes.Rating.Behavior)] public bool Disabled { get; set; } /// /// If true, the ratings will show without interactions. /// [Parameter] [Category(CategoryTypes.Rating.Behavior)] public bool ReadOnly { get; set; } /// /// Fires when SelectedValue changes. /// [Parameter] public EventCallback SelectedValueChanged { get; set; } /// /// Selected value. This property is two-way bindable. /// [Parameter] [Category(CategoryTypes.Rating.Data)] public int SelectedValue { get => _selectedValue; set { if (_selectedValue == value) return; _selectedValue = value; SelectedValueChanged.InvokeAsync(_selectedValue); } } private int _selectedValue = 0; /// /// Fires when hovered value change. Value will be null if no rating item is hovered. /// [Parameter] public EventCallback HoveredValueChanged { get; set; } internal int? HoveredValue { get => _hoveredValue; set { if (_hoveredValue == value) return; _hoveredValue = value; HoveredValueChanged.InvokeAsync(value); } } private int? _hoveredValue = null; internal bool IsRatingHover => HoveredValue.HasValue; private void HandleItemClicked(int itemValue) { SelectedValue = itemValue; if (itemValue == 0) { HoveredValue = null; } } internal void HandleItemHovered(int? itemValue) => HoveredValue = itemValue; private void IncreaseValue(int val) { if ((SelectedValue == MaxValue && val > 0) || (SelectedValue == 0 && val < 0)) { } else { SelectedValue += val; } } protected internal void HandleKeyDown(KeyboardEventArgs obj) { if (Disabled || ReadOnly) { return; } switch (obj.Key) { case "ArrowRight": if (obj.ShiftKey == true) { IncreaseValue(MaxValue - SelectedValue); } else { IncreaseValue(1); } break; case "ArrowLeft": if (obj.ShiftKey == true) { IncreaseValue(-SelectedValue); } else { IncreaseValue(-1); } break; } } }