Table of Contents

Class TwPopoverPickerComponentBase

Namespace
TwBlazor
Assembly
TwBlazor.dll

Shared focus-management and JS-interop plumbing for text-editable "combobox" pickers that open a popover panel on focus (TwDatePicker, TwTimePicker): a Tab focus trap and background inert-ing while the panel is open, an outside-click handler that closes it, and restoring focus to the trigger once it does. Each derived picker still owns its own value parsing/formatting and OnAfterRenderAsync override (their native-vs-custom picker detection differs slightly in what happens afterward), but the open/close mechanics themselves are identical, so they live here once instead of being copy-pasted per picker.

public abstract class TwPopoverPickerComponentBase : TwBlazorTextInputComponentBase, IComponent, IHandleEvent, IHandleAfterRender, ITwComponent, ITwInputComponent, IAsyncDisposable
Inheritance
TwPopoverPickerComponentBase
Implements
Derived
Inherited Members

Constructors

TwPopoverPickerComponentBase()

protected TwPopoverPickerComponentBase()

Fields

FocusReturnToken

Opaque token (captured via JS interop from the element focused just before the panel opened, almost always the trigger textfield) used to restore focus there once the panel closes.

protected string? FocusReturnToken

Field Value

string

InputRoot

Reference to the TwInputRoot component instance, used to access the root DOM element for JS interop.

protected TwInputRoot? InputRoot

Field Value

TwInputRoot

PanelRef

Reference to the popover panel element, used to move focus into it and to trap Tab navigation while it's open.

protected ElementReference PanelRef

Field Value

ElementReference

PendingOpenFocus

Set when the panel opens so the next OnAfterRenderAsync arms the Tab focus trap and background inert-ing. Deliberately does not move focus into the panel - the trigger is a text-editable combobox (typing a value directly is a first-class input method here, not just a fallback), so focus has to stay on the input for that to work. Users move into the panel explicitly, same as any combobox-with-popup: Tab, a click, or an arrow key.

protected bool PendingOpenFocus

Field Value

bool

UseNativePicker

Indicates whether the browser's native picker UI is being used instead of the custom popover, either because PreferNativePicker was explicitly set or because the client platform (iOS/Android) was detected via JS interop.

protected bool UseNativePicker

Field Value

bool

Properties

JSRuntime

Gets or sets the JavaScript runtime instance used for interop operations.

[Inject]
public IJSRuntime JSRuntime { get; set; }

Property Value

IJSRuntime

PreferNativePicker

Overrides automatic device detection for whether the browser's native picker should be used instead of the custom popover. Leave unset (null) to auto-detect based on the client platform (iOS and Android use the native picker by default).

[Parameter]
public bool? PreferNativePicker { get; set; }

Property Value

bool?

isFocused

Determines whether the popover panel is currently shown.

protected bool isFocused { get; set; }

Property Value

bool

triggerAttributes

Extra ARIA attributes forwarded onto the trigger textfield's rendered <input> so assistive technology knows it opens a popover dialog and whether that dialog is currently open. Omitted when the native browser picker is in use, since no custom dialog will appear.

protected Dictionary<string, object> triggerAttributes { get; }

Property Value

Dictionary<string, object>

triggerInputRef

Reference to the trigger textfield's actual <input> element, supplied by derived pickers (TwDatePicker, TwTimePicker) that render a TwTextfield<T> trigger. Used by OnIconClickAsync() to focus that element directly.

protected virtual ElementReference? triggerInputRef { get; }

Property Value

ElementReference?

Methods

Close()

Closes the picker's popover panel and cleans up JavaScript event handlers.

[JSInvokable("Close")]
public override Task Close()

Returns

Task

Remarks

This method is invoked from JavaScript when a click outside the picker is detected. It sets isFocused to false, unregisters the outside click handler, and triggers a UI refresh.

DisposeAsync()

Disposes of the component's resources asynchronously.

public ValueTask DisposeAsync()

Returns

ValueTask

Remarks

This method ensures that JavaScript event handlers are unregistered and the .NET object reference is disposed, even if the component is removed from the DOM without Close() being called. This prevents memory leaks and orphaned event listeners.

OnFocusAsync()

Handles the focus event of the trigger input, opening the popover panel.

protected virtual Task OnFocusAsync()

Returns

Task

Remarks

Sets isFocused to true and registers an outside click handler to detect clicks outside the component. If the component is readonly, disabled, or the native picker is in use, the custom popover panel will not be shown.

OnIconClickAsync()

Handles a click on the trigger's decorative icon by moving focus into the trigger textfield, which opens the picker via the normal OnFocusAsync() focus handler (triggered by the native "focus" event this causes).

protected Task OnIconClickAsync()

Returns

Task

Remarks

Focuses triggerInputRef directly when a derived picker supplies one, rather than falling back to twDialog.focusSurface over the whole InputRoot: the icon itself is rendered ahead of the trigger input in DOM order and (being a role="button" element with tabindex="0") is itself focusable, so scanning the root for the first focusable descendant would find - and refocus - the icon that was just clicked instead of the input, silently no-oping the click instead of opening the panel.

OnIconKeyDownAsync(KeyboardEventArgs)

Handles keydown events on the trigger icon so it's operable from the keyboard (Enter/Space forward focus to the trigger, same as a click), since it's a <div> rather than a native button.

protected Task OnIconKeyDownAsync(KeyboardEventArgs e)

Parameters

e KeyboardEventArgs

Returns

Task

OnPanelKeyDownAsync(KeyboardEventArgs)

Handles keydown events on the popover panel, closing it (and restoring focus to the trigger) when Escape is pressed.

protected Task OnPanelKeyDownAsync(KeyboardEventArgs e)

Parameters

e KeyboardEventArgs

Returns

Task

RegisterOutsideClickAsync()

Registers a JavaScript event handler to detect clicks outside the picker component.

protected Task RegisterOutsideClickAsync()

Returns

Task

Remarks

This method is called when the picker is focused. It ensures the handler is only registered once by checking the TwBlazor.TwPopoverPickerComponentBase.registeredOutsideHandler flag.

ReleasePanelTrapAsync()

Releases the Tab focus trap and clears background inert-ing. Must be called (and awaited) while the panel is still mounted - i.e. before isFocused is set to false - since it needs PanelRef to still resolve to a live DOM node.

protected Task ReleasePanelTrapAsync()

Returns

Task

RestoreFocusAsync()

Restores focus to whatever element was focused (captured via FocusReturnToken) right before the panel opened, typically this component's own trigger textfield. No-ops if no token was captured (e.g. the panel is being closed a second time).

protected Task RestoreFocusAsync()

Returns

Task

UnregisterOutsideClickAsync()

Unregisters the JavaScript outside click handler and disposes of the .NET object reference.

protected Task UnregisterOutsideClickAsync()

Returns

Task

Remarks

This method should be called when the picker is closed to prevent memory leaks and remove event listeners.