Back to Consul

SuperSelectWithCreate

ui/packages/consul-ui/app/components/super-select-with-create/README.mdx

1.22.75.4 KB
Original Source

SuperSelectWithCreate

hbs
<SuperSelectWithCreate
  @options={{availableOptions}}
  @selected={{selectedOption}}
  @onCreate={{action "createNewOption"}}
  @onChange={{action "handleSelection"}}
  as |option|>
  {{option.name}}
</SuperSelectWithCreate>

<SuperSelectWithCreate /> is an accessible dropdown component that extends the functionality of HDS SuperSelect to allow users to create new options on-the-fly. It provides the same API as PowerSelectWithCreate but with built-in accessibility features and proper ARIA attributes.

Please note: This component uses HDS SuperSelect as its foundation and includes automatic ARIA fixes for PowerSelect accessibility issues. All accessibility features are handled internally without requiring external modifiers.

Arguments

Argument/AttributeTypeDefaultDescription
optionsArray[]Array of available options to display in the dropdown
selectedObject/StringnullCurrently selected option
onCreateFunctionfunction() {}Required - Action called when creating a new option. Receives the search term as parameter
onChangeFunctionfunction() {}Action called when selection changes. Receives the selected option as parameter
onFilterFunctionfunction() {}Action called when search term changes
onOpenFunctionfunction() {}Action called when dropdown opens
onCloseFunctionfunction() {}Action called when dropdown closes
onErrorFunctionfunction() {}Action called when create operation fails
buildSuggestionFunctionnullCustom function to build the "Create..." option text
showCreateWhenFunctionnullCustom function to determine when to show create option
searchFieldString'name'Field to use for searching and displaying options
searchPlaceholderString'Search...'Placeholder text for search input
labelString''Label for the select component
listboxAriaLabelString'Available options'ARIA label for the dropdown listbox
isOptionalBooleantrueWhether the field is optional
helperTextString''Helper text displayed below the component
errorTextString''Error text displayed when validation fails
disabledBooleanfalseWhether the component is disabled
placeholderStringnullPlaceholder text for the input
typeString'option'Type of items being selected (used in labels)
idStringnullHTML id attribute for the component

The component yields contextual content through named blocks:

  • <:option>: Used for rendering individual options
  • <:label>: Used for rendering the label content
  • <:create>: Used for rendering create-specific content
  • <:creating>: Used for rendering loading state during creation
  • <:selected>: Used for rendering content when options are selected
  • <:empty>: Used for rendering content when no options are selected

Example

hbs
<SuperSelectWithCreate
  @options={{availableTags}}
  @selected={{selectedTag}}
  @onCreate={{action "createTag"}}
  @onChange={{action "updateTag"}}
  @buildSuggestion={{this.buildTagSuggestion}}
  @showCreateWhen={{this.shouldAllowTagCreation}}
  @searchField="name"
  @label="Select or create tag"
  @searchPlaceholder="Search tags or type to create..."
  @type="tag"
>
  <:label>Tag Selection</:label>
  <:option as |tag|>
    <strong>{{tag.name}}</strong>
    {{#if tag.description}}
      
<small>{{tag.description}}</small>
    {{/if}}
  </:option>
  <:creating>
    <div class="custom-creating">Creating new tag...</div>
  </:creating>
  <:selected>
    <p>Selected: {{selectedTag.name}}</p>
  </:selected>
</SuperSelectWithCreate>

Component Actions Example

javascript
// In your parent component
@action
async createTag(tagName) {
  try {
    const newTag = await this.tagService.create({ name: tagName });
    this.availableTags.pushObject(newTag);
    return newTag; // Will be selected automatically
  } catch (error) {
    console.error('Failed to create tag:', error);
    throw error;
  }
}

@action
buildTagSuggestion(term) {
  return `Add new tag: "${term}"`;
}

@action
shouldAllowTagCreation(term, options) {
  return term.length >= 3 && !options.find(opt => 
    opt.name.toLowerCase() === term.toLowerCase()
  );
}

Accessibility Features

This component includes built-in accessibility features:

  • Proper ARIA roles - Fixes PowerSelect's role="alert" to role="option"
  • Keyboard navigation - Full arrow key and Enter/Escape support
  • Screen reader support - Proper ARIA labels and descriptions
  • Focus management - Correct focus handling for dropdown states
  • Scroll accessibility - Auto-scroll to highlighted options

States

The component manages several internal states:

  • idle - Normal state, ready for interaction
  • searching - User is typing to filter options
  • creating - New option is being created (shows loading indicator)
  • error - Creation failed (if onError handler provided)

See