NewPower Apps · canvas componentInputs and forms✓ Tested in StudioMIT License
Tag picker
Chips for the tags chosen so far, each with a remove button; a box that suggests matching options as you type; a limit on how many; new tags from what's typed if you allow it; SelectedKeys and SelectedTags for your Patch, OnChange, Add, Remove and Clear; light and dark, with motion.
- Name in Studio
- lcsTagPicker
- Version
- 0.1.0
- Properties
- 10 inputs · 4 outputs · 1 event · 3 actions
Variations
As it is when you paste it, with every input at its default.
SelectedKeys: "apps,dataverse" · Count: 2 · SearchText: ""
Formulas on this screen
Set the same ones in Studio to try it the same way; there, each Notify shows its event in a banner, which this preview leaves out so nothing covers the component. The instance names are the ones Studio gives the first copy on a screen.
lcsTagPicker_1.OnChange = Notify("Tags: """ & SelectedKeys & """ (" & Count & ")")
btnSave.OnSelect = Patch(Profiles, varProfile, {Skills: lcsTagPicker_1.SelectedKeys})
A web replica that behaves as the component does in Power Apps. In Studio it uses Microsoft's controls, which can look slightly different.
Add it in five steps
- In Power Apps Studio, open Settings > Updates and check that Modern controls and themes and Enhanced component properties are on.
- Open the Components tab in the tree view and select New component.
- Select an empty part of Studio, so the new component isn't selected.
- Copy the YAML on this page and press Ctrl+V.
lcsTagPickerappears with all its properties. - On a screen, insert it from Insert > Custom >
lcsTagPicker.
What it needs
- No premium licence: standard controls, no connectors
- Modern controls and themes: on
- Enhanced component properties: on
- Tested in Power Apps Studio 3.26094.9 on November 2, 2026
- Version 0.1.0
Properties (18)
Read from the component's own YAML, so they always match what you paste.
| Property | Kind | Type | Default |
|---|---|---|---|
OptionsThe tags people can choose from, as a table with Key and Label columns. Key is what you store; Label is what they see and search. | Input | Table | Table({Key: "apps", Label: "Power Apps"}, {Key: "automate", Label: "Power Automate"}, {Key: "dataverse", Label: "Dataverse"}, {Key: "bi", Label: "Power BI"}, {Key: "copilot", Label: "Copilot Studio"}, {Key: "azure", Label: "Azure"}, {Key: "sharepoint", Label: "SharePoint"}, {Key: "teams", Label: "Teams"}) |
DefaultKeysThe tags chosen when the screen loads, by Key, separated by commas. | Input | Text | "apps,dataverse" |
PlaceholderThe hint in the box, such as Add a skill. | Input | Text | "Add a tag" |
MaxTagsHow many tags can be chosen. 0 is no limit. At the limit the box says so and suggests nothing. | Input | Number | 0 |
AllowNewOffers to add what's typed as a new tag when no option matches it exactly. Its Key is the text itself. | Input | Boolean | false |
MaxSuggestionsHow many matching options show under the box. | Input | Number | 6 |
ChipWidthThe width of each chip, remove button included. A label that doesn't fit is cut; the full label stays in the tooltip and the button's name. | Input | Number | 132 |
AccentColorYour brand colour, for the chips, the box's focus and the suggestions' focus ring. | Input | Color | RGBA(15, 108, 189, 1) |
ThemeLight, or Dark for a dark screen. | Input | Text | "Light" |
MotionA chip pops in when its tag is added. None plays for people who've asked their device for reduced motion. | Input | Boolean | true |
| Property | Kind | Type | Default |
|---|---|---|---|
SelectedKeysThe chosen tags' keys, separated by commas; empty when none. | Output | Text | — |
SelectedTagsThe chosen tags, as a table of Key and Label, in the order they were added. A new tag's Label is its Key. | Output | Table | — |
CountHow many tags are chosen. | Output | Number | — |
SearchTextWhat's typed in the box, trimmed, for loading options from the server. | Output | Text | — |
| Property | Kind | Type | Default |
|---|---|---|---|
OnChange(SelectedKeys, Count)Runs in your app when a tag is added or removed, with the keys and the count.
| Event | — | false |
| Property | Kind | Type | Default |
|---|---|---|---|
Add(Key)Adds a tag by Key from your app, if it isn't chosen and the limit allows.
| Action | — | — |
Remove(Key)Removes a tag by Key from your app.
| Action | — | — |
Clear()Removes every tag and empties the box. | Action | — | — |
Guide
Use lcsTagPicker for skills on a profile, categories on a request, labels on a task: a few values from a longer list, shown as chips. The combo box does multi-select, but it keeps the choices inside a dropdown, can't add a value that isn't in the list, and shows nothing of what's chosen until you open it. This component puts the choices in front of people:
- Chips for the tags chosen so far, in your accent colour, each with a remove button named "Remove Power Apps";
- Suggestions as you type, from
Options, with the ones already chosen left out and a limit on how many show; - New tags from what's typed, when
AllowNewis on and nothing matches exactly; MaxTags: at the limit the box says so and stops suggesting;SelectedKeys(a comma list for a text column) andSelectedTags(a table for a choices column or a related table),OnChange, andAdd,RemoveandClearfrom your app.
The examples call it tpSkills on a profile form.
Options from a Dataverse table, the chosen keys saved to a text column:
// tpSkills.Options
ShowColumns(RenameColumns(Skills, "Skill", "Key", "Name", "Label"), "Key", "Label")
// tpSkills.DefaultKeys
varProfile.Skills
// btnSave.OnSelect
Patch(Profiles, varProfile, {Skills: tpSkills.SelectedKeys})
Save to a many-to-many relationship instead:
// btnSave.OnSelect
ForAll(tpSkills.SelectedTags As tag, Relate(varProfile.'Profile Skills', LookUp(Skills, Skill = tag.Key)))
Let people add a skill that isn't in the list yet:
// tpSkills.AllowNew
true
// tpSkills.OnChange, creating the new ones on the server
ForAll(Filter(tpSkills.SelectedTags As tag, IsBlank(LookUp(Skills, Skill = tag.Key))), Patch(Skills, Defaults(Skills), {Name: tag.Label}))
Load options from the server as they type, for very long lists:
// tpSkills.Options
If(Len(tpSkills.SearchText) >= 2, ShowColumns(RenameColumns(Filter(Skills, StartsWith(Name, tpSkills.SearchText)), "Skill", "Key", "Name", "Label"), "Key", "Label"), Table({Key: "", Label: ""}))
- Columns.
Optionswants exactlyKeyandLabel;RenameColumnsandShowColumnsget them from any table. Use the row's GUID or a stable code asKey, because that is whatSelectedKeysstores. - Choices columns. For a multi-select choices column, build
Optionsfrom the choice values (Table({Key: "1", Label: "Power Apps"}, …)orChoices), and patch the column withForAll(tpSkills.SelectedTags, Value(Key))mapped to the choice values. - Searching on the server. The suggestions filter
Optionsin the app within, which is fine for a few hundred options; past that, filter on the server withStartsWithonSearchText, which is delegable, as in the last example. - A tag already chosen is left out of the suggestions, and
Addignores a key that is already there, so a double Patch never happens.
- The chips are a group named "Chosen tags"; each remove control is a button named "Remove" and the label. The box is named by its placeholder, and the suggestions are a group named "Suggestions" of buttons named by the label and "add" (or "as a new tag"). Tab moves from the chips to the box to the suggestions; Enter and Space add or remove.
- At the limit, the box is disabled and its placeholder says "Limit of 3 reached", so the state is in words.
- With
Motionon, a chip pops in when its tag is added, in a quarter of a second. None plays for people who've asked their device for reduced motion, andMotionoff shows it at once.
- The component keeps room for two rows of chips (or enough for
MaxTags, up to three), the box andMaxSuggestionssuggestions: Studio can't size a component from what's inside it (it falls back to a default size), so its height doesn't follow the chips. More chips scroll in their rows. - Every chip is
ChipWidthwide, because a gallery's cells share one width; a long label is cut, and the full label stays in the tooltip and the remove button's name. SetChipWidthfor your longest usual label. - Enter doesn't add the first suggestion: the modern text input raises its change when focus leaves it, so people Tab to the suggestion or select it.
- A new tag's
Keyis its text; if you store keys as GUIDs, create the record inOnChangeand refreshDefaultKeysfrom the server afterwards. SelectedKeysis a comma list, so a key can't contain a comma.
- 0.1.0: first version: chips with remove, suggestions as you type, new tags, the limit,
SelectedKeys,SelectedTags,Count,SearchText,OnChange,Add,Remove,Clear, light and dark, the chip motion.
Did it work for you?
No ratings yet.Nobody has said it worked in their app yet.
Sign in to rate it or to say it worked in your app.
Comments
No comments yet. Share how you used it, or ask something.
Sign in to comment or reply. Comments show under a display name you choose, never your email.