Transfer
Dual left/right panels with shuttle buttons in the middle, supporting search filtering, keyboard operation, target-side drag sorting and the select-to-move mode.
Basic Usage
Basic
The panel header shows a "selected/visible" count (e.g. 1/3), updating live with selection and filtering.
Preset Values & Titles
Preset value + titles
Searchable
searchable
Case-sensitive Search
searchable + case-sensitive
One-way Mode
Move left to right only; the right panel is read-only. The left panel shows all data, already transferred items are disabled and shown as selected.
one-way
Target Order & Drag Sorting
target-sort controls the right panel ordering strategy:
original(default): keep the data source order (consistent withdata)push: append newly transferred items to the endunshift: insert newly transferred items at the head, one by one
target-draggable enables drag sorting on the right panel (the "selected list" scenario where order carries business meaning). Touch (pointer: coarse) and keyboard alternatives: per-row "move up / move down" buttons (move by one on click), or click a right row first and press Alt + ↑/↓ (drag interactions must have an accessible alternative). With original the order is decided by the data source, so neither dragging nor sort buttons apply — pair push / unshift when manual sorting is needed.
target-sort=push + target-draggable (row move up/down buttons + drag)
target-sort=unshift (new items on top)
Select to Move (simple)
With simple, clicking a row shuttles it immediately (no central button; touch friendly); the central buttons are hidden. Off by default, keeping "select then press the button" as the primary form.
On narrow viewports (≤480px) the two panels stack vertically and the shuttle buttons switch to a centered horizontal row instead of the rigid 180px×2 width. On touch screens (pointer: coarse) option rows and shuttle buttons grow to a 44px hit target.
simple
Row Customization (item slot)
template[slot="item"] is cloned into every row (static and virtual panels alike); [data-item-label] binds the item text automatically:
item slot (role icon + rich rows)
Empty Customization (empty slot)
template[slot="empty"] customizes the empty state (shared by the true empty and the no-match states, both panels):
empty slot
Virtual Scroll
Windowed rendering for tens of thousands of items with smooth scrolling; selection, select-all and keyboard navigation keep working.
virtual (10000 items, item-height 32)
Long-list pagination (pagination)
pagination enables in-panel paging (page-size items per page, default 10): both panels page independently and a simple footer appears (previous / page indicator / next, auto-disabled at the edges). Pagination applies to the visible items after search filtering; changing the filter resets the page to 1; the panel-head count still reflects all visible items. Virtual mode window-sizes on its own — when both are set, pagination does not apply.
pagination + page-size=2
List scroll event (oas-scroll)
Scrolling a panel list emits oas-scroll (both static lists and virtual viewports), detail: { side, direction, scrollTop, reachBottom } — the lazy-loading channel: listen for reachBottom and append data to data.
Scroll feedback (reachBottom)
Disabled
disabled disables the whole group (rows / select-all / search / shuttle buttons / keyboard) and mirrors data-disabled on the host for styling; disabled-skip exempts it from global disabled injection.
disabled (view-only echo)
Events
Change events
Select & search events
oas-change: value change after shuttling,detail: { value }oas-select-change: panel selection change (row click / select-all / keyboard selection),detail: { side: 'left' | 'right', selected: string[] }oas-search: search input,detail: { side, query }oas-scroll: panel list scroll,detail: { side, direction: 'up' | 'down', scrollTop, reachBottom }(lazy-loading channel)
Keyboard
| Key | Action |
|---|---|
↑ / ↓ | Move the selection (single-select navigation) |
Enter | Shuttle the currently selected item |
Space | Toggle the current item's selection |
Ctrl/⌘ + A | Select all / clear all selectable visible items of the panel |
Alt + ↑/↓ | Sort the right panel (keyboard alternative to target-draggable; select a row first) |
Tree Data Transfer (oas-tree composition)
Tree/table transfers are not part of the component data protocol; compose them with oas-tree (checking) + transfer (value linkage):
Department tree member picking (oas-tree + transfer linkage)
Table-style transfer (multi-column info) works the same way: render the left data with oas-table and sync the checked key set to the transfer value.
API
oas-transfer
Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
case-sensitive | Search filtering is case-sensitive (case-insensitive by default) | boolean | — |
data | Data (JSON attribute channel; property assignment reflects to attribute, [{ key, label, disabled }]) | TransferItem[] | string | [] |
disabled | Disabled (row clicks/buttons/search all inert; host mirrors data-disabled) | boolean | — |
item-height | Fixed row height for virtual scrolling (px), default 36 | string | — |
one-way | One-way mode: move left to right only, right panel is read-only; left panel shows all data, already transferred items are disabled and shown as selected | boolean | — |
page-size | Items per page (invalid/<1 falls back to 10) | string | 10 |
pagination | Long-list paging with a simple footer per panel (applied after filtering) | boolean | — |
searchable | Search filtering within panels (filtered independently per panel) | boolean | — |
simple | Move on selection (skip the shuttle buttons, off by default) | boolean | — |
source-title | Left panel title | — | — |
target-draggable | Target-side drag sorting (pair with target-sort=push/unshift; original ordering is data-driven and not draggable) | boolean | — |
target-sort | Target-side ordering: original (default, data-source order) / push (append) / unshift (prepend). Note the value-array ordering semantics: with original, a pre-set out-of-order value is normalized to data order | string | original |
target-title | Right panel title | — | — |
titles | Panel titles (JSON array) or source-title/target-title | string | — |
value | Selected key array (JSON attribute) | string[] | string | [] |
virtual | Windowed rendering for large data (virtual scroll, default row height 36px) | boolean | — |
Property (JS property; see each row for attribute reflection)
| Property | Description | Type | Default |
|---|---|---|---|
value | Current value: array of target-side keys | string[] | string | — |
Events
| Event | Description |
|---|---|
oas-change | Value change after shuttling, detail: { value } |
oas-scroll | List scroll event { side, direction, scrollTop, reachBottom } (lazy-load channel), detail: { side, direction: cur > prev ? 'down' : 'up', scrollTop: cur, reachBottom } |
oas-search | Panel search input, detail: { side, query } |
oas-select-change | Selection set changed (row click/select-all/keyboard), detail: { side, selected } |
Slots
| Name | Description |
|---|---|
template[slot="empty"] | Custom content shared by empty and no-match states |
template[slot="item"] | Custom row ([data-item-label] binding, identical for static and virtual rows) |
Keyboard: after focusing a panel list, ↑/↓ moves the selection, Enter shuttles.