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
InputRoot
Reference to the TwInputRoot component instance, used to access the root DOM element for JS interop.
protected TwInputRoot? InputRoot
Field Value
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
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
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
Properties
JSRuntime
Gets or sets the JavaScript runtime instance used for interop operations.
[Inject]
public IJSRuntime JSRuntime { get; set; }
Property Value
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
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
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
Methods
Close()
Closes the picker's popover panel and cleans up JavaScript event handlers.
[JSInvokable("Close")]
public override Task Close()
Returns
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
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
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
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
Returns
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
Returns
RegisterOutsideClickAsync()
Registers a JavaScript event handler to detect clicks outside the picker component.
protected Task RegisterOutsideClickAsync()
Returns
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
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
UnregisterOutsideClickAsync()
Unregisters the JavaScript outside click handler and disposes of the .NET object reference.
protected Task UnregisterOutsideClickAsync()
Returns
Remarks
This method should be called when the picker is closed to prevent memory leaks and remove event listeners.