using System.Diagnostics.CodeAnalysis; using Connected.Annotations; using Connected.Extensions; using Connected.Services; using Connected.Utilities; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; namespace Connected.Components; public partial class Switch : BooleanInput { protected string Classname => new CssBuilder("mud-switch") .AddClass($"mud-disabled", Disabled) .AddClass($"mud-readonly", ReadOnly) .AddClass(LabelPosition == LabelPosition.End ? "mud-ltr" : "mud-rtl", true) .AddClass(Class) .Build(); protected string SwitchClassname => new CssBuilder("mud-button-root mud-icon-button mud-switch-base") .AddClass($"mud-ripple mud-ripple-switch", !DisableRipple && !ReadOnly && !Disabled) .AddClass($"mud-{Color.ToDescriptionString()}-text hover:mud-{Color.ToDescriptionString()}-hover", BoolValue == true) .AddClass($"mud-{UnCheckedColor.ToDescriptionString()}-text hover:mud-{UnCheckedColor.ToDescriptionString()}-hover", BoolValue == false) .AddClass($"mud-switch-disabled", Disabled) .AddClass($"mud-readonly", ReadOnly) .AddClass($"mud-checked", BoolValue) .Build(); protected string TrackClassname => new CssBuilder("mud-switch-track") .AddClass($"mud-{Color.ToDescriptionString()}", BoolValue == true) .AddClass($"mud-{UnCheckedColor.ToDescriptionString()}", BoolValue == false) .Build(); //Excluded because not used [ExcludeFromCodeCoverage] protected string SpanClassname => new CssBuilder("mud-switch-span mud-flip-x-rtl") .Build(); private IKeyInterceptor _keyInterceptor; [Inject] private IKeyInterceptorFactory KeyInterceptorFactory { get; set; } /// /// The color of the component. It supports the theme colors. /// [Parameter] [Category(CategoryTypes.FormComponent.Appearance)] public ThemeColor Color { get; set; } = ThemeColor.Default; /// /// The base color of the component in its none active/unchecked state. It supports the theme colors. /// [Parameter] [Category(CategoryTypes.Radio.Appearance)] public ThemeColor UnCheckedColor { get; set; } = ThemeColor.Default; /// /// The text/label will be displayed next to the switch if set. /// [Parameter] [Category(CategoryTypes.FormComponent.Behavior)] public string Label { get; set; } /// /// The position of the text/label. /// [Parameter] [Category(CategoryTypes.FormComponent.Behavior)] public LabelPosition LabelPosition { get; set; } = LabelPosition.End; /// /// Shows an icon on Switch's thumb. /// [Parameter] [Category(CategoryTypes.FormComponent.Appearance)] public string ThumbIcon { get; set; } /// /// The color of the thumb icon. Supports the theme colors. /// [Parameter] [Category(CategoryTypes.FormComponent.Appearance)] public ThemeColor ThumbIconColor { get; set; } = ThemeColor.Default; /// /// If true, disables ripple effect. /// [Parameter] [Category(CategoryTypes.FormComponent.Appearance)] public bool DisableRipple { get; set; } protected internal void HandleKeyDown(KeyboardEventArgs obj) { if (Disabled || ReadOnly) return; switch (obj.Key) { case "ArrowLeft": case "Delete": SetBoolValueAsync(false); break; case "ArrowRight": case "Enter": case "NumpadEnter": SetBoolValueAsync(true); break; case " ": if (BoolValue == true) { SetBoolValueAsync(false); } else { SetBoolValueAsync(true); } break; } } private string _elementId = "switch_" + Guid.NewGuid().ToString().Substring(0, 8); protected override void OnInitialized() { base.OnInitialized(); if (Label == null && For != null) Label = For.GetLabelString(); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { _keyInterceptor = KeyInterceptorFactory.Create(); await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions() { //EnableLogging = true, TargetClass = "mud-switch-base", Keys = { new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead increment new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead decrement new KeyOptions { Key=" ", PreventDown = "key+none", PreventUp = "key+none" }, }, }); _keyInterceptor.KeyDown += HandleKeyDown; } await base.OnAfterRenderAsync(firstRender); } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing == true) { if (_keyInterceptor != null) { _keyInterceptor.KeyDown -= HandleKeyDown; _keyInterceptor.Dispose(); } } } }