Skip to content

EntityTypePicker

Picks one entity type of a site, from a searchable list of everything the site has enabled.

Single and multi: EntityTypeMultiPicker takes several types. This picker takes multiple no more; a caller passing it moves to the multi picker.

Terminal window
pnpm dlx shadcn@latest add https://sg-widgets.vercel.app/r/react/entity-type-picker.json
Terminal window
pnpm dlx shadcn-svelte@latest add https://sg-widgets.vercel.app/r/svelte/entity-type-picker.json
EntityTypePicker: allow and deny lists, codes, sizes and states

React

Loading the React demo…

Svelte

Loading the Svelte demo…

proptypedefaultmeaning
contextSgContextrequiredThe widget context. The site's enabled types are read through it, once per page.
valuestring | nullnullThe chosen type code. Two-way in Svelte.
allowstring[]—Codes on offer. Empty or absent means every enabled type.
denystring[]—Codes withheld, applied after allow.
showCodebooleantrueShows the code under the display name where the two differ.
className / classstring—Merged after the widget's own classes.
sizefrom PickerControl'sm' | 'md' | 'lg''md'Control height: 7, 8 and 9.
disabledfrom PickerControlbooleanfalse
readonlybooleanfalseKeeps full contrast and removes the chevron and the clear control.
invalidbooleanfalseApplies the invalid ring and aria-invalid.
clearablebooleantrueShow the clear control once something is chosen.
placeholderstring'Select an entity type'Shown while nothing is chosen.
searchPlaceholderstring'Search types…'Shown in the search box.
openfrom PickerControlbooleanrequiredReact: whether the popup is showing.
openfrom PickerControlbooleanfalseSvelte: whether the popup is showing, two-way.
emptyLabelstring'No match'Shown when the search matches nothing.
loadingLabelstring'Loading…'Names the skeletons a read stands behind, for a screen reader.
errorLabelstring—Shown in place of what the failed read said.

Every other attribute is spread onto the root: id, aria-*, data-*, key handlers and a ref to the root element.

Each row shows the display name, with the code beneath it in mono when the two differ, unless showCode is off. The control is a token field: the value is one chip, with the caret beside it. A pick closes the list.

allow is applied first and deny second, both to the derived list rather than to the read, so a caller narrowing the set sees the list change with no second call.

eventpayloadwhen
onValueChangestring | nullA type is chosen, or the clear control is pressed.
onOpenChangebooleanThe popup opened or closed. Svelte also binds it with bind:open.

None.

keydoes
any textNarrows the rows, from the caret in the control.
Enter, SpaceOn the chevron, opens the list.
Down, UpMove the cursor through the rows and keep it in view. The last row holds it rather than wrapping.
ArrowDown / ArrowUpfrom PickerControlMoves the highlight, and the list scrolls it into view.
EnterChoose the highlighted type and close the list.
EscapeClose, keeping the value and clearing the query. On a closed picker it does nothing.
BackspaceIn an empty search box, clears the value.
ArrowLeft / ArrowRightfrom PickerControlOn a chip, walks the row. ArrowRight past the last chip returns to the input.
Deletefrom PickerControlOn a chip, removes it and leaves the caret on its neighbour.
Tabfrom PickerControlLeaves the control.

GET /schema returns every enabled type in about 12KB, custom slots included, and presence in that listing is the enablement test: a slot absent from it 404s everywhere else. The display name is the type’s name, and the key is what a URL and a dotted path take (002_schema).

The row, chip and checkbox anatomy follows shadcn’s Base UI Combobox, read through shadcn 4.21.0. The primitive underneath is Base UI Combobox 1.8.0 in React and Bits UI Combobox 2.19.1 in Svelte. shadcn-svelte ships no combobox item, so each widget composes the headless primitive of its framework and both draw the same rows, the same classes and the same states.