npm package: @ruc-lib/multi-select
Description: A flexible and customizable multi-select dropdown component for Angular applications. It supports single or multiple selections, parent-child relationships, search, sorting, and custom theming.
Latest version: 4.0.0

# ruclib-multi-select

A flexible and customizable multi-select dropdown component for Angular applications. It supports single or multiple selections, parent-child relationships, search, sorting, and custom theming.

## Installation Guide

To use the Multi-Select component, you can install the entire RUC library or just this specific component.

### Install the Entire Library
```bash
npm install @uxpractice/ruc-lib
```

### Install Individual Component

If you only need the MultiSelect component:

**For Angular 15:**
```bash
npm install @ruc-lib/multi-select@3.2.0 @angular/material@^15.0.0 @angular/cdk@^15.0.0
```

**For Angular 16:**
```bash
npm install @ruc-lib/multi-select@3.2.0 @angular/material@^16.0.0 @angular/cdk@^16.0.0
```

**For Angular 17:**
```bash
npm install @ruc-lib/multi-select@4.0.0 @angular/material@^17.0.0 @angular/cdk@^17.0.0
```

**For Angular 18:**
```bash
npm install @ruc-lib/multi-select@4.0.0 @angular/material@^18.0.0 @angular/cdk@^18.0.0
```

**For Angular 19:**
```bash
npm install @ruc-lib/multi-select@4.0.0 @angular/material@^19.0.0 @angular/cdk@^19.0.0
```

**For Angular 20:**
```bash
npm install @ruc-lib/multi-select@4.0.0
```

> **Note:** When installing in Angular 15-19 apps, you must specify the matching `@angular/material` and `@angular/cdk` versions to avoid peer dependency conflicts. Angular 20 will automatically use the correct versions.

### 📦 Version Compatibility

| Angular Version    | Compatible `@ruc-lib/multi-select` Version     |
|--------------------|------------------------------------------------|
| 15.x.x             | `npm install @ruc-lib/multi-select@^3.2.0`     |
| 16.x.x             | `npm install @ruc-lib/multi-select@^3.2.0`     |
| 17.x.x             | `npm install @ruc-lib/multi-select@^4.0.0`     |
| 18.x.x             | `npm install @ruc-lib/multi-select@^4.0.0`     |
| 19.x.x             | `npm install @ruc-lib/multi-select@^4.0.0`     |
| 20.x.x             | `npm install @ruc-lib/multi-select@^4.0.0`     |


## Usage

### 1. Import the Component
In your Angular component file (e.g., `app.component.ts`), import the `RuclibMultiSelectComponent`:

```typescript
import { Component } from '@angular/core';

// For Complete Library
import { RuclibMultiSelectComponent } from '@uxpractice/ruc-lib/multi-select';

// For Individual Package
import { RuclibMultiSelectComponent } from '@ruc-lib/multi-select';

@Component({
  selector: 'app-root',
  imports: [RuclibMultiSelectComponent],
  templateUrl: './app.component.html',
})
export class AppComponent {
  // Component code here
}
```

### 2. Use the Component
In your component's template, use the `<uxp-ruclib-multi-select>` selector and pass the configuration and data to the respective inputs.

```html
<uxp-ruclib-multi-select 
  [dataSource]="dataSourceForMultiSelect" 
  [rucInputData]="inputObjectDataMulti" 
  [customTheme]="'custom-theme'"
  (rucEvent)="handleEvent($event)">
</uxp-ruclib-multi-select>
```

## API Reference

### Component Inputs

| Input          | Type               | Description                                      |
|----------------|--------------------|--------------------------------------------------|
| `rucInputData` | `DefaultConfig`    | The main configuration object for the component. |
| `dataSource`   | `ListItem[]`       | An array of items to be displayed in the dropdown. |
| `customTheme`  | `string`           | An optional CSS class for custom theming.        |

### Component Outputs

| Output     | Type               | Description                                                                 |
|------------|--------------------|-----------------------------------------------------------------------------|
| `rucEvent` | `EventEmitter<any>` | Emits an event whenever a selection changes, an item is deselected, or the input is clicked. |

### `DefaultConfig`
This is the main configuration object for the multi-select component.

| Property            | Type                   | Description                                                                                             |
|---------------------|------------------------|---------------------------------------------------------------------------------------------------------|
| `singleSelection`   | `boolean`              | If `true`, allows only a single item to be selected. Defaults to `false`.                               |
| `label`             | `string`               | The label for the multi-select input field.                                                             |
| `showSelectAll`     | `boolean`              | If `true`, displays a "Select All" checkbox. Defaults to `true`.                                        |
| `showSelected`      | `boolean`              | If `true`, displays a "Show Selected" filter. Defaults to `true`.                                       |
| `appearance`        | `'fill' \| 'outline'`  | The appearance of the form field. Defaults to `'outline'`.                                              |
| `scroll`            | `boolean`              | Enables or disables scrolling within the dropdown. Defaults to `true`.                                  |
| `placeholder`       | `string`               | The placeholder text for the search input.                                                              |
| `limit`             | `number`               | The maximum number of items that can be selected.                                                       |
| `maxDropdownHeight` | `string`               | The maximum height of the dropdown container (e.g., `'200px'`).                                         |
| `maxHeight`         | `number`               | The maximum height of the options box in pixels. Defaults to `150`.                                     |
| `disabled`          | `boolean`              | If `true`, disables the entire component. Defaults to `false`.                                          |
| `sortBy`            | `string`               | The property of the `ListItem` to sort by (e.g., `'id'`, `'text'`).                                     |
| `sortOrder`         | `'asc' \| 'desc'`      | The order of sorting.                                                                                   |

### `ListItem`
This object defines the configuration for each item in the `dataSource`.

| Property     | Type               | Description                                                              |
|--------------|--------------------|--------------------------------------------------------------------------|
| `id`         | `string \| number` | A unique identifier for the item.                                        |
| `text`       | `string`           | The display text for the item.                                           |
| `isDisabled` | `boolean`          | If `true`, this item will be disabled and cannot be selected.            |
| `icon`       | `string`           | An optional icon to display next to the item.                            |
| `childItem`  | `any`              | Used for creating parent-child relationships.                            |
| `grouped`    | `boolean`          | If `true`, indicates that the item is a group header.                    |

## Example Configuration

Here's an example of how to configure the Multi-Select component in your component's TypeScript file.

```typescript
import { Component } from '@angular/core';
import { DefaultConfig, ListItem } from '@ruc-lib/multi-select';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  
  inputObjectDataMulti: DefaultConfig = {
    singleSelection: false,
    label: 'Cities',
    showSelectAll: true,
    showSelected: true,
    appearance: 'outline',
    scroll: true,
    placeholder: 'Search or select from dropdown',
    limit: 5,
    maxDropdownHeight: '200px',
    maxHeight: 150,
    disabled: false,
    sortBy: 'id',
    sortOrder: 'desc',
  };

  dataSourceForMultiSelect: ListItem[] = [
    { text: 'Afghanistan', id: 'AF', isDisabled: true },
    { text: 'Åland Islands', id: 'AX', isDisabled: false },
    { text: 'Albania', id: 'AL', isDisabled: false },
    { text: 'Algeria', id: 'DZ', isDisabled: false },
  ];

  handleEvent(event: any) {
    console.log(event.eventName, event.eventOutput);
  }
}
```

> ⚠️ **IMPORTANT: Custom Theme Usage in Angular Material**

When implementing **custom themes**, such as:

```scss
.custom-theme-1 {
  @include angular-material-theme($custom-theme);
}

// You must also include the typography mixin to ensure text styles are applied correctly as shown below:
.custom-theme-1 {
  @include angular-material-theme($custom-theme);
  @include mat.typography-level($theme-custom-typography-name, body-1);
}
```


## Contribution

Contributions are welcome! Feel free to open issues or pull requests for any enhancements or fixes.

## Acknowledgements

Thank you for choosing the Multi Select Component. If you have any feedback or suggestions, please let us know!