# Picklist

![Status](https://img.shields.io/badge/status-stable-brightgreen)

Componente para transferência de itens entre duas listas — disponíveis e selecionados. Suporta arrastar e soltar, filtro por texto, seleção múltipla com checkboxes e templates customizáveis para renderização dos itens.

## Quando usar

- Seleção de múltiplos itens de uma lista para outra (ex: permissões, usuários, produtos)
- Configuração de associações ou vínculos onde a ordem dos itens selecionados importa
- Qualquer cenário de transferência bidirecional entre dois conjuntos de dados

## Quando não usar

- Para seleção simples de um único item — use `Select` ou `RadioButton`
- Para seleção múltipla sem necessidade de duas listas — use `Checkbox` ou `MultiSelect`
- Quando a lista é muito grande e precisa de paginação — considere uma abordagem diferente

## Instalação

```typescript
import { PicklistModule } from '@seniorsistemas/angular-components/picklist';
import { TemplateModule } from '@seniorsistemas/angular-components/template';

@NgModule({ imports: [PicklistModule, TemplateModule] })
export class MeuModulo {}
```

## Uso básico

```html
<s-picklist
  [itensToSelect]="itensDisponiveis"
  [selectedItens]="itensSelecionados"
  (selectedItensChange)="onSelecaoMudou($event)"
  (itensToSelectChange)="onDisponiveisAtualizado($event)"
>
  <ng-template sTemplate="item-to-select" let-item="item">
    <span>{{ item.nome }}</span>
  </ng-template>
  <ng-template sTemplate="selected-item" let-item="item">
    <span>{{ item.nome }}</span>
  </ng-template>
</s-picklist>
```

> Os dois templates (`item-to-select` e `selected-item`) são **obrigatórios**.

## API

### Inputs

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|-------------|------|--------|:-----------:|-----------|
| `itensToSelect` | `PickListItem<any>[]` | `[]` | Sim | Lista de itens disponíveis para seleção (coluna esquerda) |
| `selectedItens` | `PickListItem<any>[]` | `[]` | Sim | Lista de itens já selecionados (coluna direita) |
| `availableItensLabel` | `string` | Tradução padrão | Não | Rótulo do cabeçalho da lista de disponíveis |
| `availableItensPlaceholder` | `string` | `undefined` | Não | Placeholder do campo de busca da lista de disponíveis |
| `addSelectedItensLabel` | `string` | `undefined` | Não | Rótulo do botão que move itens selecionados para a direita |
| `addAllItensLabel` | `string` | `undefined` | Não | Rótulo do botão que move todos os disponíveis para a direita |
| `selectedItensLabel` | `string` | Tradução padrão | Não | Rótulo do cabeçalho da lista de selecionados |
| `selectedItensPlaceholder` | `string` | `undefined` | Não | Placeholder do campo de busca da lista de selecionados |
| `removeSelectedItemsLabel` | `string` | `undefined` | Não | Rótulo do botão que remove itens selecionados |
| `removeAllItemsLabel` | `string` | `undefined` | Não | Rótulo do botão que remove todos os selecionados |
| `showCheckbox` | `boolean` | `false` | Não | Exibe checkboxes nos itens e "selecionar todos" no cabeçalho |
| `filterBy` | `string` | `''` | Não | Propriedade do objeto `data` usada para filtrar os itens. Quando definido, exibe campos de busca |

### Outputs

| Evento | Tipo | Descrição |
|--------|------|-----------|
| `selectedItensChange` | `EventEmitter<any[]>` | Emitido quando a lista de selecionados muda. Emite os dados brutos (sem o wrapper `PickListItem`) |
| `itensToSelectChange` | `EventEmitter<any[]>` | Emitido quando a lista de disponíveis muda. Emite os dados brutos (sem o wrapper `PickListItem`) |

### Tipos

```typescript
interface PickListItem<T> {
  data: T;          // Dados brutos do item — expostos no template como `let-item="item"`
  disabled?: boolean; // Impede seleção, movimentação e drag do item
}
```

## Exemplos

### Picklist básico

```html
<s-picklist
  [itensToSelect]="parseItensPickList(paises)"
  [selectedItens]="parseItensPickList(paisesSelecionados)"
  (selectedItensChange)="onSelecaoMudou($event)"
>
  <ng-template sTemplate="item-to-select" let-item="item">
    <span>{{ item.nome }}</span>
  </ng-template>
  <ng-template sTemplate="selected-item" let-item="item">
    <span>{{ item.nome }}</span>
  </ng-template>
</s-picklist>
```

### Com filtro e checkbox

```html
<s-picklist
  [itensToSelect]="itensDisponiveis"
  [selectedItens]="itensSelecionados"
  [showCheckbox]="true"
  filterBy="nome"
  availableItensPlaceholder="Buscar..."
  selectedItensPlaceholder="Buscar..."
>
  <ng-template sTemplate="item-to-select" let-item="item">
    <span>{{ item.nome }}</span>
  </ng-template>
  <ng-template sTemplate="selected-item" let-item="item">
    <span>{{ item.nome }}</span>
  </ng-template>
</s-picklist>
```

### Com itens desabilitados

```typescript
import { parseItensPickList } from '@seniorsistemas/angular-components/picklist';

this.itensDisponiveis = parseItensPickList(produtos, (item) => !item.emEstoque);
```

### Com labels customizados

```html
<s-picklist
  [itensToSelect]="itensDisponiveis"
  [selectedItens]="itensSelecionados"
  availableItensLabel="Países disponíveis"
  selectedItensLabel="Países selecionados"
  addSelectedItensLabel="Incluir →"
  addAllItensLabel="Incluir todos"
  removeSelectedItemsLabel="← Excluir"
  removeAllItemsLabel="Excluir todos"
>
  ...
</s-picklist>
```

### Utilitário parseItensPickList

```typescript
import { parseItensPickList } from '@seniorsistemas/angular-components/picklist';

// Sem itens desabilitados
this.itensToSelect = parseItensPickList(meusObjetos);

// Com função de desabilitação
this.itensToSelect = parseItensPickList(meusObjetos, (item) => item.bloqueado);
```

## Acessibilidade

- Os botões de adicionar/remover são elementos `<button>` nativos, navegáveis por teclado
- O drag & drop usa o CDK do Angular, acessível com mouse
- Itens desabilitados não podem ser selecionados, movidos ou arrastados
- Os campos de filtro têm `placeholder` configurável para orientar o usuário

## Componentes relacionados

- [`TokenList`](../token-list/README.md) — exibição de tokens selecionados em modo somente leitura
- [`Chips`](../chips/README.md) — entrada de múltiplos valores em formato de tags
