Skip to main content

TagInputState

Struct TagInputState 

Source
pub struct TagInputState<T: TagLike> {
Show 37 fields pub search_query: Signal<String>, pub selected_tags: Signal<Vec<T>>, pub available_tags: Signal<Vec<T>>, pub active_pill: Signal<Option<usize>>, pub popover_pill: Signal<Option<usize>>, pub on_create: Signal<Option<Callback<String, Option<T>>>>, pub on_remove: Signal<Option<Callback<T>>>, pub on_add: Signal<Option<Callback<T>>>, pub on_query_change: Signal<Option<EventHandler<String>>>, pub on_commit: Signal<Option<EventHandler<String>>>, pub is_disabled: Signal<bool>, pub status_message: Signal<String>, pub on_paste: Signal<Option<Callback<String, Vec<T>>>>, pub paste_delimiters: Signal<Option<Vec<char>>>, pub editing_pill: Signal<Option<usize>>, pub on_edit: Signal<Option<Callback<(T, String), Option<T>>>>, pub on_reorder: Signal<Option<Callback<(usize, usize)>>>, pub delimiters: Signal<Option<Vec<char>>>, pub max_tags: Signal<Option<usize>>, pub is_at_limit: Memo<bool>, pub validate: Signal<Option<Callback<T, Result<(), String>>>>, pub validation_error: Signal<Option<String>>, pub allow_duplicates: Signal<bool>, pub on_duplicate: Signal<Option<Callback<T>>>, pub enforce_allow_list: Signal<bool>, pub deny_list: Signal<Option<Vec<String>>>, pub min_tags: Signal<Option<usize>>, pub is_below_minimum: Memo<bool>, pub is_readonly: Signal<bool>, pub max_tag_length: Signal<Option<usize>>, pub filter: Signal<Option<fn(&T, &str) -> bool>>, pub max_visible_tags: Signal<Option<usize>>, pub overflow_count: Memo<usize>, pub visible_tags: Memo<Vec<T>>, pub sort_selected: Signal<Option<fn(&T, &T) -> Ordering>>, pub form_value: Memo<String>, pub select_mode: Signal<bool>, /* private fields */
}
Expand description

Headless state for the tag input component.

All fields are Signal or Memo, which are Copy in Dioxus 0.7, so TagInputState manually implements Clone, Copy, and PartialEq without requiring T: Copy or T: PartialEq.

Fields§

§search_query: Signal<String>

The current search/filter query text.

§selected_tags: Signal<Vec<T>>

The tags currently selected by the user.

§available_tags: Signal<Vec<T>>

All tags available for selection.

§active_pill: Signal<Option<usize>>

Index of the keyboard-selected pill, or None when the cursor is in the text input.

§popover_pill: Signal<Option<usize>>

Index of the pill whose popover is open, or None when no popover is shown.

§on_create: Signal<Option<Callback<String, Option<T>>>>

Optional callback for creating new tags on Enter when no suggestion is highlighted.

When Some, pressing Enter with a non-empty query and no highlighted suggestion will call this callback with the query text. Return Some(tag) to accept the new tag, or None to reject it.

Default: None (feature off — Enter just opens the dropdown).

§on_remove: Signal<Option<Callback<T>>>

Optional callback fired when a tag is about to be removed.

Called with the tag being removed, before it is actually removed from selected_tags. Fires from remove_tag() and remove_last_tag().

Default: None

§on_add: Signal<Option<Callback<T>>>

Optional callback fired when a tag is added.

Called with the newly added tag after it has been pushed to selected_tags. Fires from add_tag() (and by extension create_tag()).

Default: None

§on_query_change: Signal<Option<EventHandler<String>>>

Optional callback fired when the input text (search query) changes.

Consumers can use this for external filtering, async fetching, or debounced search. Replaces the old on_search callback.

Default: None

§on_commit: Signal<Option<EventHandler<String>>>

Optional callback fired when the user presses Enter/delimiter with text and no on_create handler is set.

This allows consumers to handle the “commit” action externally (e.g., to open a dropdown, trigger a search, or perform a custom action).

Default: None

§is_disabled: Signal<bool>

Whether the tag input is disabled (no interaction allowed).

When true, handle_keydown, set_query, add_tag, remove_tag, and handle_click become no-ops. Consumers should also apply disabled / aria-disabled="true" attributes and visual styling based on this signal.

§status_message: Signal<String>

Screen-reader status message for aria-live announcements.

Updated automatically when tags are added/removed and when the suggestion count changes. Consumers render this inside a <div role="status" aria-live="polite"> element to provide announcements to assistive technology.

Example messages:

  • "Apple added. 3 tags selected."
  • "Cherry removed. 2 tags selected."
  • "5 suggestions available."
  • "No suggestions found."
  • "Maximum of 5 tags reached."
§on_paste: Signal<Option<Callback<String, Vec<T>>>>

Optional callback fired when text is pasted into the input.

Called with the raw clipboard text. Return a Vec<T> of tags to add. If the callback returns an empty vec, no tags are added.

Takes priority over paste_delimiters when set.

Default: None

§paste_delimiters: Signal<Option<Vec<char>>>

Delimiter characters for splitting pasted text into tags.

When set and on_paste is None, pasted text is split by these delimiters. Each non-empty token is passed to on_create (if set) to create a tag. Common delimiters: [',', '\n', '\t'].

Default: None (paste behaves normally — text enters the input field)

§editing_pill: Signal<Option<usize>>

Index of the pill currently being edited inline, or None.

When Some(idx), the consumer should render an <input> instead of a <span> for that pill. Use start_editing(idx) to enter edit mode, commit_edit(new_name) to apply changes, and cancel_edit() to discard.

§on_edit: Signal<Option<Callback<(T, String), Option<T>>>>

Optional callback for applying an inline edit to a tag.

Called with (current_tag, new_name_string). Return Some(updated_tag) to accept the edit, or None to reject it. The consumer is responsible for constructing the updated tag (the library doesn’t know your tag’s internals).

Default: None (editing disabled)

§on_reorder: Signal<Option<Callback<(usize, usize)>>>

Optional callback fired after a tag is reordered via move_tag.

Called with (from_index, to_index) after the move completes.

Default: None

§delimiters: Signal<Option<Vec<char>>>

Delimiter characters that commit the current query as a tag.

When set, typing any of these characters commits the current query: if a suggestion is highlighted, it’s selected; otherwise on_create is called (if set). Common delimiters: [',', ';', '\t']. Enter is always a commit key and doesn’t need to be in this list.

Default: None (only Enter commits)

§max_tags: Signal<Option<usize>>

Maximum number of tags that can be selected.

When set and the limit is reached, add_tag becomes a no-op and status_message announces “Maximum of N tags reached.”

Default: None (unlimited)

§is_at_limit: Memo<bool>

Whether the maximum tag limit has been reached.

Reactive memo derived from max_tags and selected_tags.len(). Consumers can use this to disable the input or hide suggestions.

§validate: Signal<Option<Callback<T, Result<(), String>>>>

Optional validation callback called before a tag is committed.

Called with the tag about to be added. Return Ok(()) to accept, or Err("message") to reject. The rejection message is stored in validation_error for the consumer to render.

Default: None (no validation — all tags accepted)

§validation_error: Signal<Option<String>>

The most recent validation error message, or None if valid.

Set by add_tag when validate returns Err(msg). Cleared on the next successful add_tag or when set_query is called.

§allow_duplicates: Signal<bool>

Whether duplicate tags are allowed.

When false (default), add_tag rejects tags whose ID already exists in selected_tags. When true, the duplicate check is skipped entirely.

Default: false

§on_duplicate: Signal<Option<Callback<T>>>

Optional callback fired when a duplicate tag is rejected.

Only fires when allow_duplicates is false and a duplicate is attempted.

Default: None

§enforce_allow_list: Signal<bool>

Whether to restrict tag selection to only items in available_tags.

When true, on_create is blocked and only tags present in available_tags can be added. Pasted tags not in the allow list are also rejected.

Default: false

§deny_list: Signal<Option<Vec<String>>>

List of forbidden tag names (case-insensitive).

Tags whose name() matches any entry (case-insensitive) are rejected by add_tag and filtered out of suggestions.

Default: None (no deny list)

§min_tags: Signal<Option<usize>>

Minimum number of required tags (informational for form validation).

Does NOT prevent removal — is_below_minimum is a reactive memo that consumers can use to show validation warnings or disable form submission.

Default: None (no minimum)

§is_below_minimum: Memo<bool>

Whether the selected tag count is below min_tags.

Reactive memo: true when min_tags is Some(n) and selected_tags.len() < n.

§is_readonly: Signal<bool>

Whether the tag input is in read-only mode.

When true, tags are displayed but cannot be added, removed, or edited. Pill navigation (ArrowLeft/Right) and Escape still work.

Default: false

§max_tag_length: Signal<Option<usize>>

Maximum character length for tag names.

When set, add_tag and create_tag reject tags whose name().len() exceeds this limit, setting validation_error.

Default: None (unlimited)

§filter: Signal<Option<fn(&T, &str) -> bool>>

Custom filter function for use_tag_input().

When Some, used instead of the default case-insensitive substring match. Receives (tag, lowercase_query). Provides parity with the grouped hook’s TagInputGroupConfig::filter.

Default: None

§max_visible_tags: Signal<Option<usize>>

Maximum number of tag pills to display before collapsing.

When set, consumers should render only visible_tags and show an “+N more” badge using overflow_count.

Default: None (show all)

§overflow_count: Memo<usize>

Count of tags hidden by max_visible_tags.

selected_tags.len() - max_visible_tags when limit is active, else 0.

§visible_tags: Memo<Vec<T>>

The truncated slice of selected tags for rendering.

When max_visible_tags is set, contains only the first N tags. Otherwise contains all selected tags.

§sort_selected: Signal<Option<fn(&T, &T) -> Ordering>>

Optional sort function applied to selected_tags after add/remove.

When Some, selected_tags is automatically sorted in place after each mutation.

Default: None (insertion order preserved)

§form_value: Memo<String>

JSON-serialized selected tag IDs for hidden form inputs.

Format: ["id1","id2","id3"]. Empty array [] when no tags selected.

§select_mode: Signal<bool>

Whether to operate in single-value select mode.

When true and max_tags is Some(1), adding a new tag replaces the existing one instead of rejecting.

Default: false

Implementations§

Source§

impl<T: TagLike> TagInputState<T>

Source

pub fn set_query(&mut self, query: String)

Update the search query.

Clears any validation_error from a previous rejected add_tag. Fires on_query_change callback (if set) so consumers can react to input changes.

Source

pub fn add_tag(&mut self, tag: T)

Add a tag to the selected list and clear the search query.

Guards: disabled, readonly, duplicate, allow list, deny list, max_tags limit, max_tag_length, validation callback, select_mode replacement. Fires on_add callback (if set) after the tag is added. Updates status_message with an announcement like “Apple added. 3 tags selected.”

Source

pub fn remove_tag(&mut self, id: &str)

Remove a tag from the selected list by its id.

No-op if the tag is locked (is_locked() == true), disabled, or readonly. Fires on_remove callback (if set) before removal. Updates status_message with an announcement like “Cherry removed. 2 tags selected.”

Source

pub fn remove_last_tag(&mut self)

Remove the last unlocked selected tag (used for Backspace on empty input).

Walks backwards from the end, skipping locked tags. If all tags are locked, no-op. Fires on_remove callback (if set) before removal. Updates status_message with an announcement.

Source

pub fn handle_click(&mut self)

Handle click/tap on the input area — clears pill selection.

Attach this to onclick on the text <input> to clear pill mode when the user taps back into the text input.

Source

pub fn toggle_popover(&mut self, index: usize)

Toggle the popover for the pill at index.

If the popover is already showing for this pill, it closes.

Source

pub fn close_popover(&mut self)

Close any open pill popover.

Source

pub fn suggestion_id(&self, index: usize) -> String

Return a stable DOM id for the suggestion at index.

Use this as the id attribute on each suggestion element so that keyboard navigation can scroll the highlighted item into view. The ID is scoped by instance_id so multiple tag inputs on the same page won’t collide.

Source

pub fn listbox_id(&self) -> String

Returns the DOM ID for the suggestion listbox container.

Use this as the id on the <ul> / <div role="listbox"> element and as the value of aria-controls / aria-owns on the combobox <input>.

Source

pub fn pill_id(&self, index: usize) -> String

Returns a stable DOM id for the selected pill at index.

Use this as the id attribute on each pill element for focus management and ARIA relationships. The ID is scoped by instance_id so multiple tag inputs on the same page won’t collide.

Source

pub fn create_tag(&mut self, tag: T)

Create a tag and add it to both selected and available tags.

The tag is appended to available_tags so it appears in future suggestions if the user removes and re-types it. Then it is added to selected_tags via add_tag.

Used internally by handle_keydown; also available for consumers who want to trigger creation programmatically.

Source

pub fn handle_paste(&mut self, text: String)

Handle pasted text by splitting it into tags.

Call this from the consumer’s onpaste handler after extracting the clipboard text. The method processes the text according to these rules (in priority order):

  1. If on_paste callback is set: calls it with the raw text. The callback returns Vec<T> of tags to add.
  2. If paste_delimiters is set: splits by delimiters, trims whitespace, and passes each non-empty token to on_create (if set) to create tags.
  3. Otherwise: no-op (normal paste into the input).

Updates status_message with a summary of how many tags were added.

Source

pub fn announce(&mut self, message: String)

Update the status message with a custom announcement.

Consumers can call this to announce arbitrary messages to screen readers via the status_message signal (rendered in an aria-live region).

Source

pub fn start_editing(&mut self, index: usize)

Enter inline editing mode for the pill at index.

Sets editing_pill to Some(index) and closes popover/dropdown. The consumer should render an <input> for this pill and call commit_edit or cancel_edit when done.

No-op if on_edit callback is not set or if is_disabled.

Source

pub fn commit_edit(&mut self, new_name: String)

Commit an inline edit, replacing the tag at the editing index.

Calls on_edit with (current_tag, new_name). If the callback returns Some(updated_tag), the tag is replaced in selected_tags. If it returns None, the edit is rejected and the original tag remains.

Always exits edit mode afterward.

Source

pub fn cancel_edit(&mut self)

Cancel inline editing without applying changes.

Source

pub fn move_tag(&mut self, from: usize, to: usize)

Move a tag from one position to another in the selected list.

Performs Vec::remove(from) then Vec::insert(to, tag). Fires on_reorder callback (if set) with (from, to) after the move. Updates status_message.

Source

pub fn clear_all(&mut self)

Remove all unlocked tags from the selection.

Locked tags are preserved. Fires on_remove for each removed tag. Updates status_message with a summary.

Source

pub fn select_all(&mut self)

Add all available (unselected) tags to the selection.

Respects max_tags limit — stops adding when the limit is reached. Updates status_message with the count added.

Source

pub fn handle_keydown(&mut self, event: Event<KeyboardData>)

Handle keyboard events for navigating suggestions and pills.

Source

pub fn handle_pill_keydown( &mut self, event: Event<KeyboardData>, pill_index: usize, )

Handle keyboard events when a pill is keyboard-selected.

Called by handle_keydown when active_pill is Some(i), or directly by compound components that manage their own pill keydown.

Source

pub fn handle_input_keydown(&mut self, event: Event<KeyboardData>)

Handle keyboard events for the text input.

Called by handle_keydown when no pill is active, or directly by compound components that manage their own input keydown.

Trait Implementations§

Source§

impl<T: TagLike> Clone for TagInputState<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: TagLike> PartialEq for TagInputState<T>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: TagLike> Copy for TagInputState<T>

Auto Trait Implementations§

§

impl<T> Freeze for TagInputState<T>

§

impl<T> !RefUnwindSafe for TagInputState<T>

§

impl<T> !Send for TagInputState<T>

§

impl<T> !Sync for TagInputState<T>

§

impl<T> Unpin for TagInputState<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for TagInputState<T>

§

impl<T> !UnwindSafe for TagInputState<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> InitializeFromFunction<T> for T

Source§

fn initialize_from_function(f: fn() -> T) -> T

Create an instance of this type from an initialization function
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<Ret> SpawnIfAsync<(), Ret> for Ret

Source§

fn spawn(self) -> Ret

Spawn the value into the dioxus runtime if it is an async block
Source§

impl<T, O> SuperFrom<T> for O
where O: From<T>,

Source§

fn super_from(input: T) -> O

Convert from a type to another type.
Source§

impl<T, O, M> SuperInto<O, M> for T
where O: SuperFrom<T, M>,

Source§

fn super_into(self) -> O

Convert from a type to another type.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DependencyElement for T
where T: 'static + PartialEq + Clone,