AppTagInput
Free-text token entry field — type and press Enter/comma to add tags.
<app-tag-input label="Tags" name="keywords">…</app-tag-input>A tag input lets a user enter free-text tokens (emails, tags, keywords) without picking from a predefined list. Type text and press Enter or comma to add a tag; press Backspace with an empty input to remove the last tag. Paste comma or newline-separated values to add multiple tags at once.
Its look and behaviour come from the shared @webority/theme and the underlying <wui-taginput> element, so the Razor <app-tag-input> and the React <AppTagInput> render identically on every Webority surface.
Playground
Every attribute, live. Each change re-renders the real tag helper on the server, so the markup underneath is the exact call that produced the field above it. Type and press Enter/comma to add a tag.
Basic tag entry
Type text and press Enter or comma to add a tag. Each tag shows as a removable chip inside the field.
<wui-tag> children; press Backspace with an empty input to remove the last tag.Show code
<app-tag-input label="Keywords" name="keywords" placeholder="Add keyword…">
<wui-tag>react</wui-tag>
<wui-tag>javascript</wui-tag>
</app-tag-input>
Paste to add many
Paste comma or newline-separated values to add multiple tags at once. Duplicates are rejected case-insensitively by default.
alice@ex.com, bob@ex.com, charlie@ex.com to add all three at once.Show code
<app-tag-input label="Recipients" name="emails" placeholder="Paste or type email addresses">
<wui-tag>alice@example.com</wui-tag>
</app-tag-input>
Sizes
size takes sm or lg (md is the default), matching AppInput and AppSelect.
Show code
<app-tag-input label="Small" name="tags" size="sm">…</app-tag-input> <app-tag-input label="Medium (default)" name="tags">…</app-tag-input> <app-tag-input label="Large" name="tags" size="lg">…</app-tag-input>
Max tags & duplicates
max-tags caps the count — once reached, new tags can't be added. allow-duplicates opts out of the default case-insensitive dedupe.
Show code
<app-tag-input label="Max 3 tags" name="tags" max-tags="3">
<wui-tag>one</wui-tag>
<wui-tag>two</wui-tag>
</app-tag-input>
Show code
<app-tag-input label="Duplicates rejected (default)" name="tags">…</app-tag-input> <app-tag-input label="allow-duplicates" name="tags" allow-duplicates="true">…</app-tag-input>
States
Surface a validation message with error, mark a mandatory field with required, and disable a read-only selection.
Show code
<app-tag-input label="Tags with hint" name="tags" hint="Enter tags related to this item" /> <app-tag-input label="Tags with error" name="tags" error="At least one tag is required" />
Show code
<app-tag-input label="Disabled" name="tags" disabled="true">…</app-tag-input>
Show code
<app-tag-input label="Required field" name="required-tags" required="true"
error="This field is required" />
hint or error shows at a time — set error once validation fails and clear it once the field is fixed.When to use
Use it when
- Tag entry fields (blog keywords, issue labels).
- Email / recipient lists the user may paste or type.
- Keyword input for search filters or product attributes.
- Free-text values with no fixed list to pick from.
Reach for something else when
- Picking from a predefined list. → AppSelect or AppMultiSelect
- A single value. → AppInput
- You only need to display tokens, not enter them. → AppChip
Best practices
Every option
The whole surface of the component, one cell per value — sizes, limits, and every field state.
size
(default)size="sm"size="lg"max-tags
(no limit)max-tags="3" — under the limitmax-tags="3" — at the limit (add is rejected)allow-duplicates
(default) — dedupes case-insensitivelyallow-duplicates="true" — case-sensitive duplicates allowedstate
(default)emptydisabled="true"hinterrorrequired="true" (asterisk on label)required + errorhelp — info-tip beside the labellong tag value (wraps inside the chip)Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| label | string | — | Field label above the control. |
| name | string | — | Field name — posts the comma-joined tags; also the element id the label points at. |
| value | string | — | Comma-joined tag seed (React values). With asp-for the bound model value is used instead, so a validation redisplay repopulates the tags. |
| placeholder | string | Add… | Placeholder shown when the input is empty. |
| size | sm | lg | — | Control size. Omit for the default (md). |
| max-tags | number | — | Maximum number of tags allowed; no limit if absent. |
| allow-duplicates | bool | false | Allow case-sensitive duplicate values; default deduplicates case-insensitively. |
| disabled | bool | false | Disables the field. |
| required | bool | false | Renders the required asterisk on the label. |
| error | string | — | Validation message; replaces the hint and marks the field invalid. |
| hint | string | — | Helper text below the field when there is no error. |
| help | string | — | Info-tip content shown beside the label. |
| help-label | string | More information | aria-label for the info-tip button (React helpLabel). |
| asp-for | ModelExpression | — | React-only equivalent is n/a — binds name, id, value, label and required from model metadata (React reaches the same outcome via explicit props). |
| <wui-tag> | text | — | Child tags — inner content is the tag value; each <wui-tag> becomes one initial tag. React reaches the same outcome via the values array. |
| class | string | — | Extra classes merged onto the .field wrapper (React fieldClassName). |
| input-class | string | — | Extra classes on the control itself (the wui-taginput) — the React className counterpart. The plain class attribute merges onto the .field wrapper instead. |
Keyboard & behavior
- Enter or , (comma) commits the current input as a tag and clears the field.
- Backspace with an empty input removes the last tag.
- Escape clears the draft text without committing.
- Paste with separators (newlines, commas) splits the pasted text and adds multiple tags.
- Duplicates are rejected by default (case-insensitive); enable allow-duplicates to allow them.
- Non-empty input is trimmed before being added as a tag.