Skip to content

feat(select): support constructions of custom select#1852

Open
spike-rabbit wants to merge 1 commit intomainfrom
feat/custom-select
Open

feat(select): support constructions of custom select#1852
spike-rabbit wants to merge 1 commit intomainfrom
feat/custom-select

Conversation

@spike-rabbit
Copy link
Copy Markdown
Member

@spike-rabbit spike-rabbit commented Apr 10, 2026

Adding a set of utilities that allows customers
to create selects with custom backed value selection, for instance using si-tree-view.

A very simple version of it can look like this:

@Component({
  selector: 'app-tree-select',
  imports: [SiSelectComboboxComponent, SiSelectDropdownDirective, SiTreeViewComponent],
  template: `
    <si-select-combobox>
      @if (select.value(); as val) {
        {{ val }}
      } @else {
        <span class="text-secondary">Select a location...</span>
      }
    </si-select-combobox>

    <ng-template si-select-dropdown>
      <si-tree-view
        class="d-block"
        ariaLabel="Locations"
        [items]="items()"
        [enableSelection]="true"
        [singleSelectMode]="true"
        [isVirtualized]="false"
        (treeItemClicked)="selectItem($event)"
      />
    </ng-template>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  hostDirectives: [
    {
      directive: SiCustomSelectDirective,
      inputs: ['disabled', 'readonly', 'value'],
      outputs: ['valueChange']
    }
  ]
})
export class TreeSelectComponent {
  protected readonly select = inject(SiCustomSelectDirective);

  /** The tree items to display. */
  readonly items = input<TreeItem[]>([]);

  selectItem(item: TreeItem): void {
    if (item.label) {
      this.select.updateValue(item.label as string);
      this.select.close();
    }
  }
}

The goal is to empower applications
to build selects with whatever content they need
while we take care of accesibility and proper appereance.

Closes #1840


Documentation.
Examples.
Dashboards Demo.
Playwright report.

Coverage Reports:

Code Coverage

@spike-rabbit spike-rabbit requested a review from spliffone April 10, 2026 14:31
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new set of components and directives—SiCustomSelectDirective, SiSelectComboboxComponent, and SiSelectDropdownDirective—to enable the creation of custom select components like tree-selects. The implementation includes ControlValueAccessor and SiFormItemControl integration, comprehensive unit tests, and a usage example. Feedback focuses on improving consistency with the standard select component through enhanced keyboard navigation and visual alignment, ensuring Server-Side Rendering (SSR) safety for browser-specific APIs, and refining the ControlValueAccessor implementation and resource cleanup.

Comment thread projects/element-ng/select/si-custom-select.directive.ts Outdated
Comment thread projects/element-ng/select/si-custom-select.directive.ts Outdated
Comment thread projects/element-ng/select/si-custom-select.directive.ts Outdated
Comment thread projects/element-ng/select/si-custom-select.directive.ts Outdated
Comment thread projects/element-ng/select/si-custom-select.directive.ts
Comment thread projects/element-ng/select/si-select-combobox.component.scss Outdated
@spike-rabbit spike-rabbit force-pushed the feat/custom-select branch 4 times, most recently from 6f97d9e to 1502853 Compare April 20, 2026 15:18
Comment thread projects/element-ng/select/si-custom-select.directive.ts Outdated
Comment thread projects/element-ng/select/si-custom-select.directive.ts
Comment thread src/app/examples/si-select/si-select-custom.ts
Comment thread src/app/examples/si-select/si-select-custom.html Outdated
Comment thread projects/element-ng/select/si-select-combobox.component.ts Outdated
Comment thread src/app/examples/si-select/si-select-custom.ts

merge(
this.overlayRef.backdropClick(),
this.overlayRef.keydownEvents().pipe(filter(e => e.key === 'Escape'))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would assume that the tab key close the overlay

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we cannot do this here generally. Then we cannot have extra buttons and alike in the dropdown.

Comment thread src/app/examples/si-select/si-select-multi-custom.ts Outdated
Comment thread src/app/examples/si-select/si-select-multi-custom.ts Outdated
Comment thread src/app/examples/si-select/si-select-multi-custom.ts Outdated
@spike-rabbit spike-rabbit force-pushed the feat/custom-select branch 3 times, most recently from f121b49 to eec3e1f Compare April 22, 2026 12:47
Copy link
Copy Markdown
Member

@panch1739 panch1739 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spike-rabbit Niceeee! Just some points:

  1. Buttons are using the sm size (24px height). They should be the standard 32px
Image
  1. When I make the screen narrower, the menu does not adjust accordingly, cutting the footer out of frame:
Image
  1. Probably this is something that im doing wrong...but i tried to change the input to a button, to check how it looks with the the ghost style. Something did not work ahaha
Image
  1. In responsive behavior, the options get truncated:
Image

But in the design, we defined the same behavior as the current si-select:

When the available space is exceeded, the values collapse into a summarized representation (e.g. “+2”).

Image

@spike-rabbit spike-rabbit force-pushed the feat/custom-select branch 3 times, most recently from 7176e06 to fda0fa2 Compare May 7, 2026 05:16
Copy link
Copy Markdown
Member

@panch1739 panch1739 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spike-rabbit I found some small things:

The total height of the input is 36px, it should be 32px as our standard buttons and input

The distance in the footer should be adjusted also

Image

@spike-rabbit spike-rabbit force-pushed the feat/custom-select branch 13 times, most recently from 5cc83ce to 730beef Compare May 7, 2026 15:05
Adding a set of utilities that allows customers
to create selects with custom backed value selection,
for instance using `si-tree-view`.

A very simple version of it can look like this:

```ts
@component({
  selector: 'app-tree-select',
  imports: [SiSelectComboboxComponent, SiSelectDropdownDirective, SiTreeViewComponent],
  template: `
    <si-select-combobox>
      @if (select.value(); as val) {
        {{ val }}
      } @else {
        <span class="text-secondary">Select a location...</span>
      }
    </si-select-combobox>

    <ng-template si-select-dropdown>
      <si-tree-view
        class="d-block"
        ariaLabel="Locations"
        [items]="items()"
        [enableSelection]="true"
        [singleSelectMode]="true"
        [isVirtualized]="false"
        (treeItemClicked)="selectItem($event)"
      />
    </ng-template>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  hostDirectives: [
    {
      directive: SiCustomSelectDirective,
      inputs: ['disabled', 'readonly', 'value'],
      outputs: ['valueChange']
    }
  ]
})
export class TreeSelectComponent {
  protected readonly select = inject(SiCustomSelectDirective);

  /** The tree items to display. */
  readonly items = input<TreeItem[]>([]);

  selectItem(item: TreeItem): void {
    if (item.label) {
      this.select.updateValue(item.label as string);
      this.select.close();
    }
  }
}
```

The goal is to empower applications
to build selects with whatever content they need
while we take care of accesibility and proper appereance.

Closes #1840
@spike-rabbit spike-rabbit force-pushed the feat/custom-select branch from 730beef to 2668d53 Compare May 7, 2026 15:09
@spike-rabbit spike-rabbit marked this pull request as ready for review May 7, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New si-custom-select

3 participants