Skip to content
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

🐛 fix(Switch/Checkbox): display the focus state only when focused by keyboard #2086

Merged
merged 2 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/Masa.Blazor.JS/src/interop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import throttle from "just-throttle";
import { parseDragEvent, parseTouchEvent, touchEvents } from "./events/EventType";
import { registerExtraEvents } from "./events/index";
import registerRippleObserver from "./ripple";
import { canUseDom, getBlazorId, getDom, getElementSelector } from "./utils/helper";
import { canUseDom, getBlazorId, getDom, getElementSelector, IN_BROWSER } from "./utils/helper";

window.onload = function () {
registerExtraEvents();
Expand Down Expand Up @@ -1638,4 +1638,19 @@ export function isScrollNearBottom(element: HTMLElement, threshold: number = 200
return false;
}
return element.scrollHeight - (element.scrollTop + element.clientHeight) < threshold;
}
}

export function matchesSelector (el: Element | undefined, selector: string): boolean | null {
const supportsSelector = IN_BROWSER &&
typeof CSS !== 'undefined' &&
typeof CSS.supports !== 'undefined' &&
CSS.supports(`selector(${selector})`)

if (!supportsSelector) return false;

try {
return !!el && el.matches(selector)
} catch (err) {
return false;
}
}
6 changes: 4 additions & 2 deletions src/Masa.Blazor.JS/src/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const IN_BROWSER = typeof window !== 'undefined'

export function addOnceEventListener (
el: EventTarget,
eventName: string,
Expand All @@ -14,7 +16,7 @@ export function addOnceEventListener (

let passiveSupported = false
try {
if (typeof window !== 'undefined') {
if (IN_BROWSER) {
const testListenerOpts = Object.defineProperty({}, 'passive', {
get: () => {
passiveSupported = true
Expand Down Expand Up @@ -183,7 +185,7 @@ export function getDom(elOrString: Element | string | undefined) {
}

export const canUseDom = !!(
typeof window !== 'undefined' &&
IN_BROWSER &&
typeof document !== 'undefined' &&
window.document &&
window.document.createElement
Expand Down
4 changes: 2 additions & 2 deletions src/Masa.Blazor/Components/Switch/MSwitch.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
{
var trackStyle = GetStyleBuilder().AddBackgroundColor(ComputedTrackColor).Build();

<div class="@ControlBlock.Element("wrapper")">
<div class="@ControlWrapper.Name">
<div class="@_trackModifierBuilder.AddTextColor(CurrentColor).AddBackgroundColor(ComputedTrackColor).AddTheme(IsDark, IndependentTheme)"
style="@trackStyle">
</div>

<div class="@ControlBlock.Element("input")" ripple>
<div class="@ControlInputClasses" ripple="@Ripple">
@GenSelection()
</div>

Expand Down
11 changes: 9 additions & 2 deletions src/Masa.Blazor/Components/Switch/MSwitch.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public partial class MSwitch<TValue> : MSelectable<TValue> where TValue : notnul
public string? TrackColor { get; set; }

public override bool HasColor => IsActive || HasText;

public string? ComputedTrackColor => HasText ? TrackColor ?? ValidationState : null;

// according to spec, should still show
Expand Down Expand Up @@ -70,7 +70,6 @@ protected override void OnInternalValueChange(TValue val)
private ModifierBuilder _modifierBuilder = _block.CreateModifierBuilder();
private static ModifierBuilder _trackModifierBuilder = _block.Element("track").CreateModifierBuilder();
private static ModifierBuilder _thumbModifierBuilder = _block.Element("thumb").CreateModifierBuilder();


protected override IEnumerable<string> BuildComponentClass()
{
Expand All @@ -84,5 +83,13 @@ protected override IEnumerable<string> BuildComponentClass()
}
);
}

protected override async Task HandleOnKeyDown(KeyboardEventArgs args)
{
if ((args.Key == "ArrowLeft" && IsActive) || (args.Key == "ArrowRight" && !IsActive))
{
await HandleOnChange();
}
}
}
}
2 changes: 2 additions & 0 deletions src/Masa.Blazor/JSInterop/JsInteropConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,6 @@ public static class JsInteropConstants
/// Arguments: element, threshold
/// </summary>
public static string IsScrollNearBottom => $"{JsInteropFuncNamePrefix}isScrollNearBottom";

public static string MatchesSelector => $"{JsInteropFuncNamePrefix}matchesSelector";
}
7 changes: 3 additions & 4 deletions src/Masa.Blazor/Mixins/Selectable/MSelectable.razor
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@

@code {

private string? RippleState => !IsDisabled && !string.IsNullOrWhiteSpace(ValidationState) ? ValidationState : null;

protected override RenderFragment GenDefaultSlot() => __builder =>
{
<div class="@ControlBlock.Element("input")" ripple>
<div class="@ControlInputClasses" ripple="@Ripple">
@GenSelection()
</div>
@GenLabel(false, true)
Expand All @@ -31,7 +29,8 @@
@onchange="@HandleOnChange"
@onfocus="@HandleOnFocus"
@onkeydown="@HandleOnKeyDown"
@attributes="@Attributes"/>
@attributes="@Attributes"
@ref="@InputElement"/>
};

}
31 changes: 19 additions & 12 deletions src/Masa.Blazor/Mixins/Selectable/MSelectable.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ public partial class MSelectable<TValue> : MInput<TValue> where TValue : notnull

[Parameter] public TValue FalseValue { get; set; } = default!;

private bool _focusVisible;

public override bool HasColor => IsActive;

public override string? ComputedColor => Color ?? (IsDark && !AppIsDark ? "white" : "primary");
public override string? ComputedColor => Color;

private bool IsCustomValue => IsDirtyParameter(nameof(TrueValue)) && IsDirtyParameter(nameof(FalseValue));

Expand Down Expand Up @@ -80,38 +82,43 @@ public async Task HandleOnChange()
public async Task HandleOnBlur(FocusEventArgs args)
{
IsFocused = false;
_focusVisible = false;

await Task.CompletedTask;
}

public async Task HandleOnFocus(FocusEventArgs args)
{
IsFocused = true;

await Task.CompletedTask;
_focusVisible = await Js.InvokeAsync<bool>(JsInteropConstants.MatchesSelector, InputElement, ":focus-visible");
}

public Task HandleOnKeyDown(KeyboardEventArgs args)
protected virtual Task HandleOnKeyDown(KeyboardEventArgs args)
{
return Task.CompletedTask;
}

#if NET8_0_OR_GREATER
protected override void OnParametersSet()
{
base.OnParametersSet();
protected override void OnParametersSet()
{
base.OnParametersSet();

if (MasaBlazor.IsSsr && !IndependentTheme)
{
CascadingIsDark = MasaBlazor.Theme.Dark;
}
if (MasaBlazor.IsSsr && !IndependentTheme)
{
CascadingIsDark = MasaBlazor.Theme.Dark;
}
}
#endif

protected static Block ControlBlock => new("m-input--selection-controls");
protected static BemIt.Element ControlWrapper => ControlBlock.Element("wrapper");

private ModifierBuilder _controlInputModifierBuilder = ControlBlock.Element("input").CreateModifierBuilder();

protected string ControlInputClasses => _controlInputModifierBuilder.Add(_focusVisible).Build();

protected override IEnumerable<string> BuildComponentClass()
{
return base.BuildComponentClass().Concat(new[] { ControlBlock.Name });
return base.BuildComponentClass().Concat([ControlBlock.Name]);
}
}
10 changes: 7 additions & 3 deletions src/Masa.Blazor/wwwroot/css/masa-blazor.extend.css
Original file line number Diff line number Diff line change
Expand Up @@ -1582,9 +1582,9 @@ html.m-overlay-scroll-blocked {
cursor: pointer;
}

/* switch */
/* switch/checkbox */

.m-input--is-focused .m-input--selection-controls__input::before {
.m-input--is-focused .m-input--selection-controls__input--focus-visible::before {
opacity: 0.12;
}

Expand Down Expand Up @@ -1708,8 +1708,12 @@ html.m-overlay-scroll-blocked {
margin-inline-end: 2px;
}

/* slider */
.m-select-list .m-list-item__action > .m-simple-checkbox .m-input--selection-controls__input {
height: auto;
width: auto;
}

/* slider */
.m-slider__track-background {
opacity: 0.38;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Masa.Blazor/wwwroot/js/masa-blazor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Masa.Blazor/wwwroot/js/masa-blazor.js.map

Large diffs are not rendered by default.

Loading