import { Component } from '@angular/core';
import { WrTransfer } from 'ngwr/transfer';
@Component({ imports: [WrTransfer] })
export class MyComponent {}Transfer
Move items between two lists; the right one is the value.
Installation
Import the class, and @use the entry point in your global styles. Nothing warns you when the @use is missing.
Basic usage
[items] is the full set and [(value)] the values on the right; ticked rows move when you press an arrow.
<wr-transfer [items]="permissions" [(value)]="granted" />Search and titles
searchable adds a filter to each list; sourceTitle and targetTitle name them.
<wr-transfer
searchable
sourceTitle="All permissions"
targetTitle="Granted"
[items]="permissions"
[(value)]="granted"
/>In a form
[formField] or any Angular form binds the values on the right.
<!-- Signal Forms -->
<wr-transfer [items]="permissions" [formField]="form.granted" />
<!-- Reactive forms -->
<wr-transfer [items]="permissions" [formControl]="granted" />API
| Name | Description | Type | Default |
|---|---|---|---|
items | Every row, in either pane. Membership of the right pane is value. | readonly WrTransferItem[] | [] |
value | Values currently in the RIGHT pane. Two-way bindable; bound automatically by [formField] / [(ngModel)]. | readonly unknown[] | [] |
(touch) | Emitted on blur / commit so a bound field marks itself touched. | void | — |
disabled | Disable the whole control. | boolean | false |
readonly | Refuse changes to the value while both panes stay focusable and readable. Bound automatically from the field's readonly state when used with [formField]. The move buttons go inert and the row checkboxes go read-only; SEARCH keeps working, because filtering a pane changes what is shown and not what is chosen. No aria-readonly on the host: role group does not support the state, so each row's checkbox mirrors its own instead. | boolean | false |
searchable | Show a filter box above each pane. | boolean | false |
sourceTitle | Heading above the left pane. Falls back to transfer.source. | string | null | null |
targetTitle | Heading above the right pane. Falls back to transfer.target. | string | null | null |
searchPlaceholder | Placeholder in both filter boxes. Falls back to transfer.search. | string | null | null |
emptyText | Shown in a pane with no rows. Falls back to transfer.empty. | string | null | null |
selectAllLabel | Accessible name of each pane's select-all checkbox, composed with the pane heading. Falls back to transfer.selectAll. | string | null | null |
toTargetLabel | Accessible name of the move-right button. Falls back to transfer.toTarget. | string | null | null |
toSourceLabel | Accessible name of the move-left button. Falls back to transfer.toSource. | string | null | null |
CSS variables
Set these on the element itself, with a rule more specific than its Declared on selector. In a global stylesheet, put a class of yours on an ancestor it really has: <body> for an overlay panel, which renders outside your markup. In a component stylesheet the selector alone works, but only for an element in that component's own template. A value on a wrapper or :root is shadowed, because ngwr/transfer declares each default on its own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-transfer-actions-gap | var(--wr-space-sm) | .wr-transfer__actions |
--wr-transfer-count-font-size | var(--wr-text-xs) | .wr-transfer__count |
--wr-transfer-empty-font-size | var(--wr-text-sm) | .wr-transfer__empty |
--wr-transfer-empty-padding-x | var(--wr-space-sm) | .wr-transfer__empty |
--wr-transfer-empty-padding-y | var(--wr-space-lg) | .wr-transfer__empty |
--wr-transfer-font-family | var(--wr-font-family-base) | .wr-transfer |
--wr-transfer-gap | var(--wr-space-md) | .wr-transfer |
--wr-transfer-head-gap | var(--wr-space-sm) | .wr-transfer__head |
--wr-transfer-head-padding-x | var(--wr-space-md) | .wr-transfer__head |
--wr-transfer-head-padding-y | var(--wr-space-sm) | .wr-transfer__head |
--wr-transfer-item-padding-x | var(--wr-space-sm) | .wr-transfer__item |
--wr-transfer-item-padding-y | var(--wr-space-xs) | .wr-transfer__item |
--wr-transfer-item-radius | var(--wr-border-radius-sm) | .wr-transfer__item |
--wr-transfer-list-padding | var(--wr-space-xs) | .wr-transfer__list |
--wr-transfer-pane-height | 15rem | .wr-transfer |
--wr-transfer-pane-radius | var(--wr-border-radius-base) | .wr-transfer__pane |
--wr-transfer-pane-width | 14rem | .wr-transfer |
--wr-transfer-search-padding-x | var(--wr-space-md) | .wr-transfer__search |
--wr-transfer-search-padding-y | var(--wr-space-sm) | .wr-transfer__search |
--wr-transfer-title-font-size | var(--wr-text-sm) | .wr-transfer__title |
--wr-transfer-title-font-weight | var(--wr-font-weight-medium) | .wr-transfer__title |
Dependencies
See also
Component SelectPick one or several values from a list, with search and free-text tags.Component Sortable ListA list the user reorders by drag or keyboard.Component Form FieldWraps a form control with a label, a hint and its error messages.Guide FormsBind ngwr controls to any Angular form and show their errors.Component ButtonA button for an action or a link.Component CheckboxA checkbox for one boolean, or a group of them for an array.Component FormA plain layout wrapper for a label, a control and its error.Component InputA directive that styles a native <input> or <textarea>.