# Known Limitations
This document lists known limitations and known-working areas of taga11y. Some are design trade-offs; others are candidates for future improvements.

## No Framework Bindings
taga11y is a vanilla JavaScript library with no official React, Vue, Svelte, or Angular bindings. Framework integration requires manual DOM management (creating the input element, passing a ref to the constructor, cleaning up on unmount).

## No Server-Side Rendering
taga11y is a client-side widget only. It requires a DOM environment and cannot be rendered on the server. The constructor will throw if called before the DOM is available.

## Single Input Per Instance
Each taga11y instance manages exactly one input element. There is no built-in support for managing multiple inputs with a single instance or for a "master" widget that controls sub-widgets.

## Suggestion Limit
The dropdown displays a maximum of **10 suggestions** at a time, regardless of how many matches exist. This limit is applied after filtering and excluding selected tags. Users cannot page or scroll beyond the first 10 results.

## No Tag Reordering
Chips cannot be reordered via drag-and-drop or keyboard. Tags are displayed in the order they were added.

## No HTML Content in Tags
Tag labels are rendered as plain text. HTML characters in labels are escaped. Rich text, icons, or inline elements in tags are not supported.

## Dropdown Positioning
The listbox is positioned absolutely below the input within the wrapper. If the wrapper is near the bottom of the viewport, the dropdown may be clipped. There is no automatic upward repositioning.

## IIFE Bundle Size
The IIFE bundle includes the full library (no tree-shaking). For browser usage, prefer the ESM or CJS bundles where tree-shaking can reduce size. The IIFE format is provided for simple script-tag inclusion and is the least-targeted format.

## Tab Key Behavior
The Tab key is never prevented, which means focus always moves out of the component. If Tab is configured as a delimiter, the pending text is committed before focus moves. This is intentional to avoid focus trapping, but it means users cannot use Tab to navigate away without potentially committing text.

## No Built-in Validation
taga11y enforces `maxTags` and `enforceSuggestions` internally but does not provide form-level validation hooks. Validation must be implemented by the consuming application using the available events and API methods.

## Limited Browser Support for Older Browsers
taga11y uses modern JavaScript features (ES modules, `AbortController`, `ResizeObserver`, `IntersectionObserver`) and the CSS `:dir()` pseudo-class plus `Intl.PluralRules` for internationalisation. Support targets modern evergreen browsers (Chrome 120+, Firefox 120+, Safari 17+, Edge 120+). Older browsers will require polyfills or will receive LTR-only layout.

## IME Composition (CJK IMEs)
Suggestion filtering runs on every `input` event, including those fired while an IME composition is in progress. For Japanese, Korean, and Chinese IME users typing multi-stroke characters, this means the dropdown filters against the intermediate (un-finalised) composition string rather than waiting for `compositionend`.

This is an intentional trade-off, made because Android Gboard with autocorrect / prediction (the default for most Android users) wraps Latin-script typing in a continuous composition session — gating filtering on `compositionend` would prevent the dropdown from updating until a word boundary, which broke the widget on the dominant mobile keyboard. The current behaviour matches `<datalist>` and shipped combobox libraries (downshift, react-select, headless-ui, etc.).

## Delimiter Detection on Soft Keyboards
Single-character delimiter detection runs through two independent paths:

1. **Keydown path** — when a `keydown` event fires with `e.key` equal to a configured delimiter character, the delimiter is committed and the character is prevented from landing in the input value. This is the desktop / hardware-keyboard fast path. It also covers Android Gboard, which surfaces real `keydown` events for punctuation even when letters go through composition.
2. **Input-event path** — when an `input` event fires and the input value contains any single-character delimiter, the value is split and committed. This covers FUTO and other soft keyboards that do not surface a usable `keydown.key` for delimiter taps.

Control delimiters (`'Enter'`, `'Tab'`) cannot be detected via the input-event path because they do not appear as characters in `input.value`; they remain keydown-only. Keyboards that do not surface a usable `keydown` event for `Enter` or `Tab` cannot trigger those delimiter commits; users on such keyboards can still commit via single-character delimiters or by blurring the input.

## Android Gboard: Backspace on Empty Input Does Not Remove Chips
On a physical keyboard (or on FUTO), pressing Backspace when the input is empty removes the last chip — a standard chip-input affordance. On Android Gboard this gesture does not work: when the input is empty, Gboard dispatches no keystroke event at all (no `keydown`, no `beforeinput`, no `input`) because there is nothing in the field for it to delete. There is no event for the JS layer to hook, so the gesture cannot be implemented.

Gboard users should use the chip's ✕ remove button instead. The remove buttons are individually focusable and announce their tag label for screen readers, so the chip-removal flow remains fully accessible — it just requires a tap rather than a Backspace.
