npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ionic-selectable

v7.0.2

Published

An Ionic component similar to Ionic Select, that allows to search items, including async search, group, add, edit, delete items, and much more.

Readme

Ionic Selectable

npm npm npm

Features | Getting started | Virtual scroll | FAQ | Docs

An Ionic component similar to Ionic Select, that allows to search items, including async search, infinite scrolling, virtual scrolling and more.

iOS Demo

Which package am I looking at? This is the Angular component. There is also a separate Stencil-based line that ships web components for vanilla JS and other frameworks. The instructions below are for the Angular package.

Contents

Compatibility

| ionic-selectable | Ionic | Angular | | ---------------- | ----- | ------- | | 7.x | 8 | 20 – 22 | | 6.x | 7 | 16 | | 4.x | 4 | — | | 3.x | 3 | — |

7.x is a standalone build. The component, the modal and all template directives are standalone, and Ionic is consumed through @ionic/angular/standalone. It works both in apps bootstrapped with provideIonicAngular() and in apps still using IonicModule.forRoot().

The package is published in Angular's partial compilation mode, so a build made with Angular 21 links cleanly into Angular 20, 21 and 22 applications.

Features

Getting started

1. Install it

npm install ionic-selectable --save

@angular/cdk is a peer dependency — it powers the virtual scroll viewport — so install it too if your app doesn't have it already:

npm install @angular/cdk --save

2. Import it

Because the component is standalone, import it directly into whichever component uses it:

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { IonItem, IonLabel } from '@ionic/angular/standalone';
import { IonicSelectableComponent } from 'ionic-selectable';

@Component({
  selector: 'app-home',
  templateUrl: './home.page.html',
  imports: [FormsModule, IonItem, IonLabel, IonicSelectableComponent]
})
export class HomePage { }

If you use the template directives (ionicSelectableItemTemplate, ionicSelectableValueTemplate, …), import them alongside the component, or import IonicSelectableModule, which re-exports the component and every directive at once:

import { IonicSelectableModule } from 'ionic-selectable';

@Component({
  // ...
  imports: [IonicSelectableModule]
})
export class HomePage { }

IonicSelectableModule is also still a valid NgModule import, so existing module-based apps keep working unchanged:

@NgModule({
  imports: [IonicSelectableModule]
})
export class AppModule { }

For Angular 16 standalone component

import { IonicSelectableComponent } from 'ionic-selectable';

@Component({
    ...,
    standalone: true,
    imports: [IonicSelectableComponent]
})

3. Add it to the template

<ion-item>
  <ion-label>Port</ion-label>
  <ionic-selectable
    [(ngModel)]="port"
    [items]="ports"
    itemValueField="id"
    itemTextField="name"
    [canSearch]="true"
    (onChange)="portChange($event)">
  </ionic-selectable>
</ion-item>

4. Configure it

import { Component } from '@angular/core';
import { IonicSelectableComponent } from 'ionic-selectable';

interface Port {
  id: number;
  name: string;
}

@Component({ /* ... */ })
export class HomePage {
  ports: Port[] = [
    { id: 1, name: 'Tokai' },
    { id: 2, name: 'Vladivostok' },
    { id: 3, name: 'Navlakhi' }
  ];
  port: Port | undefined;

  portChange(event: { component: IonicSelectableComponent; value: any }) {
    console.log('port:', event.value);
  }
}

5. Enjoy it 😉

Explore the docs and FAQ to learn more about its features, and run the demo app in this repo to see every option in action.

Virtual scroll

Set hasVirtualScroll when the list is long enough that rendering every item hurts. The modal then renders the list through an Angular CDK virtual scroll viewport, keeping only the visible rows in the DOM.

<ionic-selectable
  [(ngModel)]="port"
  [items]="ports"
  itemValueField="id"
  itemTextField="name"
  [hasVirtualScroll]="true"
  [canSearch]="true">
</ionic-selectable>

Grouping

Groups and virtual scroll can be used together. Groups are flattened into a single stream of header and item rows, so groupValueField / groupTextField work exactly as they do in a regular list:

<ionic-selectable
  [(ngModel)]="port"
  [items]="ports"
  itemValueField="id"
  itemTextField="name"
  groupValueField="country.id"
  groupTextField="country.name"
  [hasVirtualScroll]="true">
</ionic-selectable>

When the items aren't grouped with groupValueField, headers can still be inserted with virtualScrollHeaderFn. It receives each item and returns the header text to render before it, or undefined for no header:

<ionic-selectable
  [hasVirtualScroll]="true"
  [virtualScrollHeaderFn]="getGroupText">
</ionic-selectable>
getGroupText(port: Port, index: number, ports: Port[]) {
  if (index === 0 || port.country.id !== ports[index - 1].country.id) {
    return port.country.name;
  }

  return undefined;
}

Row height

Rows are rendered at a fixed height, which defaults to 40px. Both items and group headers are pinned to it. Change it with virtualScrollApproxItemHeight, which accepts a number of pixels or a px string:

<ionic-selectable [hasVirtualScroll]="true" [virtualScrollApproxItemHeight]="56">
</ionic-selectable>

The value is also exposed to CSS as --ionic-selectable-virtual-item-height on the viewport, so custom item templates can lay themselves out against it.

Notes

  • Virtual scroll and hasInfiniteScroll are mutually exclusive. With virtual scroll enabled, infinite scroll is not rendered and enableInfiniteScroll() / disableInfiniteScroll() / endInfiniteScroll() are no-ops.
  • scrollToTop() and scrollToBottom() operate on the viewport.
  • The viewport is the scrolling element, so ion-content scrolling is turned off while virtual scroll is on.
  • Searching resets the viewport back to the first row.

Development

The repo contains both the library (src/app/components/ionic-selectable) and a demo app covering every feature (src/app/pages).

npm install        # install dependencies
npm start          # serve the demo app
npm run build      # build the demo app
npm test           # run unit tests
npm run lint       # lint
npm run build.ng   # build the publishable library into dist/

Publishing

Always publish the built package from dist/, never from the repo root (the root only contains sources and would ship raw .ts files without a module/exports entry; a prepublishOnly guard blocks this by mistake):

npm version <x.y.z> --no-git-tag-version   # bump version in package.json
npm run build.ng                            # build into dist/ (copies package.json, README, LICENSE)
cd dist && npm publish                      # publish the built package

For contribution guidelines please refer to Contribution.

Share it

If you find this component useful, please star the repo to let others know that it's reliable. Also, share it with friends and colleagues who might find it useful as well. Thank you 😄