@rcarls/rc-transfer-list 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,137 @@
1
1
  # @rcarls/rc-transfer-list
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 079e025: Standardize component styling contracts for the breaking 0.7 release.
8
+
9
+ BREAKING CHANGE: Rename the Markdown editor's `--rme-*` properties to
10
+ `--rc-markdown-editor-*`, `--rc-app-bar-background` to `--rc-app-bar-bg`,
11
+ `--rc-textarea-radius` to `--rc-textarea-border-radius`, the transfer-list
12
+ `--rc-transfer-list-panel-*` properties to `--rc-transfer-list-listbox-*`,
13
+ `--rc-chip-group-webkit-scrollbar-display` to
14
+ `--rc-chip-group-scrollbar-display`, and `--rc-text` to `--rc-field-text`.
15
+ Compatibility aliases are intentionally not provided.
16
+
17
+ BREAKING CHANGE: Replace `--rc-select-chip-padding-inline` and
18
+ `--rc-combobox-chip-padding-inline` with explicit `*-padding-inline-start` and
19
+ `*-padding-inline-end` tokens. Generated removable chips now reserve the full
20
+ remove target and its edge offset, so their indicator cannot overlap label text.
21
+
22
+ Add canonical app-bar elevation, transfer-list listbox radius, and textarea
23
+ line-action tokens. Add logical `rc-chip` inline-padding properties so themes
24
+ can implement Material's icon-aware spacing without overriding authored child
25
+ styles. Make `rc-field` consume the shared semantic token layer,
26
+ and place the `rc-chip` and `rc-search-bar` light-DOM structural styles in the
27
+ `rc-base` cascade layer so normal consumer rules override them.
28
+
29
+ Prevent decorative, `aria-hidden` trailing list content from intercepting a
30
+ whole-row action target, and keep segmented-list item geometry from leaking
31
+ into nested standard lists.
32
+
33
+ Remove unused Material navigation-rail toggle tokens and obsolete list-item
34
+ theme tokens. Register the segmented-button private theme seam and enforce
35
+ token ownership, documentation, removed-name, selector-budget, and cascade
36
+ layer contracts through the component architecture audit.
37
+
38
+ - 54d9ead: Localize every component's built-in text. Button names, role
39
+ descriptions, announcements, and default labels now resolve per key from
40
+ the element's `messages` property, then from text registered with
41
+ `registerMessages(locale, catalog)` in `@rcarls/rc-common`, then from the
42
+ English defaults. The locale is the element's own `lang`, else
43
+ `<html lang>`; an ancestor's `lang` is ignored, because it usually marks
44
+ content rather than the interface. Components re-render when that locale
45
+ changes or new text is registered. `RcMessageCatalog` types the catalog,
46
+ and each package adds its scope to it.
47
+
48
+ Numbers a component formats as text follow the same locale:
49
+ `rc-progress`'s default percentage and `rc-splitter`'s `aria-valuetext`
50
+ use `Intl.NumberFormat`. `TypeaheadController` matches prefixes with an
51
+ `Intl.Collator`, so case and accents are ignored the way the locale
52
+ ignores them, and takes a `locale` option. `ItemsCollectionController`'s
53
+ `setCreateOption(text, label?)` takes the option's visible text from its
54
+ caller.
55
+
56
+ `rc-transfer-list`'s direction arrows are now decorative: screen readers
57
+ read only the action name, and the arrows turn over in RTL.
58
+
59
+ **Breaking:** chrome-text properties are replaced by `messages`. Migrate:
60
+
61
+ - `rc-search-bar` `clear-label` / `clearLabel` → `messages.clear`
62
+ - `rc-adaptive-menu` `overflow-label` / `overflowLabel` → `messages.overflow`
63
+ - `rc-chip-group` `show-all-label` / `showAllLabel` and `show-less-label` /
64
+ `showLessLabel` → `messages.showAll` and `messages.showLess`
65
+ - `rc-select` and `rc-combobox` `dialog-confirm-label` /
66
+ `dialogConfirmLabel` and `dialog-cancel-label` / `dialogCancelLabel` →
67
+ `messages.done` and `messages.cancel`
68
+ - `rc-editor-toolbar` `label` → `messages.toolbar`
69
+
70
+ Per-instance names stay attributes, but now default to `undefined` and fall
71
+ back to a message: `label` on `rc-adaptive-menu`, `rc-chip-group`,
72
+ `rc-menubar`, and `rc-splitter`; `available-label` and `selected-label`
73
+ on `rc-transfer-list`; `low-label` and `high-label` on `rc-range-slider`.
74
+ Read the resolved name from the rendered `aria-label` instead of the
75
+ property.
76
+
77
+ ### Patch Changes
78
+
79
+ - 5c006de: Ship component CSS minified. Package builds now run the CSS in Lit `css` styles
80
+ and light-DOM structural styles through Lightning CSS, removing comments and
81
+ whitespace while keeping source maps that resolve to each template. Rendered
82
+ styles are unchanged.
83
+
84
+ `@rcarls/rc-common` adds `cssText`, an identity tag that marks a plain CSS
85
+ string for minification. `rc-chip`, `rc-disclosure`, and `rc-accordion` now
86
+ depend on `@rcarls/rc-common` for it.
87
+
88
+ - 51f6403: Arrow keys follow the reading direction everywhere. `keyNavigation` now also
89
+ flips the cross axis in RTL, so a vertical menu opens its submenu with
90
+ ArrowLeft, as the APG describes. A horizontal menubar and segmented button
91
+ advance with ArrowLeft in RTL, Alt+ArrowLeft moves items toward the selected
92
+ list of a transfer list in RTL, and the arrow toward the inline start reaches
93
+ the chips of a multiple select or combobox (ArrowRight in RTL).
94
+
95
+ Add `inlineArrowKeys(flow)` for content that runs along the inline axis, such
96
+ as chips or text.
97
+
98
+ - Updated dependencies [e3dfa59]
99
+ - Updated dependencies [50d5610]
100
+ - Updated dependencies [9ee769c]
101
+ - Updated dependencies [1179f24]
102
+ - Updated dependencies [595fe37]
103
+ - Updated dependencies [38cd00c]
104
+ - Updated dependencies [5c006de]
105
+ - Updated dependencies [a6553ff]
106
+ - Updated dependencies [2205478]
107
+ - Updated dependencies [4341311]
108
+ - Updated dependencies [899bb5e]
109
+ - Updated dependencies [25fcfe0]
110
+ - Updated dependencies [51f6403]
111
+ - Updated dependencies [9caca6b]
112
+ - Updated dependencies [b764a3c]
113
+ - Updated dependencies [cc0205d]
114
+ - Updated dependencies [54d9ead]
115
+ - Updated dependencies [b9175e9]
116
+ - Updated dependencies [c8b762b]
117
+ - Updated dependencies [55e1e7f]
118
+ - Updated dependencies [f1ca82d]
119
+ - Updated dependencies [b87f27b]
120
+ - Updated dependencies [32ebead]
121
+ - Updated dependencies [bfefedd]
122
+ - Updated dependencies [c130173]
123
+ - Updated dependencies [11680b6]
124
+ - Updated dependencies [223d36c]
125
+ - Updated dependencies [7b91a44]
126
+ - Updated dependencies [aa04ead]
127
+ - Updated dependencies [ac65b5b]
128
+ - Updated dependencies [6d126fd]
129
+ - Updated dependencies [afcfef8]
130
+ - Updated dependencies [11ef1ad]
131
+ - @rcarls/rc-common@0.7.0
132
+ - @rcarls/rc-listbox@0.7.0
133
+ - @rcarls/rc-toolbar@0.7.0
134
+
3
135
  ## 0.6.0
4
136
 
5
137
  ### Patch Changes
package/README.md CHANGED
@@ -53,15 +53,16 @@ switch layout automatically at viewport breakpoints.
53
53
 
54
54
  ### Properties
55
55
 
56
- | Property | Attribute | Type | Default | Description |
57
- | ----------------- | ----------------- | ------------------------------ | ------------------- | ----------------------------------------------------------------------------- |
58
- | `multiple` | `multiple` | `boolean` | `false` | Allows multiple highlighted rows in each listbox. |
59
- | `compact` | `compact` | `boolean` | `false` | Stacks the panels and action toolbar into a compact one-column layout. |
60
- | `availableLabel` | `available-label` | `string` | `'Available'` | Visible label for the available list. |
61
- | `selectedLabel` | `selected-label` | `string` | `'Selected'` | Visible label for the selected list. |
62
- | `available` | - | `ListboxOption[]` | native select state | Gets or replaces unselected options. |
63
- | `selected` | - | `ListboxOption[]` | native select state | Gets or replaces selected options. |
64
- | `defaultSelected` | - | `ListboxOption[] \| undefined` | `undefined` | Initial uncontrolled selected options, applied before host `selected` writes. |
56
+ | Property | Attribute | Type | Default | Description |
57
+ | ----------------- | ----------------- | --------------------------------- | ------------------- | ----------------------------------------------------------------------------- |
58
+ | `multiple` | `multiple` | `boolean` | `false` | Allows multiple highlighted rows in each listbox. |
59
+ | `compact` | `compact` | `boolean` | `false` | Stacks the panels and action toolbar into a compact one-column layout. |
60
+ | `availableLabel` | `available-label` | `string \| undefined` | `available` message | Visible label for the available list. |
61
+ | `selectedLabel` | `selected-label` | `string \| undefined` | `selected` message | Visible label for the selected list. |
62
+ | `messages` | - | `Partial<RCTransferListMessages>` | `undefined` | Built-in text overrides; see Localization. |
63
+ | `available` | - | `ListboxOption[]` | native select state | Gets or replaces unselected options. |
64
+ | `selected` | - | `ListboxOption[]` | native select state | Gets or replaces selected options. |
65
+ | `defaultSelected` | - | `ListboxOption[] \| undefined` | `undefined` | Initial uncontrolled selected options, applied before host `selected` writes. |
65
66
 
66
67
  ### Methods
67
68
 
@@ -81,6 +82,14 @@ switch layout automatically at viewport breakpoints.
81
82
 
82
83
  Host property writes to `available`, `selected`, or `defaultSelected` are silent.
83
84
 
85
+ ## Localization
86
+
87
+ Built-in text follows the element's own `lang`, else `<html lang>`, and never an
88
+ ancestor's `lang`, which usually marks content. Override it per element with the
89
+ `messages` property, or for every instance with `registerMessages()` from
90
+ `@rcarls/rc-common` under `rc-transfer-list`. Keys: `available`, `selected`, `actions`, `add`, `addAll`, `remove`, `clear`, `moveUp`, `moveDown`. The arrows on the action buttons are decorative and turn over in RTL. See the
91
+ [rc-common Localization section](https://github.com/richardcarls/rc-webcomponents/tree/develop/packages/rc-common#localization).
92
+
84
93
  ## Keyboard
85
94
 
86
95
  The embedded `rc-listbox` controls provide list navigation and selection. The
@@ -102,21 +111,22 @@ Panels expose `data-empty` when their backing list has no options and
102
111
  exposes `data-can-move-up` and `data-can-move-down` when the selected panel has
103
112
  highlighted rows that can be reordered in that direction.
104
113
 
105
- | CSS custom property | Default | Description |
106
- | ------------------------------------------- | ----------------------------------------------- | ------------------------------------------ |
107
- | `--rc-transfer-list-gap` | `var(--rc-control-gap, 0.75rem)` | Gap between panels and the action toolbar. |
108
- | `--rc-transfer-list-panel-gap` | `var(--rc-control-gap, 0.35rem)` | Gap between a panel label and its listbox. |
109
- | `--rc-transfer-list-listbox-min-block-size` | `10rem` | Minimum block size for each listbox. |
110
- | `--rc-transfer-list-listbox-border` | `var(--rc-border, 1px solid ButtonBorder)` | Border around each listbox. |
111
- | `--rc-transfer-list-listbox-bg` | `var(--rc-surface, Canvas)` | Background of each listbox. |
112
- | `--rc-transfer-list-listbox-color` | `var(--rc-field-text, FieldText)` | Text color of each listbox. |
113
- | `--rc-transfer-list-option-gap` | `var(--rc-item-gap, 0.4em)` | Gap between option adornments and labels. |
114
- | `--rc-transfer-list-option-padding-block` | `var(--rc-item-padding-block, 0.3em)` | Block padding for option rows. |
115
- | `--rc-transfer-list-option-padding-inline` | `var(--rc-item-padding-inline, 0.75em)` | Inline padding for option rows. |
116
- | `--rc-transfer-list-option-selected-bg` | `var(--rc-highlight, Highlight)` | Selected option background. |
117
- | `--rc-transfer-list-option-selected-color` | `var(--rc-highlight-text, HighlightText)` | Selected option foreground. |
118
- | `--rc-transfer-list-option-hover-bg` | `var(--rc-transfer-list-option-selected-bg)` | Hovered/active option background. |
119
- | `--rc-transfer-list-option-hover-color` | `var(--rc-transfer-list-option-selected-color)` | Hovered/active option foreground. |
114
+ | CSS custom property | Default | Description |
115
+ | ------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------ |
116
+ | `--rc-transfer-list-gap` | `var(--rc-control-gap, 0.75rem)` | Gap between panels and the action toolbar. |
117
+ | `--rc-transfer-list-panel-gap` | `var(--rc-control-gap, 0.35rem)` | Gap between a panel label and its listbox. |
118
+ | `--rc-transfer-list-listbox-min-block-size` | `10rem` | Minimum block size for each listbox. |
119
+ | `--rc-transfer-list-listbox-border` | `var(--rc-border, 1px solid ButtonBorder)` | Border around each listbox. |
120
+ | `--rc-transfer-list-listbox-radius` | `var(--rc-control-radius, 0.125rem)` | Corner radius of each listbox. |
121
+ | `--rc-transfer-list-listbox-bg` | `var(--rc-surface, Canvas)` | Background of each listbox. |
122
+ | `--rc-transfer-list-listbox-color` | `var(--rc-field-text, FieldText)` | Text color of each listbox. |
123
+ | `--rc-transfer-list-option-gap` | `var(--rc-item-gap, 0.4em)` | Gap between option adornments and labels. |
124
+ | `--rc-transfer-list-option-padding-block` | `var(--rc-item-padding-block, 0.3em)` | Block padding for option rows. |
125
+ | `--rc-transfer-list-option-padding-inline` | `var(--rc-item-padding-inline, 0.75em)` | Inline padding for option rows. |
126
+ | `--rc-transfer-list-option-selected-bg` | `var(--rc-highlight, Highlight)` | Selected option background. |
127
+ | `--rc-transfer-list-option-selected-color` | `var(--rc-highlight-text, HighlightText)` | Selected option foreground. |
128
+ | `--rc-transfer-list-option-hover-bg` | `var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))` | Hovered/active option background. |
129
+ | `--rc-transfer-list-option-hover-color` | `var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))` | Hovered/active option foreground. |
120
130
 
121
131
  | Part | Description |
122
132
  | ------------------- | -------------------------------------------------------------- |
@@ -44,6 +44,13 @@
44
44
  "kind": "javascript-module",
45
45
  "path": "src/rc-transfer-list.ts",
46
46
  "declarations": [
47
+ {
48
+ "kind": "variable",
49
+ "name": "DEFAULT_TRANSFER_LIST_MESSAGES",
50
+ "type": {
51
+ "text": "Readonly<RCTransferListMessages>"
52
+ }
53
+ },
47
54
  {
48
55
  "kind": "class",
49
56
  "description": "Transfer list that enhances a native <select multiple> into available and selected\npanes.\n\nThe component renders two listboxes and transfer/reorder actions in between.\nAvailable options are on the left, and selected options appear on the right. It\nis an older enterprise/admin UI pattern, but solves the specific problem of\nmultiple selection within a large amount of options.\n\nThe `available` and `selected` JS array properties write through to the\nbacking `<select>`, so the component can also be driven imperatively from a\nframework without giving up form participation.",
@@ -52,12 +59,12 @@
52
59
  {
53
60
  "description": "Gap between panels and the action toolbar",
54
61
  "name": "--rc-transfer-list-gap",
55
- "default": "var(--rc-control-gap)"
62
+ "default": "var(--rc-control-gap, 0.75rem)"
56
63
  },
57
64
  {
58
65
  "description": "Gap between a panel label and its listbox",
59
66
  "name": "--rc-transfer-list-panel-gap",
60
- "default": "var(--rc-control-gap)"
67
+ "default": "var(--rc-control-gap, 0.35rem)"
61
68
  },
62
69
  {
63
70
  "description": "Minimum block size for each listbox",
@@ -67,52 +74,57 @@
67
74
  {
68
75
  "description": "Border around each listbox",
69
76
  "name": "--rc-transfer-list-listbox-border",
70
- "default": "var(--rc-border)"
77
+ "default": "var(--rc-border, 1px solid ButtonBorder)"
78
+ },
79
+ {
80
+ "description": "Corner radius of each listbox",
81
+ "name": "--rc-transfer-list-listbox-radius",
82
+ "default": "var(--rc-control-radius, 0.125rem)"
71
83
  },
72
84
  {
73
85
  "description": "Background of each listbox",
74
86
  "name": "--rc-transfer-list-listbox-bg",
75
- "default": "var(--rc-surface)"
87
+ "default": "var(--rc-surface, Canvas)"
76
88
  },
77
89
  {
78
90
  "description": "Text color of each listbox",
79
91
  "name": "--rc-transfer-list-listbox-color",
80
- "default": "var(--rc-field-text)"
92
+ "default": "var(--rc-field-text, FieldText)"
81
93
  },
82
94
  {
83
95
  "description": "Gap between option adornments and labels",
84
96
  "name": "--rc-transfer-list-option-gap",
85
- "default": "var(--rc-item-gap)"
97
+ "default": "var(--rc-item-gap, 0.4em)"
86
98
  },
87
99
  {
88
100
  "description": "Block padding for option rows",
89
101
  "name": "--rc-transfer-list-option-padding-block",
90
- "default": "var(--rc-item-padding-block)"
102
+ "default": "var(--rc-item-padding-block, 0.3em)"
91
103
  },
92
104
  {
93
105
  "description": "Inline padding for option rows",
94
106
  "name": "--rc-transfer-list-option-padding-inline",
95
- "default": "var(--rc-item-padding-inline)"
107
+ "default": "var(--rc-item-padding-inline, 0.75em)"
96
108
  },
97
109
  {
98
110
  "description": "Selected option background",
99
111
  "name": "--rc-transfer-list-option-selected-bg",
100
- "default": "var(--rc-highlight)"
112
+ "default": "var(--rc-highlight, Highlight)"
101
113
  },
102
114
  {
103
115
  "description": "Selected option foreground",
104
116
  "name": "--rc-transfer-list-option-selected-color",
105
- "default": "var(--rc-highlight-text)"
117
+ "default": "var(--rc-highlight-text, HighlightText)"
106
118
  },
107
119
  {
108
120
  "description": "Hovered/active option background",
109
121
  "name": "--rc-transfer-list-option-hover-bg",
110
- "default": "var(--rc-transfer-list-option-selected-bg)"
122
+ "default": "var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))"
111
123
  },
112
124
  {
113
125
  "description": "Hovered/active option foreground",
114
126
  "name": "--rc-transfer-list-option-hover-color",
115
- "default": "var(--rc-transfer-list-option-selected-color)"
127
+ "default": "var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))"
116
128
  }
117
129
  ],
118
130
  "cssParts": [
@@ -216,22 +228,35 @@
216
228
  "kind": "field",
217
229
  "name": "availableLabel",
218
230
  "type": {
219
- "text": "string"
231
+ "text": "string | undefined"
220
232
  },
221
- "default": "'Available'",
222
- "description": "Visible label for the available list.",
233
+ "description": "Visible label for the available list. Defaults to the `available` message.",
223
234
  "attribute": "available-label"
224
235
  },
225
236
  {
226
237
  "kind": "field",
227
238
  "name": "selectedLabel",
228
239
  "type": {
229
- "text": "string"
240
+ "text": "string | undefined"
230
241
  },
231
- "default": "'Selected'",
232
- "description": "Visible label for the selected list.",
242
+ "description": "Visible label for the selected list. Defaults to the `selected` message.",
233
243
  "attribute": "selected-label"
234
244
  },
245
+ {
246
+ "kind": "field",
247
+ "name": "messages",
248
+ "type": {
249
+ "text": "Partial<RCTransferListMessages> | undefined"
250
+ },
251
+ "description": "Built-in text overrides; unset keys fall back to registered text, then English."
252
+ },
253
+ {
254
+ "kind": "field",
255
+ "name": "_messages",
256
+ "privacy": "private",
257
+ "readonly": true,
258
+ "default": "new MessagesController( this, 'rc-transfer-list', DEFAULT_TRANSFER_LIST_MESSAGES, { overrides: () => this.messages }, )"
259
+ },
235
260
  {
236
261
  "kind": "field",
237
262
  "name": "_$availableList",
@@ -600,21 +625,19 @@
600
625
  "fieldName": "compact"
601
626
  },
602
627
  {
603
- "description": "Visible label for the available list.",
628
+ "description": "Visible label for the available list. Defaults to the `available` message.",
604
629
  "name": "available-label",
605
630
  "type": {
606
- "text": "string"
631
+ "text": "string | undefined"
607
632
  },
608
- "default": "'Available'",
609
633
  "fieldName": "availableLabel"
610
634
  },
611
635
  {
612
- "description": "Visible label for the selected list.",
636
+ "description": "Visible label for the selected list. Defaults to the `selected` message.",
613
637
  "name": "selected-label",
614
638
  "type": {
615
- "text": "string"
639
+ "text": "string | undefined"
616
640
  },
617
- "default": "'Selected'",
618
641
  "fieldName": "selectedLabel"
619
642
  }
620
643
  ],
@@ -627,6 +650,14 @@
627
650
  }
628
651
  ],
629
652
  "exports": [
653
+ {
654
+ "kind": "js",
655
+ "name": "DEFAULT_TRANSFER_LIST_MESSAGES",
656
+ "declaration": {
657
+ "name": "DEFAULT_TRANSFER_LIST_MESSAGES",
658
+ "module": "src/rc-transfer-list.ts"
659
+ }
660
+ },
630
661
  {
631
662
  "kind": "js",
632
663
  "name": "RCTransferList",
@@ -1,124 +1,32 @@
1
- import { css as _, LitElement as m, nothing as c, html as y } from "lit";
2
- import { property as p, query as f, state as v } from "lit/decorators.js";
3
- import { MutationObserverController as $, NativeChildController as x } from "@rcarls/rc-common";
1
+ import { css as m, LitElement as y, nothing as d, html as $ } from "lit";
2
+ import { property as p, query as f, state as g } from "lit/decorators.js";
3
+ import { MessagesController as S, MutationObserverController as x, arrowKeys as w, resolveFlow as A, NativeChildController as k } from "@rcarls/rc-common";
4
4
  import "@rcarls/rc-listbox/define";
5
5
  import "@rcarls/rc-toolbar/define";
6
- const S = _`
7
- :host {
8
- display: block;
9
- }
10
-
11
- :host([hidden]) {
12
- display: none;
13
- }
14
-
15
- #root {
16
- display: grid;
17
- grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
18
- align-items: stretch;
19
- gap: var(--rc-transfer-list-gap, var(--rc-control-gap, 0.75rem));
20
- }
21
-
22
- :host([compact]) #root {
23
- grid-template-columns: minmax(0, 1fr);
24
- }
25
-
26
- .rc-transfer-list-panel {
27
- display: flex;
28
- min-inline-size: 0;
29
- flex-direction: column;
30
- gap: var(--rc-transfer-list-panel-gap, var(--rc-control-gap, 0.35rem));
31
- }
32
-
33
- .rc-transfer-list-panel > rc-listbox {
34
- flex: 1 1 auto;
35
- min-block-size: var(--rc-transfer-list-listbox-min-block-size, 10rem);
36
- overflow: auto;
37
- border: var(--rc-transfer-list-listbox-border, var(--rc-border, 1px solid ButtonBorder));
38
- background: var(--rc-transfer-list-listbox-bg, var(--rc-surface, Canvas));
39
- color: var(--rc-transfer-list-listbox-color, var(--rc-field-text, FieldText));
40
- --rc-listbox-option-gap: var(--rc-transfer-list-option-gap, var(--rc-item-gap, 0.4em));
41
- --rc-listbox-option-padding-block: var(
42
- --rc-transfer-list-option-padding-block,
43
- var(--rc-item-padding-block, 0.3em)
44
- );
45
- --rc-listbox-option-padding-inline: var(
46
- --rc-transfer-list-option-padding-inline,
47
- var(--rc-item-padding-inline, 0.75em)
48
- );
49
- --rc-listbox-hover-bg: var(
50
- --rc-transfer-list-option-hover-bg,
51
- var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))
52
- );
53
- --rc-listbox-hover-color: var(
54
- --rc-transfer-list-option-hover-color,
55
- var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))
56
- );
57
- --rc-listbox-active-bg: var(
58
- --rc-transfer-list-option-hover-bg,
59
- var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))
60
- );
61
- --rc-listbox-active-color: var(
62
- --rc-transfer-list-option-hover-color,
63
- var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))
64
- );
65
- --rc-listbox-selected-bg: var(
66
- --rc-transfer-list-option-selected-bg,
67
- var(--rc-highlight, Highlight)
68
- );
69
- --rc-listbox-selected-color: var(
70
- --rc-transfer-list-option-selected-color,
71
- var(--rc-highlight-text, HighlightText)
72
- );
73
- --rc-listbox-disabled-opacity: var(--rc-disabled-opacity, 0.5);
74
- }
75
-
76
- rc-listbox [part~='option'][hidden] {
77
- display: none;
78
- }
79
-
80
- rc-listbox [part~='option'][data-active]:not([aria-disabled='true']) {
81
- outline: var(--rc-focus-ring, 2px solid var(--rc-accent, Highlight));
82
- outline-offset: -2px;
83
- }
84
-
85
- rc-listbox [part~='option'][aria-disabled='true'] {
86
- cursor: not-allowed;
87
- }
88
-
89
- #actions {
90
- align-self: center;
91
- transform: translateY(
92
- calc((1lh + var(--rc-transfer-list-panel-gap, var(--rc-control-gap, 0.35rem))) / 2)
93
- );
94
- }
95
-
96
- :host([compact]) #actions {
97
- align-self: stretch;
98
- transform: none;
99
- }
100
-
101
- :host([compact]) #actions::part(root) {
102
- flex-wrap: wrap;
103
- justify-content: center;
104
- }
105
-
106
- #actions button {
107
- white-space: nowrap;
108
- }
109
-
110
- slot:not([name]) {
111
- display: none;
112
- }
113
- `;
114
- var w = Object.defineProperty, n = (u, e, t, s) => {
115
- for (var l = void 0, i = u.length - 1, r; i >= 0; i--)
116
- (r = u[i]) && (l = r(e, t, l) || l);
117
- return l && w(e, t, l), l;
6
+ const C = m`:host{display:block}:host([hidden]){display:none}#root{align-items:stretch;gap:var(--rc-transfer-list-gap,var(--rc-control-gap,.75rem));grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);display:grid}:host([compact]) #root{grid-template-columns:minmax(0,1fr)}.rc-transfer-list-panel{gap:var(--rc-transfer-list-panel-gap,var(--rc-control-gap,.35rem));flex-direction:column;min-inline-size:0;display:flex}.rc-transfer-list-panel>rc-listbox{min-block-size:var(--rc-transfer-list-listbox-min-block-size,10rem);border:var(--rc-transfer-list-listbox-border,var(--rc-border,1px solid ButtonBorder));border-radius:var(--rc-transfer-list-listbox-radius,var(--rc-control-radius,.125rem));background:var(--rc-transfer-list-listbox-bg,var(--rc-surface,Canvas));color:var(--rc-transfer-list-listbox-color,var(--rc-field-text,FieldText));--rc-listbox-option-gap:var(--rc-transfer-list-option-gap,var(--rc-item-gap,.4em));--rc-listbox-option-padding-block:var(--rc-transfer-list-option-padding-block,var(--rc-item-padding-block,.3em));--rc-listbox-option-padding-inline:var(--rc-transfer-list-option-padding-inline,var(--rc-item-padding-inline,.75em));--rc-listbox-hover-bg:var(--rc-transfer-list-option-hover-bg,var(--rc-transfer-list-option-selected-bg,var(--rc-highlight,Highlight)));--rc-listbox-hover-color:var(--rc-transfer-list-option-hover-color,var(--rc-transfer-list-option-selected-color,var(--rc-highlight-text,HighlightText)));--rc-listbox-active-bg:var(--rc-transfer-list-option-hover-bg,var(--rc-transfer-list-option-selected-bg,var(--rc-highlight,Highlight)));--rc-listbox-active-color:var(--rc-transfer-list-option-hover-color,var(--rc-transfer-list-option-selected-color,var(--rc-highlight-text,HighlightText)));--rc-listbox-selected-bg:var(--rc-transfer-list-option-selected-bg,var(--rc-highlight,Highlight));--rc-listbox-selected-color:var(--rc-transfer-list-option-selected-color,var(--rc-highlight-text,HighlightText));--rc-listbox-disabled-opacity:var(--rc-disabled-opacity,.5);flex:auto;overflow:auto}rc-listbox [part~=option][hidden]{display:none}rc-listbox [part~=option][data-active]:not([aria-disabled=true]){outline:var(--rc-focus-ring,2px solid var(--rc-accent,Highlight));outline-offset:-2px}rc-listbox [part~=option][aria-disabled=true]{cursor:not-allowed}#actions{transform:translateY(calc((1lh + var(--rc-transfer-list-panel-gap,var(--rc-control-gap,.35rem))) / 2));align-self:center}:host([compact]) #actions{align-self:stretch;transform:none}:host([compact]) #actions::part(root){flex-wrap:wrap;justify-content:center}#actions button{white-space:nowrap}.arrow:dir(rtl){display:inline-block;transform:scaleX(-1)}slot:not([name]){display:none}`;
7
+ var D = Object.defineProperty, c = (v, e, t, s) => {
8
+ for (var l = void 0, i = v.length - 1, r; i >= 0; i--)
9
+ (r = v[i]) && (l = r(e, t, l) || l);
10
+ return l && D(e, t, l), l;
118
11
  };
119
- const b = class b extends m {
12
+ const L = Object.freeze({
13
+ available: "Available",
14
+ selected: "Selected",
15
+ actions: "Transfer actions",
16
+ add: "Add",
17
+ addAll: "Add all",
18
+ remove: "Remove",
19
+ clear: "Clear",
20
+ moveUp: "Move up",
21
+ moveDown: "Move down"
22
+ }), u = class u extends y {
120
23
  constructor() {
121
- super(), this.multiple = !1, this.compact = !1, this.availableLabel = "Available", this.selectedLabel = "Selected", this._availableSelection = [], this._selectedSelection = [], this._$select = null, this._syncing = !1, this._selectedInitialized = !1, this._selectObserver = new $(this, {
24
+ super(), this.multiple = !1, this.compact = !1, this._messages = new S(
25
+ this,
26
+ "rc-transfer-list",
27
+ L,
28
+ { overrides: () => this.messages }
29
+ ), this._availableSelection = [], this._selectedSelection = [], this._$select = null, this._syncing = !1, this._selectedInitialized = !1, this._selectObserver = new x(this, {
122
30
  target: null,
123
31
  disabled: !0,
124
32
  callback: () => {
@@ -130,11 +38,12 @@ const b = class b extends m {
130
38
  this.moveSelected(1);
131
39
  }, this._onKeydown = (e) => {
132
40
  if (e.altKey) {
41
+ const s = w("horizontal", A(this));
133
42
  switch (e.key) {
134
- case "ArrowRight":
43
+ case s.next:
135
44
  e.preventDefault(), this.addSelected();
136
45
  break;
137
- case "ArrowLeft":
46
+ case s.prev:
138
47
  e.preventDefault(), this.removeSelected();
139
48
  break;
140
49
  case "ArrowUp":
@@ -160,7 +69,7 @@ const b = class b extends m {
160
69
  }
161
70
  const s = t.detail.value, l = Array.isArray(s) ? s : s ? [s] : [], i = e.currentTarget?.id;
162
71
  i === "available-list" ? this._availableSelection = l : i === "selected-list" && (this._selectedSelection = l);
163
- }, new x(this, {
72
+ }, new k(this, {
164
73
  selector: ":scope > select[multiple]",
165
74
  observe: !0,
166
75
  onChange: (e) => this._setupSelect(e),
@@ -229,24 +138,26 @@ const b = class b extends m {
229
138
  super.disconnectedCallback(), this._teardownSelect();
230
139
  }
231
140
  render() {
232
- const e = this.available, t = this.selected, s = new Set(this._selectedSelection), l = e.length === 0, i = t.length === 0, r = t.length < 2, h = this._availableSelection.length === 0, a = this._selectedSelection.length === 0, d = this._canMoveSelected(t, s, -1), g = this._canMoveSelected(t, s, 1);
233
- return y`
141
+ const e = this.available, t = this.selected, s = new Set(this._selectedSelection), l = e.length === 0, i = t.length === 0, r = t.length < 2, b = this._availableSelection.length === 0, a = this._selectedSelection.length === 0, h = this._canMoveSelected(t, s, -1), _ = this._canMoveSelected(t, s, 1), n = this._messages.value;
142
+ return $`
234
143
  <div
235
144
  id="root"
236
145
  part="root"
237
146
  class="rc-transfer-list-root"
238
- data-can-move-up=${d ? "" : c}
239
- data-can-move-down=${g ? "" : c}
147
+ data-can-move-up=${h ? "" : d}
148
+ data-can-move-down=${_ ? "" : d}
240
149
  @keydown=${this._onKeydown}
241
150
  >
242
151
  <section
243
152
  part="panel available-panel"
244
153
  class="rc-transfer-list-panel"
245
154
  aria-labelledby="available-label"
246
- data-empty=${l ? "" : c}
247
- data-has-selection=${h ? c : ""}
155
+ data-empty=${l ? "" : d}
156
+ data-has-selection=${b ? d : ""}
248
157
  >
249
- <span part="label available-label" id="available-label">${this.availableLabel}</span>
158
+ <span part="label available-label" id="available-label"
159
+ >${this.availableLabel ?? n.available}</span
160
+ >
250
161
  <rc-listbox
251
162
  id="available-list"
252
163
  part="listbox available-listbox"
@@ -261,17 +172,17 @@ const b = class b extends m {
261
172
  <rc-toolbar
262
173
  id="actions"
263
174
  orientation=${this.compact ? "horizontal" : "vertical"}
264
- label="Transfer actions"
175
+ label=${n.actions}
265
176
  part="actions"
266
177
  class="rc-transfer-list-actions"
267
178
  >
268
179
  <button
269
180
  type="button"
270
181
  part="button add-button"
271
- ?disabled=${l || h}
182
+ ?disabled=${l || b}
272
183
  @click=${this.addSelected}
273
184
  >
274
- Add &#x2192;
185
+ ${n.add} <span class="arrow" aria-hidden="true">&#x2192;</span>
275
186
  </button>
276
187
 
277
188
  <button
@@ -280,7 +191,7 @@ const b = class b extends m {
280
191
  ?disabled=${l}
281
192
  @click=${this.addAll}
282
193
  >
283
- Add all &#x2192;
194
+ ${n.addAll} <span class="arrow" aria-hidden="true">&#x2192;</span>
284
195
  </button>
285
196
 
286
197
  <button
@@ -289,7 +200,7 @@ const b = class b extends m {
289
200
  ?disabled=${i || a}
290
201
  @click=${this.removeSelected}
291
202
  >
292
- &#x2190; Remove
203
+ <span class="arrow" aria-hidden="true">&#x2190;</span> ${n.remove}
293
204
  </button>
294
205
 
295
206
  <button
@@ -298,7 +209,7 @@ const b = class b extends m {
298
209
  ?disabled=${i}
299
210
  @click=${this.clearSelected}
300
211
  >
301
- &#x2190; Clear
212
+ <span class="arrow" aria-hidden="true">&#x2190;</span> ${n.clear}
302
213
  </button>
303
214
 
304
215
  <button
@@ -307,7 +218,7 @@ const b = class b extends m {
307
218
  ?disabled=${r || a}
308
219
  @click=${this._onMoveUp}
309
220
  >
310
- Move up
221
+ ${n.moveUp}
311
222
  </button>
312
223
 
313
224
  <button
@@ -316,7 +227,7 @@ const b = class b extends m {
316
227
  ?disabled=${r || a}
317
228
  @click=${this._onMoveDown}
318
229
  >
319
- Move down
230
+ ${n.moveDown}
320
231
  </button>
321
232
  </rc-toolbar>
322
233
 
@@ -324,10 +235,12 @@ const b = class b extends m {
324
235
  part="panel selected-panel"
325
236
  class="rc-transfer-list-panel"
326
237
  aria-labelledby="selected-label"
327
- data-empty=${i ? "" : c}
328
- data-has-selection=${a ? c : ""}
238
+ data-empty=${i ? "" : d}
239
+ data-has-selection=${a ? d : ""}
329
240
  >
330
- <span part="label selected-label" id="selected-label">${this.selectedLabel}</span>
241
+ <span part="label selected-label" id="selected-label"
242
+ >${this.selectedLabel ?? n.selected}</span
243
+ >
331
244
 
332
245
  <rc-listbox
333
246
  id="selected-list"
@@ -420,10 +333,13 @@ const b = class b extends m {
420
333
  * preserve user-determined order in form serialisation.
421
334
  */
422
335
  _reorderSelectOptions(e, t) {
423
- const s = this._$select, l = Array.from(s.options).filter((a) => a.selected), i = t < 0 ? 1 : l.length - 2, r = t < 0 ? l.length : -1, h = t < 0 ? 1 : -1;
424
- for (let a = i; a !== r; a += h) {
425
- const d = a + t;
426
- !e.has(l[a].value) || e.has(l[d].value) || (t < 0 ? s.insertBefore(l[a], l[d]) : l[d].insertAdjacentElement("afterend", l[a]));
336
+ const s = this._$select;
337
+ if (!s)
338
+ return;
339
+ const l = Array.from(s.options).filter((a) => a.selected), i = t < 0 ? 1 : l.length - 2, r = t < 0 ? l.length : -1, b = t < 0 ? 1 : -1;
340
+ for (let a = i; a !== r; a += b) {
341
+ const h = a + t;
342
+ !e.has(l[a].value) || e.has(l[h].value) || (t < 0 ? s.insertBefore(l[a], l[h]) : l[h].insertAdjacentElement("afterend", l[a]));
427
343
  }
428
344
  }
429
345
  // Restores selection in the selected listbox after a mutation. Options are
@@ -443,33 +359,37 @@ const b = class b extends m {
443
359
  });
444
360
  }
445
361
  };
446
- b.styles = S;
447
- let o = b;
448
- n([
362
+ u.styles = C;
363
+ let o = u;
364
+ c([
449
365
  p({ type: Boolean, reflect: !0 })
450
366
  ], o.prototype, "multiple");
451
- n([
367
+ c([
452
368
  p({ type: Boolean, reflect: !0 })
453
369
  ], o.prototype, "compact");
454
- n([
370
+ c([
455
371
  p({ attribute: "available-label" })
456
372
  ], o.prototype, "availableLabel");
457
- n([
373
+ c([
458
374
  p({ attribute: "selected-label" })
459
375
  ], o.prototype, "selectedLabel");
460
- n([
376
+ c([
377
+ p({ attribute: !1 })
378
+ ], o.prototype, "messages");
379
+ c([
461
380
  f("#available-list")
462
381
  ], o.prototype, "_$availableList");
463
- n([
382
+ c([
464
383
  f("#selected-list")
465
384
  ], o.prototype, "_$selectedList");
466
- n([
467
- v()
385
+ c([
386
+ g()
468
387
  ], o.prototype, "_availableSelection");
469
- n([
470
- v()
388
+ c([
389
+ g()
471
390
  ], o.prototype, "_selectedSelection");
472
391
  export {
392
+ L as D,
473
393
  o as R
474
394
  };
475
- //# sourceMappingURL=rc-transfer-list-DFPxuGJ2.js.map
395
+ //# sourceMappingURL=rc-transfer-list-CYvAsEi5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-transfer-list-CYvAsEi5.js","sources":["../src/rc-transfer-list.styles.ts","../src/rc-transfer-list.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const transferListStyles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n #root {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);\n align-items: stretch;\n gap: var(--rc-transfer-list-gap, var(--rc-control-gap, 0.75rem));\n }\n\n :host([compact]) #root {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .rc-transfer-list-panel {\n display: flex;\n min-inline-size: 0;\n flex-direction: column;\n gap: var(--rc-transfer-list-panel-gap, var(--rc-control-gap, 0.35rem));\n }\n\n .rc-transfer-list-panel > rc-listbox {\n flex: 1 1 auto;\n min-block-size: var(--rc-transfer-list-listbox-min-block-size, 10rem);\n overflow: auto;\n border: var(--rc-transfer-list-listbox-border, var(--rc-border, 1px solid ButtonBorder));\n border-radius: var(--rc-transfer-list-listbox-radius, var(--rc-control-radius, 0.125rem));\n background: var(--rc-transfer-list-listbox-bg, var(--rc-surface, Canvas));\n color: var(--rc-transfer-list-listbox-color, var(--rc-field-text, FieldText));\n --rc-listbox-option-gap: var(--rc-transfer-list-option-gap, var(--rc-item-gap, 0.4em));\n --rc-listbox-option-padding-block: var(\n --rc-transfer-list-option-padding-block,\n var(--rc-item-padding-block, 0.3em)\n );\n --rc-listbox-option-padding-inline: var(\n --rc-transfer-list-option-padding-inline,\n var(--rc-item-padding-inline, 0.75em)\n );\n --rc-listbox-hover-bg: var(\n --rc-transfer-list-option-hover-bg,\n var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))\n );\n --rc-listbox-hover-color: var(\n --rc-transfer-list-option-hover-color,\n var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))\n );\n --rc-listbox-active-bg: var(\n --rc-transfer-list-option-hover-bg,\n var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))\n );\n --rc-listbox-active-color: var(\n --rc-transfer-list-option-hover-color,\n var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))\n );\n --rc-listbox-selected-bg: var(\n --rc-transfer-list-option-selected-bg,\n var(--rc-highlight, Highlight)\n );\n --rc-listbox-selected-color: var(\n --rc-transfer-list-option-selected-color,\n var(--rc-highlight-text, HighlightText)\n );\n --rc-listbox-disabled-opacity: var(--rc-disabled-opacity, 0.5);\n }\n\n rc-listbox [part~='option'][hidden] {\n display: none;\n }\n\n rc-listbox [part~='option'][data-active]:not([aria-disabled='true']) {\n outline: var(--rc-focus-ring, 2px solid var(--rc-accent, Highlight));\n outline-offset: -2px;\n }\n\n rc-listbox [part~='option'][aria-disabled='true'] {\n cursor: not-allowed;\n }\n\n #actions {\n align-self: center;\n transform: translateY(\n calc((1lh + var(--rc-transfer-list-panel-gap, var(--rc-control-gap, 0.35rem))) / 2)\n );\n }\n\n :host([compact]) #actions {\n align-self: stretch;\n transform: none;\n }\n\n :host([compact]) #actions::part(root) {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n #actions button {\n white-space: nowrap;\n }\n\n /* The arrows point along the inline axis, so they turn over in RTL. */\n .arrow:dir(rtl) {\n display: inline-block;\n transform: scaleX(-1);\n }\n\n slot:not([name]) {\n display: none;\n }\n`;\n\nexport default transferListStyles;\n","import { LitElement, html, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\n\nimport {\n arrowKeys,\n MessagesController,\n MutationObserverController,\n NativeChildController,\n resolveFlow,\n warnMissingDirectChild,\n} from '@rcarls/rc-common';\nimport type { ListboxOption, RCListbox, RCListboxChangeEvent } from '@rcarls/rc-listbox';\nimport '@rcarls/rc-listbox/define';\nimport '@rcarls/rc-toolbar/define';\n\nimport { transferListStyles } from './rc-transfer-list.styles.js';\n\n/** Built-in text of `rc-transfer-list`. */\nexport interface RCTransferListMessages {\n /** Default label of the available list, when `available-label` is unset. */\n available: string;\n /** Default label of the selected list, when `selected-label` is unset. */\n selected: string;\n /** Accessible name of the action toolbar. */\n actions: string;\n add: string;\n addAll: string;\n remove: string;\n clear: string;\n moveUp: string;\n moveDown: string;\n}\n\nexport const DEFAULT_TRANSFER_LIST_MESSAGES: Readonly<RCTransferListMessages> = Object.freeze({\n available: 'Available',\n selected: 'Selected',\n actions: 'Transfer actions',\n add: 'Add',\n addAll: 'Add all',\n remove: 'Remove',\n clear: 'Clear',\n moveUp: 'Move up',\n moveDown: 'Move down',\n});\n\ndeclare module '@rcarls/rc-common' {\n interface RcMessageCatalog {\n 'rc-transfer-list': RCTransferListMessages;\n }\n}\n\nexport interface RCTransferListChangeEvent {\n /** Ordered selected/right-hand list options. */\n selected: ListboxOption[];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-transfer-list': RCTransferList;\n }\n}\n\n/**\n * Transfer list that enhances a native <select multiple> into available and selected\n * panes.\n *\n * The component renders two listboxes and transfer/reorder actions in between.\n * Available options are on the left, and selected options appear on the right. It\n * is an older enterprise/admin UI pattern, but solves the specific problem of\n * multiple selection within a large amount of options.\n *\n * The `available` and `selected` JS array properties write through to the\n * backing `<select>`, so the component can also be driven imperatively from a\n * framework without giving up form participation.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-transfer-list rc-transfer-list docs}\n *\n * Built-in text (action buttons, default list labels) follows the element's\n * own `lang`, else `<html lang>`: per element through `messages`, or for\n * every transfer list through `registerMessages()` from `@rcarls/rc-common`\n * under `rc-transfer-list`. The direction arrows on the action buttons are\n * decorative and turn with the inline direction.\n *\n * @fires rc-transfer-list-change - Fires when the selected/right-hand list changes.\n *\n * @attr multiple - Enable multi-selection in both lists.\n * @attr compact - Stack the panels and action toolbar into a compact one-column layout.\n * @attr available-label - Visible label for the available list. Defaults to the `available` message.\n * @attr selected-label - Visible label for the selected list. Defaults to the `selected` message.\n *\n * @cssprop [--rc-transfer-list-gap=var(--rc-control-gap, 0.75rem)] - Gap between panels and the action toolbar\n * @cssprop [--rc-transfer-list-panel-gap=var(--rc-control-gap, 0.35rem)] - Gap between a panel label and its listbox\n * @cssprop [--rc-transfer-list-listbox-min-block-size=10rem] - Minimum block size for each listbox\n * @cssprop [--rc-transfer-list-listbox-border=var(--rc-border, 1px solid ButtonBorder)] - Border around each listbox\n * @cssprop [--rc-transfer-list-listbox-radius=var(--rc-control-radius, 0.125rem)] - Corner radius of each listbox\n * @cssprop [--rc-transfer-list-listbox-bg=var(--rc-surface, Canvas)] - Background of each listbox\n * @cssprop [--rc-transfer-list-listbox-color=var(--rc-field-text, FieldText)] - Text color of each listbox\n * @cssprop [--rc-transfer-list-option-gap=var(--rc-item-gap, 0.4em)] - Gap between option adornments and labels\n * @cssprop [--rc-transfer-list-option-padding-block=var(--rc-item-padding-block, 0.3em)] - Block padding for option rows\n * @cssprop [--rc-transfer-list-option-padding-inline=var(--rc-item-padding-inline, 0.75em)] - Inline padding for option rows\n * @cssprop [--rc-transfer-list-option-selected-bg=var(--rc-highlight, Highlight)] - Selected option background\n * @cssprop [--rc-transfer-list-option-selected-color=var(--rc-highlight-text, HighlightText)] - Selected option foreground\n * @cssprop [--rc-transfer-list-option-hover-bg=var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))] - Hovered/active option background\n * @cssprop [--rc-transfer-list-option-hover-color=var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))] - Hovered/active option foreground\n *\n * @csspart root - Root layout wrapper. Reflects data-can-move-up/down.\n * @csspart panel - Shared list panel surface.\n * @csspart available-panel - Available/left panel. Reflects data-empty and data-has-selection.\n * @csspart selected-panel - Selected/right panel. Reflects data-empty and data-has-selection.\n * @csspart label - Shared panel label surface.\n * @csspart available-label - Label for the available panel.\n * @csspart selected-label - Label for the selected panel.\n * @csspart listbox - Shared listbox surface.\n * @csspart available-listbox - The available/left `rc-listbox`.\n * @csspart selected-listbox - The selected/right `rc-listbox`.\n * @csspart actions - Transfer action toolbar.\n * @csspart button - Shared action button surface.\n * @csspart add-button - Moves highlighted available options to the selected list.\n * @csspart add-all-button - Moves every available option to the selected list.\n * @csspart remove-button - Moves highlighted selected options back to the available list.\n * @csspart clear-button - Moves every selected option back to the available list.\n * @csspart move-up-button - Moves highlighted selected options up.\n * @csspart move-down-button - Moves highlighted selected options down.\n */\nexport class RCTransferList extends LitElement {\n static override styles = transferListStyles;\n\n /** Enable multi-selection in both lists. */\n @property({ type: Boolean, reflect: true })\n multiple = false;\n\n /** Stack the panels and action toolbar into a compact one-column layout. */\n @property({ type: Boolean, reflect: true })\n compact = false;\n\n /** Visible label for the available list. Defaults to the `available` message. */\n @property({ attribute: 'available-label' })\n availableLabel: string | undefined;\n\n /** Visible label for the selected list. Defaults to the `selected` message. */\n @property({ attribute: 'selected-label' })\n selectedLabel: string | undefined;\n\n /** Built-in text overrides; unset keys fall back to registered text, then English. */\n @property({ attribute: false })\n messages: Partial<RCTransferListMessages> | undefined;\n\n private readonly _messages = new MessagesController(\n this,\n 'rc-transfer-list',\n DEFAULT_TRANSFER_LIST_MESSAGES,\n { overrides: () => this.messages },\n );\n\n @query('#available-list')\n private _$availableList?: RCListbox;\n\n @query('#selected-list')\n private _$selectedList?: RCListbox;\n\n /** Values currently highlighted in the available list. Drives the \"Add →\" button disable state. */\n @state()\n private _availableSelection: string[] = [];\n\n /** Values currently highlighted in the selected list. Drives Remove/reorder button disable states. */\n @state()\n private _selectedSelection: string[] = [];\n\n private _$select: HTMLSelectElement | null = null;\n\n /** Set while the component mutates the backing <select> to prevent observer feedback loops. */\n private _syncing = false;\n\n private _defaultSelected: ListboxOption[] | undefined;\n\n private _selectedInitialized = false;\n\n private readonly _selectObserver = new MutationObserverController(this, {\n target: null,\n disabled: true,\n callback: () => {\n if (!this._syncing) {\n this.requestUpdate();\n }\n },\n });\n\n constructor() {\n super();\n\n new NativeChildController<HTMLSelectElement>(this, {\n selector: ':scope > select[multiple]',\n observe: true,\n onChange: ($select) => this._setupSelect($select),\n onMissing: () => {\n if (import.meta.env.DEV) {\n warnMissingDirectChild(this, {\n selector: ':scope > select[multiple]',\n message:\n '[rc-transfer-list] No direct child <select multiple> found. ' +\n 'Add a <select multiple> child for form participation and progressive enhancement.',\n });\n }\n },\n });\n }\n\n /**\n * Available/left-hand options derived from unselected `<option>` elements.\n *\n * Setting this property replaces all unselected options in the backing\n * `<select>`. Items whose values already appear in the selected list are\n * skipped to prevent duplicate option values.\n */\n get available(): ListboxOption[] {\n if (!this._$select) {\n return [];\n }\n\n return Array.from(this._$select.options)\n .filter(($option) => !$option.selected)\n .map(($option) => ({ value: $option.value, label: $option.label || $option.text }));\n }\n\n set available(items: ListboxOption[]) {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n const selectedValues = new Set(\n Array.from(this._$select.options)\n .filter(($option) => $option.selected)\n .map(($option) => $option.value),\n );\n\n for (const $option of Array.from(this._$select.options)) {\n if (!$option.selected) {\n $option.remove();\n }\n }\n\n for (const item of items) {\n if (!selectedValues.has(item.value)) {\n this._$select.add(new Option(item.label, item.value));\n }\n }\n\n this._syncing = false;\n this.requestUpdate();\n }\n\n /**\n * Selected/right-hand options derived from selected `<option>` elements.\n *\n * Setting this property replaces all selected options in the backing\n * `<select>`. Unselected options are left unchanged.\n */\n get selected(): ListboxOption[] {\n if (!this._$select) {\n return [];\n }\n\n return Array.from(this._$select.options)\n .filter(($option) => $option.selected)\n .map(($option) => ({ value: $option.value, label: $option.label || $option.text }));\n }\n\n set selected(items: ListboxOption[]) {\n this._selectedInitialized = true;\n\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n if ($option.selected) {\n $option.remove();\n }\n }\n\n for (const item of items) {\n this._$select.add(new Option(item.label, item.value, false, true));\n }\n\n this._syncing = false;\n this.requestUpdate();\n }\n\n /** Initial uncontrolled selected list. Applied before any `selected` write from the host. */\n get defaultSelected(): ListboxOption[] | undefined {\n return this._defaultSelected;\n }\n\n set defaultSelected(items: ListboxOption[] | undefined) {\n this._defaultSelected = items;\n\n if (!this._selectedInitialized && this._$select && items !== undefined) {\n this._applyDefaultSelected(items);\n }\n }\n\n private _applyDefaultSelected(items: ListboxOption[]): void {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n $option.selected = items.some((item) => item.value === $option.value);\n }\n\n this._syncing = false;\n this.requestUpdate();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardownSelect();\n }\n\n override render() {\n const available = this.available; // reads <select> directly; requestUpdate() always precedes render\n const selected = this.selected;\n const selectedValues = new Set(this._selectedSelection);\n const noAvailable = available.length === 0;\n const noSelected = selected.length === 0;\n const cannotReorder = selected.length < 2;\n const noAvailableSelection = this._availableSelection.length === 0;\n const noSelectedSelection = this._selectedSelection.length === 0;\n const canMoveUp = this._canMoveSelected(selected, selectedValues, -1);\n const canMoveDown = this._canMoveSelected(selected, selectedValues, 1);\n const m = this._messages.value;\n\n return html`\n <div\n id=\"root\"\n part=\"root\"\n class=\"rc-transfer-list-root\"\n data-can-move-up=${canMoveUp ? '' : nothing}\n data-can-move-down=${canMoveDown ? '' : nothing}\n @keydown=${this._onKeydown}\n >\n <section\n part=\"panel available-panel\"\n class=\"rc-transfer-list-panel\"\n aria-labelledby=\"available-label\"\n data-empty=${noAvailable ? '' : nothing}\n data-has-selection=${!noAvailableSelection ? '' : nothing}\n >\n <span part=\"label available-label\" id=\"available-label\"\n >${this.availableLabel ?? m.available}</span\n >\n <rc-listbox\n id=\"available-list\"\n part=\"listbox available-listbox\"\n aria-labelledby=\"available-label\"\n tabindex=\"0\"\n .options=${available}\n .multiple=${this.multiple}\n @rc-listbox-change=${this._onListboxChange}\n ></rc-listbox>\n </section>\n\n <rc-toolbar\n id=\"actions\"\n orientation=${this.compact ? 'horizontal' : 'vertical'}\n label=${m.actions}\n part=\"actions\"\n class=\"rc-transfer-list-actions\"\n >\n <button\n type=\"button\"\n part=\"button add-button\"\n ?disabled=${noAvailable || noAvailableSelection}\n @click=${this.addSelected}\n >\n ${m.add} <span class=\"arrow\" aria-hidden=\"true\">&#x2192;</span>\n </button>\n\n <button\n type=\"button\"\n part=\"button add-all-button\"\n ?disabled=${noAvailable}\n @click=${this.addAll}\n >\n ${m.addAll} <span class=\"arrow\" aria-hidden=\"true\">&#x2192;</span>\n </button>\n\n <button\n type=\"button\"\n part=\"button remove-button\"\n ?disabled=${noSelected || noSelectedSelection}\n @click=${this.removeSelected}\n >\n <span class=\"arrow\" aria-hidden=\"true\">&#x2190;</span> ${m.remove}\n </button>\n\n <button\n type=\"button\"\n part=\"button clear-button\"\n ?disabled=${noSelected}\n @click=${this.clearSelected}\n >\n <span class=\"arrow\" aria-hidden=\"true\">&#x2190;</span> ${m.clear}\n </button>\n\n <button\n type=\"button\"\n part=\"button move-up-button\"\n ?disabled=${cannotReorder || noSelectedSelection}\n @click=${this._onMoveUp}\n >\n ${m.moveUp}\n </button>\n\n <button\n type=\"button\"\n part=\"button move-down-button\"\n ?disabled=${cannotReorder || noSelectedSelection}\n @click=${this._onMoveDown}\n >\n ${m.moveDown}\n </button>\n </rc-toolbar>\n\n <section\n part=\"panel selected-panel\"\n class=\"rc-transfer-list-panel\"\n aria-labelledby=\"selected-label\"\n data-empty=${noSelected ? '' : nothing}\n data-has-selection=${!noSelectedSelection ? '' : nothing}\n >\n <span part=\"label selected-label\" id=\"selected-label\"\n >${this.selectedLabel ?? m.selected}</span\n >\n\n <rc-listbox\n id=\"selected-list\"\n part=\"listbox selected-listbox\"\n aria-labelledby=\"selected-label\"\n tabindex=\"0\"\n .options=${selected}\n .multiple=${this.multiple}\n @rc-listbox-change=${this._onListboxChange}\n ></rc-listbox>\n </section>\n </div>\n <slot></slot>\n `;\n }\n\n /** Adds the highlighted available options to the selected list. */\n addSelected(): void {\n if (!this._$select) {\n return;\n }\n\n const values = new Set(this._$availableList?.selectedValues ?? []);\n\n if (values.size === 0) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n if (!$option.selected && values.has($option.value)) {\n $option.selected = true;\n }\n }\n\n this._syncing = false;\n this._availableSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Adds every available option to the selected list. */\n addAll(): void {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n $option.selected = true;\n }\n\n this._syncing = false;\n\n this._availableSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Removes the highlighted right-hand options from the selected list. */\n removeSelected(): void {\n if (!this._$select) {\n return;\n }\n\n const values = new Set(this._$selectedList?.selectedValues ?? []);\n\n if (values.size === 0) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n if ($option.selected && values.has($option.value)) {\n $option.selected = false;\n }\n }\n\n this._syncing = false;\n this._selectedSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Clears the selected/right-hand list. */\n clearSelected(): void {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n $option.selected = false;\n }\n\n this._syncing = false;\n\n this._selectedSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Moves highlighted right-hand options by `delta` rows (-1 = up, 1 = down). */\n moveSelected(delta: number): void {\n if (delta === 0 || !this._$select) {\n return;\n }\n\n const values = new Set(this._$selectedList?.selectedValues ?? []);\n\n if (values.size === 0) {\n return;\n }\n\n this._syncing = true;\n this._reorderSelectOptions(values, delta);\n this._syncing = false;\n\n this.requestUpdate();\n this._dispatchChange(values);\n }\n\n private _onMoveUp = (): void => {\n this.moveSelected(-1);\n };\n\n private _onMoveDown = (): void => {\n this.moveSelected(1);\n };\n\n private _canMoveSelected(\n selected: ListboxOption[],\n selectedValues: Set<string>,\n delta: -1 | 1,\n ): boolean {\n if (selectedValues.size === 0 || selected.length < 2) {\n return false;\n }\n\n return selected.some((item, index) => {\n if (!selectedValues.has(item.value)) {\n return false;\n }\n\n const target = index + delta;\n\n if (target < 0 || target >= selected.length) {\n return false;\n }\n\n return !selectedValues.has(selected[target].value);\n });\n }\n\n private _onKeydown = (e: KeyboardEvent): void => {\n if (e.altKey) {\n // Alt+arrow toward the selected list adds; the lists swap sides in RTL.\n const keys = arrowKeys('horizontal', resolveFlow(this));\n\n switch (e.key) {\n case keys.next:\n e.preventDefault();\n this.addSelected();\n\n break;\n\n case keys.prev:\n e.preventDefault();\n this.removeSelected();\n\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n this.moveSelected(-1);\n\n break;\n\n case 'ArrowDown':\n e.preventDefault();\n this.moveSelected(1);\n\n break;\n }\n\n return;\n }\n\n const targetId = this._getListboxEventTargetId(e);\n\n // APG shortcut: Enter in the available list adds the active item.\n\n // Restricted to single-select: in multi mode Enter toggles selection in rc-listbox\n // first, so triggering addSelected() here would immediately transfer a single item\n // and discard any multi-item selection the user was building.\n if (targetId === 'available-list' && !this.multiple && e.key === 'Enter') {\n e.preventDefault();\n this.addSelected();\n\n return;\n }\n\n // APG shortcut: Delete in the selected list removes the highlighted items.\n if (targetId === 'selected-list' && e.key === 'Delete') {\n e.preventDefault();\n\n this.removeSelected();\n }\n };\n\n private _onListboxChange = (e: Event): void => {\n const ev = e as CustomEvent<RCListboxChangeEvent>;\n\n if (ev.detail.reason === 'action') {\n e.stopPropagation();\n\n return;\n }\n\n const raw = ev.detail.value;\n const values = Array.isArray(raw) ? raw : raw ? [raw] : [];\n const targetId = (e.currentTarget as Element | null)?.id;\n\n if (targetId === 'available-list') {\n this._availableSelection = values;\n } else if (targetId === 'selected-list') {\n this._selectedSelection = values;\n }\n };\n\n private _getListboxEventTargetId(e: Event): string | undefined {\n for (const node of e.composedPath()) {\n if (\n node instanceof Element &&\n (node.id === 'available-list' || node.id === 'selected-list')\n ) {\n return node.id;\n }\n }\n\n return undefined;\n }\n\n private _setupSelect($select: HTMLSelectElement | null): void {\n if ($select === this._$select) {\n return;\n }\n\n this._teardownSelect();\n this._$select = $select;\n\n if (!$select) {\n return;\n }\n\n // Remove from visual display, AT, and tab order — the rc-listbox UI is the\n // accessible interface; the <select> is only present for form serialisation.\n $select.style.display = 'none';\n $select.setAttribute('aria-hidden', 'true');\n $select.tabIndex = -1;\n\n // Watch for external option additions/removals (attribute-level opt.selected\n // changes via IDL are not observable; use the component API instead).\n this._selectObserver.setOptions({\n target: $select,\n disabled: false,\n observerOptions: { childList: true },\n });\n\n if (!this._selectedInitialized && this._defaultSelected !== undefined) {\n this._applyDefaultSelected(this._defaultSelected);\n }\n\n this.requestUpdate();\n }\n\n private _teardownSelect(): void {\n if (this._$select) {\n this._$select.style.display = '';\n this._$select.removeAttribute('aria-hidden');\n this._$select.removeAttribute('tabindex');\n }\n\n this._selectObserver.setOptions({ target: null, disabled: true });\n this._$select = null;\n }\n\n /**\n * Reorders selected `<option>` DOM nodes inside the backing `<select>` to\n * preserve user-determined order in form serialisation.\n */\n private _reorderSelectOptions(movedValues: Set<string>, delta: number): void {\n const $select = this._$select;\n\n if (!$select) {\n return;\n }\n\n const $options = Array.from($select.options).filter(($option) => $option.selected);\n\n const start = delta < 0 ? 1 : $options.length - 2;\n const end = delta < 0 ? $options.length : -1;\n const step = delta < 0 ? 1 : -1;\n\n for (let i = start; i !== end; i += step) {\n const target = i + delta;\n\n if (!movedValues.has($options[i].value) || movedValues.has($options[target].value)) {\n continue;\n }\n\n if (delta < 0) {\n $select.insertBefore($options[i], $options[target]);\n } else {\n $options[target].insertAdjacentElement('afterend', $options[i]);\n }\n }\n }\n\n // Restores selection in the selected listbox after a mutation. Options are\n // set declaratively in render() so only selection state needs imperative sync.\n private _syncSelection(selectedValues: Set<string> = new Set()): void {\n this._$selectedList?.setSelectedValues([...selectedValues]);\n }\n\n private _dispatchChange(selectedValues?: Set<string>): void {\n this.updateComplete.then(() => {\n this._syncSelection(selectedValues);\n\n this.dispatchEvent(\n new CustomEvent<RCTransferListChangeEvent>('rc-transfer-list-change', {\n bubbles: true,\n composed: true,\n detail: { selected: [...this.selected] },\n }),\n );\n });\n }\n}\n\nexport default RCTransferList;\n"],"names":["transferListStyles","css","DEFAULT_TRANSFER_LIST_MESSAGES","_RCTransferList","LitElement","MessagesController","MutationObserverController","keys","arrowKeys","resolveFlow","targetId","ev","raw","values","NativeChildController","$select","$option","items","selectedValues","item","available","selected","noAvailable","noSelected","cannotReorder","noAvailableSelection","noSelectedSelection","canMoveUp","canMoveDown","m","html","nothing","delta","index","target","node","movedValues","$options","start","end","step","i","RCTransferList","__decorateClass","property","query","state"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
- import { R as t } from "./rc-transfer-list-DFPxuGJ2.js";
2
- customElements.get("rc-transfer-list") || customElements.define("rc-transfer-list", t);
1
+ import { R as r } from "./rc-transfer-list-CYvAsEi5.js";
2
+ import { D as m } from "./rc-transfer-list-CYvAsEi5.js";
3
+ customElements.get("rc-transfer-list") || customElements.define("rc-transfer-list", r);
3
4
  export {
4
- t as RCTransferList
5
+ m as DEFAULT_TRANSFER_LIST_MESSAGES,
6
+ r as RCTransferList
5
7
  };
6
8
  //# sourceMappingURL=rc-transfer-list-define.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rc-transfer-list-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCTransferList } from './index.js';\n\ncustomElements.get('rc-transfer-list') || customElements.define('rc-transfer-list', RCTransferList);\n\nexport * from './index.js';\n"],"names":["RCTransferList"],"mappings":";AAEA,eAAe,IAAI,kBAAkB,KAAK,eAAe,OAAO,oBAAoBA,CAAc;"}
1
+ {"version":3,"file":"rc-transfer-list-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCTransferList } from './index.js';\n\ncustomElements.get('rc-transfer-list') || customElements.define('rc-transfer-list', RCTransferList);\n\nexport * from './index.js';\n"],"names":["RCTransferList"],"mappings":";;AAEA,eAAe,IAAI,kBAAkB,KAAK,eAAe,OAAO,oBAAoBA,CAAc;"}
@@ -1,5 +1,6 @@
1
- import { R as a } from "./rc-transfer-list-DFPxuGJ2.js";
1
+ import { D as s, R as E } from "./rc-transfer-list-CYvAsEi5.js";
2
2
  export {
3
- a as RCTransferList
3
+ s as DEFAULT_TRANSFER_LIST_MESSAGES,
4
+ E as RCTransferList
4
5
  };
5
6
  //# sourceMappingURL=rc-transfer-list.js.map
@@ -1,5 +1,26 @@
1
1
  import { LitElement } from 'lit';
2
2
  import { ListboxOption } from '@rcarls/rc-listbox';
3
+ /** Built-in text of `rc-transfer-list`. */
4
+ export interface RCTransferListMessages {
5
+ /** Default label of the available list, when `available-label` is unset. */
6
+ available: string;
7
+ /** Default label of the selected list, when `selected-label` is unset. */
8
+ selected: string;
9
+ /** Accessible name of the action toolbar. */
10
+ actions: string;
11
+ add: string;
12
+ addAll: string;
13
+ remove: string;
14
+ clear: string;
15
+ moveUp: string;
16
+ moveDown: string;
17
+ }
18
+ export declare const DEFAULT_TRANSFER_LIST_MESSAGES: Readonly<RCTransferListMessages>;
19
+ declare module '@rcarls/rc-common' {
20
+ interface RcMessageCatalog {
21
+ 'rc-transfer-list': RCTransferListMessages;
22
+ }
23
+ }
3
24
  export interface RCTransferListChangeEvent {
4
25
  /** Ordered selected/right-hand list options. */
5
26
  selected: ListboxOption[];
@@ -24,26 +45,33 @@ declare global {
24
45
  *
25
46
  * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-transfer-list rc-transfer-list docs}
26
47
  *
48
+ * Built-in text (action buttons, default list labels) follows the element's
49
+ * own `lang`, else `<html lang>`: per element through `messages`, or for
50
+ * every transfer list through `registerMessages()` from `@rcarls/rc-common`
51
+ * under `rc-transfer-list`. The direction arrows on the action buttons are
52
+ * decorative and turn with the inline direction.
53
+ *
27
54
  * @fires rc-transfer-list-change - Fires when the selected/right-hand list changes.
28
55
  *
29
56
  * @attr multiple - Enable multi-selection in both lists.
30
57
  * @attr compact - Stack the panels and action toolbar into a compact one-column layout.
31
- * @attr available-label - Visible label for the available list.
32
- * @attr selected-label - Visible label for the selected list.
58
+ * @attr available-label - Visible label for the available list. Defaults to the `available` message.
59
+ * @attr selected-label - Visible label for the selected list. Defaults to the `selected` message.
33
60
  *
34
- * @cssprop [--rc-transfer-list-gap=var(--rc-control-gap)] - Gap between panels and the action toolbar
35
- * @cssprop [--rc-transfer-list-panel-gap=var(--rc-control-gap)] - Gap between a panel label and its listbox
61
+ * @cssprop [--rc-transfer-list-gap=var(--rc-control-gap, 0.75rem)] - Gap between panels and the action toolbar
62
+ * @cssprop [--rc-transfer-list-panel-gap=var(--rc-control-gap, 0.35rem)] - Gap between a panel label and its listbox
36
63
  * @cssprop [--rc-transfer-list-listbox-min-block-size=10rem] - Minimum block size for each listbox
37
- * @cssprop [--rc-transfer-list-listbox-border=var(--rc-border)] - Border around each listbox
38
- * @cssprop [--rc-transfer-list-listbox-bg=var(--rc-surface)] - Background of each listbox
39
- * @cssprop [--rc-transfer-list-listbox-color=var(--rc-field-text)] - Text color of each listbox
40
- * @cssprop [--rc-transfer-list-option-gap=var(--rc-item-gap)] - Gap between option adornments and labels
41
- * @cssprop [--rc-transfer-list-option-padding-block=var(--rc-item-padding-block)] - Block padding for option rows
42
- * @cssprop [--rc-transfer-list-option-padding-inline=var(--rc-item-padding-inline)] - Inline padding for option rows
43
- * @cssprop [--rc-transfer-list-option-selected-bg=var(--rc-highlight)] - Selected option background
44
- * @cssprop [--rc-transfer-list-option-selected-color=var(--rc-highlight-text)] - Selected option foreground
45
- * @cssprop [--rc-transfer-list-option-hover-bg=var(--rc-transfer-list-option-selected-bg)] - Hovered/active option background
46
- * @cssprop [--rc-transfer-list-option-hover-color=var(--rc-transfer-list-option-selected-color)] - Hovered/active option foreground
64
+ * @cssprop [--rc-transfer-list-listbox-border=var(--rc-border, 1px solid ButtonBorder)] - Border around each listbox
65
+ * @cssprop [--rc-transfer-list-listbox-radius=var(--rc-control-radius, 0.125rem)] - Corner radius of each listbox
66
+ * @cssprop [--rc-transfer-list-listbox-bg=var(--rc-surface, Canvas)] - Background of each listbox
67
+ * @cssprop [--rc-transfer-list-listbox-color=var(--rc-field-text, FieldText)] - Text color of each listbox
68
+ * @cssprop [--rc-transfer-list-option-gap=var(--rc-item-gap, 0.4em)] - Gap between option adornments and labels
69
+ * @cssprop [--rc-transfer-list-option-padding-block=var(--rc-item-padding-block, 0.3em)] - Block padding for option rows
70
+ * @cssprop [--rc-transfer-list-option-padding-inline=var(--rc-item-padding-inline, 0.75em)] - Inline padding for option rows
71
+ * @cssprop [--rc-transfer-list-option-selected-bg=var(--rc-highlight, Highlight)] - Selected option background
72
+ * @cssprop [--rc-transfer-list-option-selected-color=var(--rc-highlight-text, HighlightText)] - Selected option foreground
73
+ * @cssprop [--rc-transfer-list-option-hover-bg=var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))] - Hovered/active option background
74
+ * @cssprop [--rc-transfer-list-option-hover-color=var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))] - Hovered/active option foreground
47
75
  *
48
76
  * @csspart root - Root layout wrapper. Reflects data-can-move-up/down.
49
77
  * @csspart panel - Shared list panel surface.
@@ -70,10 +98,13 @@ export declare class RCTransferList extends LitElement {
70
98
  multiple: boolean;
71
99
  /** Stack the panels and action toolbar into a compact one-column layout. */
72
100
  compact: boolean;
73
- /** Visible label for the available list. */
74
- availableLabel: string;
75
- /** Visible label for the selected list. */
76
- selectedLabel: string;
101
+ /** Visible label for the available list. Defaults to the `available` message. */
102
+ availableLabel: string | undefined;
103
+ /** Visible label for the selected list. Defaults to the `selected` message. */
104
+ selectedLabel: string | undefined;
105
+ /** Built-in text overrides; unset keys fall back to registered text, then English. */
106
+ messages: Partial<RCTransferListMessages> | undefined;
107
+ private readonly _messages;
77
108
  private _$availableList?;
78
109
  private _$selectedList?;
79
110
  /** Values currently highlighted in the available list. Drives the "Add →" button disable state. */
@@ -109,7 +140,7 @@ export declare class RCTransferList extends LitElement {
109
140
  set defaultSelected(items: ListboxOption[] | undefined);
110
141
  private _applyDefaultSelected;
111
142
  disconnectedCallback(): void;
112
- render(): import('lit').TemplateResult<1>;
143
+ render(): import('lit-html').TemplateResult<1>;
113
144
  /** Adds the highlighted available options to the selected list. */
114
145
  addSelected(): void;
115
146
  /** Adds every available option to the selected list. */
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.6.0",
6
+ "version": "0.7.0",
7
7
  "description": "Transfer list that enhances a native <select multiple> into available and selected panes.",
8
8
  "repository": {
9
9
  "type": "git",
@@ -45,9 +45,9 @@
45
45
  "test:browser:firefox": "vitest --run --project=firefox"
46
46
  },
47
47
  "dependencies": {
48
- "@rcarls/rc-common": "0.6.0",
49
- "@rcarls/rc-listbox": "0.6.0",
50
- "@rcarls/rc-toolbar": "0.6.0"
48
+ "@rcarls/rc-common": "0.7.0",
49
+ "@rcarls/rc-listbox": "0.7.0",
50
+ "@rcarls/rc-toolbar": "0.7.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@custom-elements-manifest/analyzer": "0.11.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"rc-transfer-list-DFPxuGJ2.js","sources":["../src/rc-transfer-list.styles.ts","../src/rc-transfer-list.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const transferListStyles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n #root {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);\n align-items: stretch;\n gap: var(--rc-transfer-list-gap, var(--rc-control-gap, 0.75rem));\n }\n\n :host([compact]) #root {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .rc-transfer-list-panel {\n display: flex;\n min-inline-size: 0;\n flex-direction: column;\n gap: var(--rc-transfer-list-panel-gap, var(--rc-control-gap, 0.35rem));\n }\n\n .rc-transfer-list-panel > rc-listbox {\n flex: 1 1 auto;\n min-block-size: var(--rc-transfer-list-listbox-min-block-size, 10rem);\n overflow: auto;\n border: var(--rc-transfer-list-listbox-border, var(--rc-border, 1px solid ButtonBorder));\n background: var(--rc-transfer-list-listbox-bg, var(--rc-surface, Canvas));\n color: var(--rc-transfer-list-listbox-color, var(--rc-field-text, FieldText));\n --rc-listbox-option-gap: var(--rc-transfer-list-option-gap, var(--rc-item-gap, 0.4em));\n --rc-listbox-option-padding-block: var(\n --rc-transfer-list-option-padding-block,\n var(--rc-item-padding-block, 0.3em)\n );\n --rc-listbox-option-padding-inline: var(\n --rc-transfer-list-option-padding-inline,\n var(--rc-item-padding-inline, 0.75em)\n );\n --rc-listbox-hover-bg: var(\n --rc-transfer-list-option-hover-bg,\n var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))\n );\n --rc-listbox-hover-color: var(\n --rc-transfer-list-option-hover-color,\n var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))\n );\n --rc-listbox-active-bg: var(\n --rc-transfer-list-option-hover-bg,\n var(--rc-transfer-list-option-selected-bg, var(--rc-highlight, Highlight))\n );\n --rc-listbox-active-color: var(\n --rc-transfer-list-option-hover-color,\n var(--rc-transfer-list-option-selected-color, var(--rc-highlight-text, HighlightText))\n );\n --rc-listbox-selected-bg: var(\n --rc-transfer-list-option-selected-bg,\n var(--rc-highlight, Highlight)\n );\n --rc-listbox-selected-color: var(\n --rc-transfer-list-option-selected-color,\n var(--rc-highlight-text, HighlightText)\n );\n --rc-listbox-disabled-opacity: var(--rc-disabled-opacity, 0.5);\n }\n\n rc-listbox [part~='option'][hidden] {\n display: none;\n }\n\n rc-listbox [part~='option'][data-active]:not([aria-disabled='true']) {\n outline: var(--rc-focus-ring, 2px solid var(--rc-accent, Highlight));\n outline-offset: -2px;\n }\n\n rc-listbox [part~='option'][aria-disabled='true'] {\n cursor: not-allowed;\n }\n\n #actions {\n align-self: center;\n transform: translateY(\n calc((1lh + var(--rc-transfer-list-panel-gap, var(--rc-control-gap, 0.35rem))) / 2)\n );\n }\n\n :host([compact]) #actions {\n align-self: stretch;\n transform: none;\n }\n\n :host([compact]) #actions::part(root) {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n #actions button {\n white-space: nowrap;\n }\n\n slot:not([name]) {\n display: none;\n }\n`;\n\nexport default transferListStyles;\n","import { LitElement, html, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\n\nimport {\n MutationObserverController,\n NativeChildController,\n warnMissingDirectChild,\n} from '@rcarls/rc-common';\nimport type { ListboxOption, RCListbox, RCListboxChangeEvent } from '@rcarls/rc-listbox';\n\nimport '@rcarls/rc-listbox/define';\nimport '@rcarls/rc-toolbar/define';\n\nimport { transferListStyles } from './rc-transfer-list.styles.js';\n\nexport interface RCTransferListChangeEvent {\n /** Ordered selected/right-hand list options. */\n selected: ListboxOption[];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-transfer-list': RCTransferList;\n }\n}\n\n/**\n * Transfer list that enhances a native <select multiple> into available and selected\n * panes.\n *\n * The component renders two listboxes and transfer/reorder actions in between.\n * Available options are on the left, and selected options appear on the right. It\n * is an older enterprise/admin UI pattern, but solves the specific problem of\n * multiple selection within a large amount of options.\n *\n * The `available` and `selected` JS array properties write through to the\n * backing `<select>`, so the component can also be driven imperatively from a\n * framework without giving up form participation.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-transfer-list rc-transfer-list docs}\n *\n * @fires rc-transfer-list-change - Fires when the selected/right-hand list changes.\n *\n * @attr multiple - Enable multi-selection in both lists.\n * @attr compact - Stack the panels and action toolbar into a compact one-column layout.\n * @attr available-label - Visible label for the available list.\n * @attr selected-label - Visible label for the selected list.\n *\n * @cssprop [--rc-transfer-list-gap=var(--rc-control-gap)] - Gap between panels and the action toolbar\n * @cssprop [--rc-transfer-list-panel-gap=var(--rc-control-gap)] - Gap between a panel label and its listbox\n * @cssprop [--rc-transfer-list-listbox-min-block-size=10rem] - Minimum block size for each listbox\n * @cssprop [--rc-transfer-list-listbox-border=var(--rc-border)] - Border around each listbox\n * @cssprop [--rc-transfer-list-listbox-bg=var(--rc-surface)] - Background of each listbox\n * @cssprop [--rc-transfer-list-listbox-color=var(--rc-field-text)] - Text color of each listbox\n * @cssprop [--rc-transfer-list-option-gap=var(--rc-item-gap)] - Gap between option adornments and labels\n * @cssprop [--rc-transfer-list-option-padding-block=var(--rc-item-padding-block)] - Block padding for option rows\n * @cssprop [--rc-transfer-list-option-padding-inline=var(--rc-item-padding-inline)] - Inline padding for option rows\n * @cssprop [--rc-transfer-list-option-selected-bg=var(--rc-highlight)] - Selected option background\n * @cssprop [--rc-transfer-list-option-selected-color=var(--rc-highlight-text)] - Selected option foreground\n * @cssprop [--rc-transfer-list-option-hover-bg=var(--rc-transfer-list-option-selected-bg)] - Hovered/active option background\n * @cssprop [--rc-transfer-list-option-hover-color=var(--rc-transfer-list-option-selected-color)] - Hovered/active option foreground\n *\n * @csspart root - Root layout wrapper. Reflects data-can-move-up/down.\n * @csspart panel - Shared list panel surface.\n * @csspart available-panel - Available/left panel. Reflects data-empty and data-has-selection.\n * @csspart selected-panel - Selected/right panel. Reflects data-empty and data-has-selection.\n * @csspart label - Shared panel label surface.\n * @csspart available-label - Label for the available panel.\n * @csspart selected-label - Label for the selected panel.\n * @csspart listbox - Shared listbox surface.\n * @csspart available-listbox - The available/left `rc-listbox`.\n * @csspart selected-listbox - The selected/right `rc-listbox`.\n * @csspart actions - Transfer action toolbar.\n * @csspart button - Shared action button surface.\n * @csspart add-button - Moves highlighted available options to the selected list.\n * @csspart add-all-button - Moves every available option to the selected list.\n * @csspart remove-button - Moves highlighted selected options back to the available list.\n * @csspart clear-button - Moves every selected option back to the available list.\n * @csspart move-up-button - Moves highlighted selected options up.\n * @csspart move-down-button - Moves highlighted selected options down.\n */\nexport class RCTransferList extends LitElement {\n static override styles = transferListStyles;\n\n /** Enable multi-selection in both lists. */\n @property({ type: Boolean, reflect: true })\n multiple = false;\n\n /** Stack the panels and action toolbar into a compact one-column layout. */\n @property({ type: Boolean, reflect: true })\n compact = false;\n\n /** Visible label for the available list. */\n @property({ attribute: 'available-label' })\n availableLabel = 'Available';\n\n /** Visible label for the selected list. */\n @property({ attribute: 'selected-label' })\n selectedLabel = 'Selected';\n\n @query('#available-list')\n private _$availableList?: RCListbox;\n\n @query('#selected-list')\n private _$selectedList?: RCListbox;\n\n /** Values currently highlighted in the available list. Drives the \"Add →\" button disable state. */\n @state()\n private _availableSelection: string[] = [];\n\n /** Values currently highlighted in the selected list. Drives Remove/reorder button disable states. */\n @state()\n private _selectedSelection: string[] = [];\n\n private _$select: HTMLSelectElement | null = null;\n\n /** Set while the component mutates the backing <select> to prevent observer feedback loops. */\n private _syncing = false;\n\n private _defaultSelected: ListboxOption[] | undefined;\n\n private _selectedInitialized = false;\n\n private readonly _selectObserver = new MutationObserverController(this, {\n target: null,\n disabled: true,\n callback: () => {\n if (!this._syncing) {\n this.requestUpdate();\n }\n },\n });\n\n constructor() {\n super();\n\n new NativeChildController<HTMLSelectElement>(this, {\n selector: ':scope > select[multiple]',\n observe: true,\n onChange: ($select) => this._setupSelect($select),\n onMissing: () => {\n if (import.meta.env.DEV) {\n warnMissingDirectChild(this, {\n selector: ':scope > select[multiple]',\n message:\n '[rc-transfer-list] No direct child <select multiple> found. ' +\n 'Add a <select multiple> child for form participation and progressive enhancement.',\n });\n }\n },\n });\n }\n\n /**\n * Available/left-hand options derived from unselected `<option>` elements.\n *\n * Setting this property replaces all unselected options in the backing\n * `<select>`. Items whose values already appear in the selected list are\n * skipped to prevent duplicate option values.\n */\n get available(): ListboxOption[] {\n if (!this._$select) {\n return [];\n }\n\n return Array.from(this._$select.options)\n .filter(($option) => !$option.selected)\n .map(($option) => ({ value: $option.value, label: $option.label || $option.text }));\n }\n\n set available(items: ListboxOption[]) {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n const selectedValues = new Set(\n Array.from(this._$select.options)\n .filter(($option) => $option.selected)\n .map(($option) => $option.value),\n );\n\n for (const $option of Array.from(this._$select.options)) {\n if (!$option.selected) {\n $option.remove();\n }\n }\n\n for (const item of items) {\n if (!selectedValues.has(item.value)) {\n this._$select.add(new Option(item.label, item.value));\n }\n }\n\n this._syncing = false;\n this.requestUpdate();\n }\n\n /**\n * Selected/right-hand options derived from selected `<option>` elements.\n *\n * Setting this property replaces all selected options in the backing\n * `<select>`. Unselected options are left unchanged.\n */\n get selected(): ListboxOption[] {\n if (!this._$select) {\n return [];\n }\n\n return Array.from(this._$select.options)\n .filter(($option) => $option.selected)\n .map(($option) => ({ value: $option.value, label: $option.label || $option.text }));\n }\n\n set selected(items: ListboxOption[]) {\n this._selectedInitialized = true;\n\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n if ($option.selected) {\n $option.remove();\n }\n }\n\n for (const item of items) {\n this._$select.add(new Option(item.label, item.value, false, true));\n }\n\n this._syncing = false;\n this.requestUpdate();\n }\n\n /** Initial uncontrolled selected list. Applied before any `selected` write from the host. */\n get defaultSelected(): ListboxOption[] | undefined {\n return this._defaultSelected;\n }\n\n set defaultSelected(items: ListboxOption[] | undefined) {\n this._defaultSelected = items;\n\n if (!this._selectedInitialized && this._$select && items !== undefined) {\n this._applyDefaultSelected(items);\n }\n }\n\n private _applyDefaultSelected(items: ListboxOption[]): void {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n $option.selected = items.some((item) => item.value === $option.value);\n }\n\n this._syncing = false;\n this.requestUpdate();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardownSelect();\n }\n\n override render() {\n const available = this.available; // reads <select> directly; requestUpdate() always precedes render\n const selected = this.selected;\n const selectedValues = new Set(this._selectedSelection);\n const noAvailable = available.length === 0;\n const noSelected = selected.length === 0;\n const cannotReorder = selected.length < 2;\n const noAvailableSelection = this._availableSelection.length === 0;\n const noSelectedSelection = this._selectedSelection.length === 0;\n const canMoveUp = this._canMoveSelected(selected, selectedValues, -1);\n const canMoveDown = this._canMoveSelected(selected, selectedValues, 1);\n\n return html`\n <div\n id=\"root\"\n part=\"root\"\n class=\"rc-transfer-list-root\"\n data-can-move-up=${canMoveUp ? '' : nothing}\n data-can-move-down=${canMoveDown ? '' : nothing}\n @keydown=${this._onKeydown}\n >\n <section\n part=\"panel available-panel\"\n class=\"rc-transfer-list-panel\"\n aria-labelledby=\"available-label\"\n data-empty=${noAvailable ? '' : nothing}\n data-has-selection=${!noAvailableSelection ? '' : nothing}\n >\n <span part=\"label available-label\" id=\"available-label\">${this.availableLabel}</span>\n <rc-listbox\n id=\"available-list\"\n part=\"listbox available-listbox\"\n aria-labelledby=\"available-label\"\n tabindex=\"0\"\n .options=${available}\n .multiple=${this.multiple}\n @rc-listbox-change=${this._onListboxChange}\n ></rc-listbox>\n </section>\n\n <rc-toolbar\n id=\"actions\"\n orientation=${this.compact ? 'horizontal' : 'vertical'}\n label=\"Transfer actions\"\n part=\"actions\"\n class=\"rc-transfer-list-actions\"\n >\n <button\n type=\"button\"\n part=\"button add-button\"\n ?disabled=${noAvailable || noAvailableSelection}\n @click=${this.addSelected}\n >\n Add &#x2192;\n </button>\n\n <button\n type=\"button\"\n part=\"button add-all-button\"\n ?disabled=${noAvailable}\n @click=${this.addAll}\n >\n Add all &#x2192;\n </button>\n\n <button\n type=\"button\"\n part=\"button remove-button\"\n ?disabled=${noSelected || noSelectedSelection}\n @click=${this.removeSelected}\n >\n &#x2190; Remove\n </button>\n\n <button\n type=\"button\"\n part=\"button clear-button\"\n ?disabled=${noSelected}\n @click=${this.clearSelected}\n >\n &#x2190; Clear\n </button>\n\n <button\n type=\"button\"\n part=\"button move-up-button\"\n ?disabled=${cannotReorder || noSelectedSelection}\n @click=${this._onMoveUp}\n >\n Move up\n </button>\n\n <button\n type=\"button\"\n part=\"button move-down-button\"\n ?disabled=${cannotReorder || noSelectedSelection}\n @click=${this._onMoveDown}\n >\n Move down\n </button>\n </rc-toolbar>\n\n <section\n part=\"panel selected-panel\"\n class=\"rc-transfer-list-panel\"\n aria-labelledby=\"selected-label\"\n data-empty=${noSelected ? '' : nothing}\n data-has-selection=${!noSelectedSelection ? '' : nothing}\n >\n <span part=\"label selected-label\" id=\"selected-label\">${this.selectedLabel}</span>\n\n <rc-listbox\n id=\"selected-list\"\n part=\"listbox selected-listbox\"\n aria-labelledby=\"selected-label\"\n tabindex=\"0\"\n .options=${selected}\n .multiple=${this.multiple}\n @rc-listbox-change=${this._onListboxChange}\n ></rc-listbox>\n </section>\n </div>\n <slot></slot>\n `;\n }\n\n /** Adds the highlighted available options to the selected list. */\n addSelected(): void {\n if (!this._$select) {\n return;\n }\n\n const values = new Set(this._$availableList?.selectedValues ?? []);\n\n if (values.size === 0) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n if (!$option.selected && values.has($option.value)) {\n $option.selected = true;\n }\n }\n\n this._syncing = false;\n this._availableSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Adds every available option to the selected list. */\n addAll(): void {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n $option.selected = true;\n }\n\n this._syncing = false;\n\n this._availableSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Removes the highlighted right-hand options from the selected list. */\n removeSelected(): void {\n if (!this._$select) {\n return;\n }\n\n const values = new Set(this._$selectedList?.selectedValues ?? []);\n\n if (values.size === 0) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n if ($option.selected && values.has($option.value)) {\n $option.selected = false;\n }\n }\n\n this._syncing = false;\n this._selectedSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Clears the selected/right-hand list. */\n clearSelected(): void {\n if (!this._$select) {\n return;\n }\n\n this._syncing = true;\n\n for (const $option of Array.from(this._$select.options)) {\n $option.selected = false;\n }\n\n this._syncing = false;\n\n this._selectedSelection = [];\n this.requestUpdate();\n this._dispatchChange();\n }\n\n /** Moves highlighted right-hand options by `delta` rows (-1 = up, 1 = down). */\n moveSelected(delta: number): void {\n if (delta === 0 || !this._$select) {\n return;\n }\n\n const values = new Set(this._$selectedList?.selectedValues ?? []);\n\n if (values.size === 0) {\n return;\n }\n\n this._syncing = true;\n this._reorderSelectOptions(values, delta);\n this._syncing = false;\n\n this.requestUpdate();\n this._dispatchChange(values);\n }\n\n private _onMoveUp = (): void => {\n this.moveSelected(-1);\n };\n\n private _onMoveDown = (): void => {\n this.moveSelected(1);\n };\n\n private _canMoveSelected(\n selected: ListboxOption[],\n selectedValues: Set<string>,\n delta: -1 | 1,\n ): boolean {\n if (selectedValues.size === 0 || selected.length < 2) {\n return false;\n }\n\n return selected.some((item, index) => {\n if (!selectedValues.has(item.value)) {\n return false;\n }\n\n const target = index + delta;\n\n if (target < 0 || target >= selected.length) {\n return false;\n }\n\n return !selectedValues.has(selected[target].value);\n });\n }\n\n private _onKeydown = (e: KeyboardEvent): void => {\n if (e.altKey) {\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault();\n this.addSelected();\n\n break;\n\n case 'ArrowLeft':\n e.preventDefault();\n this.removeSelected();\n\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n this.moveSelected(-1);\n\n break;\n\n case 'ArrowDown':\n e.preventDefault();\n this.moveSelected(1);\n\n break;\n }\n\n return;\n }\n\n const targetId = this._getListboxEventTargetId(e);\n\n // APG shortcut: Enter in the available list adds the active item.\n\n // Restricted to single-select: in multi mode Enter toggles selection in rc-listbox\n // first, so triggering addSelected() here would immediately transfer a single item\n // and discard any multi-item selection the user was building.\n if (targetId === 'available-list' && !this.multiple && e.key === 'Enter') {\n e.preventDefault();\n this.addSelected();\n\n return;\n }\n\n // APG shortcut: Delete in the selected list removes the highlighted items.\n if (targetId === 'selected-list' && e.key === 'Delete') {\n e.preventDefault();\n\n this.removeSelected();\n }\n };\n\n private _onListboxChange = (e: Event): void => {\n const ev = e as CustomEvent<RCListboxChangeEvent>;\n\n if (ev.detail.reason === 'action') {\n e.stopPropagation();\n return;\n }\n\n const raw = ev.detail.value;\n const values = Array.isArray(raw) ? raw : raw ? [raw] : [];\n const targetId = (e.currentTarget as Element | null)?.id;\n\n if (targetId === 'available-list') {\n this._availableSelection = values;\n } else if (targetId === 'selected-list') {\n this._selectedSelection = values;\n }\n };\n\n private _getListboxEventTargetId(e: Event): string | undefined {\n for (const node of e.composedPath()) {\n if (\n node instanceof Element &&\n (node.id === 'available-list' || node.id === 'selected-list')\n ) {\n return node.id;\n }\n }\n\n return undefined;\n }\n\n private _setupSelect($select: HTMLSelectElement | null): void {\n if ($select === this._$select) {\n return;\n }\n\n this._teardownSelect();\n this._$select = $select;\n\n if (!$select) {\n return;\n }\n\n // Remove from visual display, AT, and tab order — the rc-listbox UI is the\n // accessible interface; the <select> is only present for form serialisation.\n $select.style.display = 'none';\n $select.setAttribute('aria-hidden', 'true');\n $select.tabIndex = -1;\n\n // Watch for external option additions/removals (attribute-level opt.selected\n // changes via IDL are not observable; use the component API instead).\n this._selectObserver.setOptions({\n target: $select,\n disabled: false,\n observerOptions: { childList: true },\n });\n\n if (!this._selectedInitialized && this._defaultSelected !== undefined) {\n this._applyDefaultSelected(this._defaultSelected);\n }\n\n this.requestUpdate();\n }\n\n private _teardownSelect(): void {\n if (this._$select) {\n this._$select.style.display = '';\n this._$select.removeAttribute('aria-hidden');\n this._$select.removeAttribute('tabindex');\n }\n\n this._selectObserver.setOptions({ target: null, disabled: true });\n this._$select = null;\n }\n\n /**\n * Reorders selected `<option>` DOM nodes inside the backing `<select>` to\n * preserve user-determined order in form serialisation.\n */\n private _reorderSelectOptions(movedValues: Set<string>, delta: number): void {\n const $select = this._$select!;\n const $options = Array.from($select.options).filter(($option) => $option.selected);\n\n const start = delta < 0 ? 1 : $options.length - 2;\n const end = delta < 0 ? $options.length : -1;\n const step = delta < 0 ? 1 : -1;\n\n for (let i = start; i !== end; i += step) {\n const target = i + delta;\n\n if (!movedValues.has($options[i].value) || movedValues.has($options[target].value)) {\n continue;\n }\n\n if (delta < 0) {\n $select.insertBefore($options[i], $options[target]);\n } else {\n $options[target].insertAdjacentElement('afterend', $options[i]);\n }\n }\n }\n\n // Restores selection in the selected listbox after a mutation. Options are\n // set declaratively in render() so only selection state needs imperative sync.\n private _syncSelection(selectedValues: Set<string> = new Set()): void {\n this._$selectedList?.setSelectedValues([...selectedValues]);\n }\n\n private _dispatchChange(selectedValues?: Set<string>): void {\n this.updateComplete.then(() => {\n this._syncSelection(selectedValues);\n\n this.dispatchEvent(\n new CustomEvent<RCTransferListChangeEvent>('rc-transfer-list-change', {\n bubbles: true,\n composed: true,\n detail: { selected: [...this.selected] },\n }),\n );\n });\n }\n}\n\nexport default RCTransferList;\n"],"names":["transferListStyles","css","_RCTransferList","LitElement","MutationObserverController","targetId","ev","raw","values","NativeChildController","$select","$option","items","selectedValues","item","available","selected","noAvailable","noSelected","cannotReorder","noAvailableSelection","noSelectedSelection","canMoveUp","canMoveDown","html","nothing","delta","index","target","node","movedValues","$options","start","end","step","i","RCTransferList","__decorateClass","property","query","state"],"mappings":"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"}