@rcarls/rc-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 +177 -0
- package/README.md +102 -0
- package/dist/custom-elements.json +430 -2
- package/dist/rc-list-BqQXmC0M.js +325 -0
- package/dist/rc-list-BqQXmC0M.js.map +1 -0
- package/dist/rc-list-define.js +1 -1
- package/dist/rc-list.js +1 -1
- package/dist/types/packages/rc-list/src/listBaseStyles.d.ts +10 -0
- package/dist/types/packages/rc-list/src/rc-list-item.d.ts +51 -2
- package/dist/types/packages/rc-list/src/rc-list.d.ts +83 -1
- package/package.json +2 -2
- package/dist/rc-list-DyOxApRJ.js +0 -361
- package/dist/rc-list-DyOxApRJ.js.map +0 -1
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
+
import { ReorderMessages } from '@rcarls/rc-common';
|
|
3
|
+
import { RCListItem } from './rc-list-item.js';
|
|
2
4
|
export type RCListVariant = 'standard' | 'segmented';
|
|
3
5
|
export type RCListSelection = 'none' | 'single' | 'multiple';
|
|
4
6
|
declare global {
|
|
5
7
|
interface HTMLElementTagNameMap {
|
|
6
8
|
'rc-list': RCList;
|
|
7
9
|
}
|
|
10
|
+
interface HTMLElementEventMap {
|
|
11
|
+
'rc-list-reorder': CustomEvent<RCListReorderDetail>;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** Detail shape for `rc-list-reorder`. Positions are 0-based among visible items. */
|
|
15
|
+
export interface RCListReorderDetail {
|
|
16
|
+
/** The moved item. */
|
|
17
|
+
item: RCListItem;
|
|
18
|
+
/** Position the item is moving from. */
|
|
19
|
+
from: number;
|
|
20
|
+
/** Position the item is moving to. */
|
|
21
|
+
to: number;
|
|
8
22
|
}
|
|
23
|
+
/** Overridable reorder announcements. Positions passed to the functions are 1-based. */
|
|
24
|
+
export type RCListReorderMessages = Partial<ReorderMessages>;
|
|
9
25
|
/**
|
|
10
26
|
* Shared-column list layout with optional native-backed selection.
|
|
11
27
|
*
|
|
@@ -20,6 +36,18 @@ declare global {
|
|
|
20
36
|
*
|
|
21
37
|
* @attr variant - Appearance hint: `standard` or `segmented`.
|
|
22
38
|
* @attr selection - Native selection coordination: `none`, `single`, or `multiple`.
|
|
39
|
+
* @attr ordered - Marks the item order as meaningful. Visible items without authored
|
|
40
|
+
* `aria-posinset`/`aria-setsize` receive their position so assistive technology reports it.
|
|
41
|
+
* No counters are rendered; item content carries any visible numbering.
|
|
42
|
+
* @attr reorderable - Lets people reorder items with a handle, by pointer or keyboard.
|
|
43
|
+
* Implies `ordered`. Each item provides a native `<button data-rc-reorder-handle>`.
|
|
44
|
+
* @attr [data-reordering] - Reflected while an item is lifted.
|
|
45
|
+
*
|
|
46
|
+
* @fires rc-list-reorder - Fires, cancelable, when a reorder moves an item;
|
|
47
|
+
* `detail: { item, from, to }`. Unless the event is canceled the list moves the item's
|
|
48
|
+
* node itself. A framework that renders the items cancels it and reorders its own data.
|
|
49
|
+
* A pointer drag fires once on drop; the keyboard fires on each step, and once more to
|
|
50
|
+
* move the item back when the reorder is canceled.
|
|
23
51
|
* @attr [has-leading] - Reflected when a visible item uses the leading slot.
|
|
24
52
|
* @attr [has-trailing] - Reflected when a visible item uses the trailing slot.
|
|
25
53
|
*
|
|
@@ -31,6 +59,28 @@ declare global {
|
|
|
31
59
|
* @cssprop [--rc-list-trailing-gap=1rem] - Gap before the trailing column.
|
|
32
60
|
* @cssprop [--rc-list-row-gap=0] - Gap between rows.
|
|
33
61
|
*
|
|
62
|
+
* ## Reordering
|
|
63
|
+
*
|
|
64
|
+
* With `reorderable`, a native `<button data-rc-reorder-handle>` inside an item starts a
|
|
65
|
+
* reorder. Label the button yourself, for example "Reorder Photo 2". Handles without an
|
|
66
|
+
* authored `aria-description` get a short keyboard hint.
|
|
67
|
+
*
|
|
68
|
+
* - Pointer: press the handle and drag. The lifted item follows the pointer, the items
|
|
69
|
+
* it passes shift out of its way, and the nearest scroll container scrolls near its
|
|
70
|
+
* edges. Escape cancels.
|
|
71
|
+
* - Touch and pen: as on Android, a long press anywhere on an item also picks it up, then
|
|
72
|
+
* drag. Moving before the press completes scrolls the list instead. A mouse drags only
|
|
73
|
+
* by the handle. Item text cannot be selected in a reorderable list.
|
|
74
|
+
* - Keyboard: Space or Enter picks the item up, the block-axis arrow keys, Home, and End
|
|
75
|
+
* move it, Space or Enter drops it, and Escape returns it. Leaving the handle drops it.
|
|
76
|
+
*
|
|
77
|
+
* Each step is announced through a polite live region mounted in the nearest open
|
|
78
|
+
* `dialog` or popover, else the document body; override the text with `reorderMessages`. Focus stays on the moved item's handle, and is restored to
|
|
79
|
+
* the item at the new position when a framework replaces the item's nodes.
|
|
80
|
+
*
|
|
81
|
+
* The lifted item carries `data-dragging`, and the list carries `data-reordering`. The
|
|
82
|
+
* list writes inline `translate` offsets to items while a pointer drag previews a move.
|
|
83
|
+
*
|
|
34
84
|
* @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-list rc-list documentation}
|
|
35
85
|
* @see {@link https://m3.material.io/components/lists/overview Material Design lists}
|
|
36
86
|
*/
|
|
@@ -43,23 +93,55 @@ export declare class RCList extends LitElement {
|
|
|
43
93
|
private readonly _authoredItemState;
|
|
44
94
|
private _$slot;
|
|
45
95
|
private _mutationObserver;
|
|
96
|
+
private _unobserveLocale;
|
|
46
97
|
/** Appearance hint. */
|
|
47
98
|
variant: RCListVariant;
|
|
48
99
|
/** Native selection coordination mode. */
|
|
49
100
|
selection: RCListSelection;
|
|
101
|
+
/** Whether item order is meaningful; positions are exposed without rendered counters. */
|
|
102
|
+
ordered: boolean;
|
|
103
|
+
/** Whether people can reorder items with a handle. Implies `ordered`. */
|
|
104
|
+
reorderable: boolean;
|
|
105
|
+
/** Overrides for the reorder announcements and the handle hint. */
|
|
106
|
+
reorderMessages: RCListReorderMessages | undefined;
|
|
107
|
+
private readonly _reorder;
|
|
108
|
+
/** Handle descriptions this list wrote, released when no longer reorderable. */
|
|
109
|
+
private readonly _describedHandles;
|
|
110
|
+
/**
|
|
111
|
+
* Positions this list wrote, by item. An item whose attributes no longer
|
|
112
|
+
* match was repositioned by its author, possibly after the first sync, and
|
|
113
|
+
* is left alone from then on.
|
|
114
|
+
*/
|
|
115
|
+
private readonly _positionedItems;
|
|
50
116
|
constructor();
|
|
51
117
|
connectedCallback(): void;
|
|
52
118
|
disconnectedCallback(): void;
|
|
53
119
|
protected firstUpdated(): void;
|
|
54
120
|
protected updated(changed: Map<PropertyKey, unknown>): void;
|
|
55
121
|
private _items;
|
|
122
|
+
private _visibleItems;
|
|
56
123
|
private _expectedInputType;
|
|
57
124
|
private _inputFor;
|
|
58
125
|
private _queueSync;
|
|
59
126
|
private _syncItems;
|
|
127
|
+
/**
|
|
128
|
+
* Expose each visible item's position in an ordered list. Items that carry
|
|
129
|
+
* authored positions (a virtualized slice) keep them; positions this list
|
|
130
|
+
* wrote are released when the item leaves or the list stops being ordered.
|
|
131
|
+
*/
|
|
132
|
+
private _syncOrderedPositions;
|
|
133
|
+
private _isOrdered;
|
|
134
|
+
/**
|
|
135
|
+
* Give each handle a keyboard hint unless its author described it. A
|
|
136
|
+
* description the author rewrites afterward is theirs from then on.
|
|
137
|
+
*/
|
|
138
|
+
private _syncHandleDescriptions;
|
|
139
|
+
/** Dispatch a reorder and, unless a consumer took it over, move the node. */
|
|
140
|
+
private _moveItem;
|
|
141
|
+
private _releasePosition;
|
|
60
142
|
private _restoreItem;
|
|
61
143
|
private _restoreAllItems;
|
|
62
144
|
private readonly _handleChange;
|
|
63
145
|
private _handleSlotChange;
|
|
64
|
-
protected render(): import('lit').TemplateResult<1>;
|
|
146
|
+
protected render(): import('lit-html').TemplateResult<1>;
|
|
65
147
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.7.0",
|
|
7
7
|
"description": "Shared-column list rows with native-backed selection patterns.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"test:browser:firefox": "vitest --run --project=firefox"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@rcarls/rc-common": "0.
|
|
48
|
+
"@rcarls/rc-common": "0.7.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@custom-elements-manifest/analyzer": "0.11.0",
|
package/dist/rc-list-DyOxApRJ.js
DELETED
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
import { css as g, LitElement as m, html as v } from "lit";
|
|
2
|
-
import { property as n, query as f } from "lit/decorators.js";
|
|
3
|
-
import { ClickDelegateController as b } from "@rcarls/rc-common";
|
|
4
|
-
const _ = g`
|
|
5
|
-
:host {
|
|
6
|
-
display: grid;
|
|
7
|
-
grid-column: 1 / -1;
|
|
8
|
-
grid-template-columns: subgrid;
|
|
9
|
-
min-inline-size: 0;
|
|
10
|
-
color: var(--rc-list-item-color, CanvasText);
|
|
11
|
-
color-scheme: inherit;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
:host([hidden]) {
|
|
15
|
-
display: none;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
[part='row'] {
|
|
19
|
-
position: relative;
|
|
20
|
-
display: grid;
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
grid-column: 1 / -1;
|
|
23
|
-
grid-template-columns: subgrid;
|
|
24
|
-
grid-template-rows: var(--rc-list-item-grid-template-rows, auto);
|
|
25
|
-
align-items: center;
|
|
26
|
-
row-gap: var(--rc-list-item-row-gap, 0);
|
|
27
|
-
min-block-size: var(--rc-list-item-min-block-size, 3rem);
|
|
28
|
-
min-inline-size: 0;
|
|
29
|
-
padding-block: var(--rc-list-item-padding-block, 0.5rem);
|
|
30
|
-
overflow: clip;
|
|
31
|
-
border: var(--rc-list-item-border, 0);
|
|
32
|
-
border-radius: var(--rc-list-item-border-radius, 0);
|
|
33
|
-
background: var(--rc-list-item-background, transparent);
|
|
34
|
-
box-shadow: var(--rc-list-item-box-shadow, none);
|
|
35
|
-
transition:
|
|
36
|
-
background-color var(--rc-list-item-transition-duration, 0ms)
|
|
37
|
-
var(--rc-list-item-transition-easing, ease),
|
|
38
|
-
box-shadow var(--rc-list-item-transition-duration, 0ms)
|
|
39
|
-
var(--rc-list-item-transition-easing, ease);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
[part='state-layer'] {
|
|
43
|
-
position: absolute;
|
|
44
|
-
z-index: 0;
|
|
45
|
-
inset: 0;
|
|
46
|
-
pointer-events: none;
|
|
47
|
-
background: var(--rc-list-item-state-layer-color, currentColor);
|
|
48
|
-
opacity: var(--rc-list-item-state-layer-opacity, 0);
|
|
49
|
-
transition: opacity var(--rc-list-item-transition-duration, 0ms)
|
|
50
|
-
var(--rc-list-item-transition-easing, ease);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
[part='leading'],
|
|
54
|
-
[part='content'],
|
|
55
|
-
[part='trailing'] {
|
|
56
|
-
position: relative;
|
|
57
|
-
z-index: 1;
|
|
58
|
-
min-inline-size: 0;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
[part='leading'] {
|
|
62
|
-
grid-column: var(--rc-list-item-leading-grid-column, leading-start / leading-end);
|
|
63
|
-
grid-row: var(--rc-list-item-leading-grid-row, auto);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
[part='content'] {
|
|
67
|
-
grid-column: var(--rc-list-item-content-grid-column, content-start / content-end);
|
|
68
|
-
grid-row: var(--rc-list-item-content-grid-row, auto);
|
|
69
|
-
overflow: hidden;
|
|
70
|
-
text-overflow: var(--rc-list-item-content-text-overflow, ellipsis);
|
|
71
|
-
white-space: var(--rc-list-item-content-white-space, nowrap);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
[part='trailing'] {
|
|
75
|
-
grid-column: var(--rc-list-item-trailing-grid-column, trailing-start / trailing-end);
|
|
76
|
-
grid-row: var(--rc-list-item-trailing-grid-row, auto);
|
|
77
|
-
justify-self: var(--rc-list-item-trailing-justify-self, end);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
[part='leading'][hidden],
|
|
81
|
-
[part='trailing'][hidden] {
|
|
82
|
-
display: none;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
::slotted(*) {
|
|
86
|
-
min-inline-size: 0;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
[part='content'] ::slotted(*) {
|
|
90
|
-
overflow: hidden;
|
|
91
|
-
text-overflow: inherit;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
[part='divider'] {
|
|
95
|
-
position: absolute;
|
|
96
|
-
z-index: 1;
|
|
97
|
-
inset-block-end: 0;
|
|
98
|
-
inset-inline: var(--rc-list-item-divider-inset-inline, 0);
|
|
99
|
-
border-block-end: var(--rc-list-item-divider, 0);
|
|
100
|
-
pointer-events: none;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
:host([interactive]:not([disabled])) {
|
|
104
|
-
cursor: pointer;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
:host([interactive]:not([disabled]):hover) [part='state-layer'] {
|
|
108
|
-
opacity: var(--rc-list-item-hover-state-layer-opacity, 0.08);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
:host([interactive]:not([disabled]):focus-within) [part='state-layer'] {
|
|
112
|
-
opacity: var(--rc-list-item-focus-state-layer-opacity, 0.1);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
:host([interactive]:not([disabled]):active) [part='state-layer'] {
|
|
116
|
-
opacity: var(--rc-list-item-pressed-state-layer-opacity, 0.1);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
:host([selected]) [part='row'] {
|
|
120
|
-
color: var(--rc-list-item-selected-color, var(--rc-list-item-color, CanvasText));
|
|
121
|
-
background: var(--rc-list-item-selected-background, transparent);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
:host([disabled]) {
|
|
125
|
-
cursor: default;
|
|
126
|
-
opacity: var(--rc-list-item-disabled-opacity, 0.38);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
@media (forced-colors: active) {
|
|
130
|
-
[part='row'] {
|
|
131
|
-
border-color: CanvasText;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
:host([selected]) [part='row'] {
|
|
135
|
-
outline: 2px solid Highlight;
|
|
136
|
-
outline-offset: -2px;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
@media (prefers-reduced-motion: reduce) {
|
|
141
|
-
[part='row'],
|
|
142
|
-
[part='state-layer'] {
|
|
143
|
-
transition-duration: 0ms;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
`;
|
|
147
|
-
var y = Object.defineProperty, c = (l, t, e, r) => {
|
|
148
|
-
for (var i = void 0, s = l.length - 1, o; s >= 0; s--)
|
|
149
|
-
(o = l[s]) && (i = o(t, e, i) || i);
|
|
150
|
-
return i && y(t, e, i), i;
|
|
151
|
-
};
|
|
152
|
-
const p = class p extends m {
|
|
153
|
-
constructor() {
|
|
154
|
-
super(), this.selected = !1, this.disabled = !1, this.interactive = !1, this.actionTarget = "", this._internals = this.attachInternals(), this._internals.role = "listitem", new b(this, {
|
|
155
|
-
target: () => this._resolveActionTarget() ?? this._nativeInput(),
|
|
156
|
-
disabled: () => !this.interactive || this.disabled
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
connectedCallback() {
|
|
160
|
-
super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "listitem");
|
|
161
|
-
}
|
|
162
|
-
updated(t) {
|
|
163
|
-
}
|
|
164
|
-
_hasAssignedElements(t) {
|
|
165
|
-
return t.currentTarget.assignedNodes({ flatten: !0 }).some((e) => e.nodeType !== Node.TEXT_NODE || !!e.textContent?.trim());
|
|
166
|
-
}
|
|
167
|
-
_handleNamedSlotChange(t) {
|
|
168
|
-
const e = t.currentTarget;
|
|
169
|
-
this.toggleAttribute(`has-${e.name}`, this._hasAssignedElements(t));
|
|
170
|
-
}
|
|
171
|
-
_nativeInput() {
|
|
172
|
-
return this.querySelector(':scope > input:is([type="checkbox"], [type="radio"])');
|
|
173
|
-
}
|
|
174
|
-
_resolveActionTarget() {
|
|
175
|
-
const t = this.actionTarget.trim();
|
|
176
|
-
if (!t)
|
|
177
|
-
return null;
|
|
178
|
-
const e = this.getRootNode(), r = e instanceof Document || e instanceof ShadowRoot ? e.getElementById(t) : null;
|
|
179
|
-
return r instanceof HTMLAnchorElement || r instanceof HTMLButtonElement ? r : null;
|
|
180
|
-
}
|
|
181
|
-
firstUpdated() {
|
|
182
|
-
for (const t of this.shadowRoot?.querySelectorAll("slot[name]") ?? [])
|
|
183
|
-
this.toggleAttribute(`has-${t.name}`, t.assignedNodes({ flatten: !0 }).length > 0);
|
|
184
|
-
}
|
|
185
|
-
render() {
|
|
186
|
-
return v`
|
|
187
|
-
<div part="row">
|
|
188
|
-
<span part="state-layer" aria-hidden="true"></span>
|
|
189
|
-
<span part="leading">
|
|
190
|
-
<slot name="leading" @slotchange=${this._handleNamedSlotChange}></slot>
|
|
191
|
-
</span>
|
|
192
|
-
<span part="content"><slot></slot></span>
|
|
193
|
-
<span part="trailing">
|
|
194
|
-
<slot name="trailing" @slotchange=${this._handleNamedSlotChange}></slot>
|
|
195
|
-
</span>
|
|
196
|
-
<span part="divider" aria-hidden="true"></span>
|
|
197
|
-
</div>
|
|
198
|
-
`;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
p.styles = _;
|
|
202
|
-
let a = p;
|
|
203
|
-
c([
|
|
204
|
-
n({ type: Boolean, reflect: !0 })
|
|
205
|
-
], a.prototype, "selected");
|
|
206
|
-
c([
|
|
207
|
-
n({ type: Boolean, reflect: !0 })
|
|
208
|
-
], a.prototype, "disabled");
|
|
209
|
-
c([
|
|
210
|
-
n({ type: Boolean, reflect: !0 })
|
|
211
|
-
], a.prototype, "interactive");
|
|
212
|
-
c([
|
|
213
|
-
n({ type: String, attribute: "action-target" })
|
|
214
|
-
], a.prototype, "actionTarget");
|
|
215
|
-
const w = g`
|
|
216
|
-
:host {
|
|
217
|
-
--_rc-list-leading-gap: 0;
|
|
218
|
-
--_rc-list-leading-size: 0;
|
|
219
|
-
--_rc-list-trailing-gap: 0;
|
|
220
|
-
--_rc-list-trailing-size: 0;
|
|
221
|
-
|
|
222
|
-
display: block;
|
|
223
|
-
min-inline-size: 0;
|
|
224
|
-
color-scheme: inherit;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
:host([hidden]) {
|
|
228
|
-
display: none;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
:host([has-leading]) {
|
|
232
|
-
--_rc-list-leading-gap: var(--rc-list-leading-gap, 1rem);
|
|
233
|
-
--_rc-list-leading-size: var(--rc-list-leading-size, minmax(0, max-content));
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
:host([has-trailing]) {
|
|
237
|
-
--_rc-list-trailing-gap: var(--rc-list-trailing-gap, 1rem);
|
|
238
|
-
--_rc-list-trailing-size: var(--rc-list-trailing-size, minmax(0, max-content));
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
[part='list'] {
|
|
242
|
-
display: grid;
|
|
243
|
-
grid-template-columns:
|
|
244
|
-
[item-start] var(--rc-list-padding-inline, 0)
|
|
245
|
-
[leading-start] var(--_rc-list-leading-size) [leading-end]
|
|
246
|
-
var(--_rc-list-leading-gap)
|
|
247
|
-
[content-start] minmax(0, 1fr) [content-end]
|
|
248
|
-
var(--_rc-list-trailing-gap)
|
|
249
|
-
[trailing-start] var(--_rc-list-trailing-size) [trailing-end]
|
|
250
|
-
var(--rc-list-padding-inline, 0) [item-end];
|
|
251
|
-
min-inline-size: 0;
|
|
252
|
-
padding-block: var(--rc-list-padding-block, 0);
|
|
253
|
-
row-gap: var(--rc-list-row-gap, 0);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
::slotted(rc-list-item) {
|
|
257
|
-
grid-column: item-start / item-end;
|
|
258
|
-
}
|
|
259
|
-
`;
|
|
260
|
-
var x = Object.defineProperty, h = (l, t, e, r) => {
|
|
261
|
-
for (var i = void 0, s = l.length - 1, o; s >= 0; s--)
|
|
262
|
-
(o = l[s]) && (i = o(t, e, i) || i);
|
|
263
|
-
return i && x(t, e, i), i;
|
|
264
|
-
};
|
|
265
|
-
const u = class u extends m {
|
|
266
|
-
constructor() {
|
|
267
|
-
super(), this._syncQueued = !1, this._warnedInvalidChildren = /* @__PURE__ */ new WeakSet(), this._warnedInvalidSelection = /* @__PURE__ */ new WeakMap(), this._authoredItemState = /* @__PURE__ */ new Map(), this._mutationObserver = null, this.variant = "standard", this.selection = "none", this._handleChange = (t) => {
|
|
268
|
-
this.selection !== "none" && t.target instanceof HTMLInputElement && t.target.parentElement?.localName === "rc-list-item" && t.target.type === this._expectedInputType() && this._queueSync();
|
|
269
|
-
}, this._internals = this.attachInternals(), this._internals.role = "list";
|
|
270
|
-
}
|
|
271
|
-
connectedCallback() {
|
|
272
|
-
super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "list"), this.addEventListener("change", this._handleChange), typeof MutationObserver == "function" && (this._mutationObserver ??= new MutationObserver(() => this._queueSync()), this._mutationObserver.observe(this, {
|
|
273
|
-
attributes: !0,
|
|
274
|
-
subtree: !0,
|
|
275
|
-
attributeFilter: ["checked", "disabled", "has-leading", "has-trailing", "hidden"]
|
|
276
|
-
}));
|
|
277
|
-
}
|
|
278
|
-
disconnectedCallback() {
|
|
279
|
-
super.disconnectedCallback(), this.removeEventListener("change", this._handleChange), this._mutationObserver?.disconnect(), this._restoreAllItems();
|
|
280
|
-
}
|
|
281
|
-
firstUpdated() {
|
|
282
|
-
this._syncItems();
|
|
283
|
-
}
|
|
284
|
-
updated(t) {
|
|
285
|
-
t.has("selection") && this._queueSync();
|
|
286
|
-
}
|
|
287
|
-
_items() {
|
|
288
|
-
return this._$slot.assignedElements({ flatten: !0 }).filter((t) => t.localName === "rc-list-item");
|
|
289
|
-
}
|
|
290
|
-
_expectedInputType() {
|
|
291
|
-
if (this.selection === "single")
|
|
292
|
-
return "radio";
|
|
293
|
-
if (this.selection === "multiple")
|
|
294
|
-
return "checkbox";
|
|
295
|
-
}
|
|
296
|
-
_inputFor(t) {
|
|
297
|
-
const e = this._expectedInputType();
|
|
298
|
-
return e ? t.querySelector(`:scope > input[type="${e}"]`) : null;
|
|
299
|
-
}
|
|
300
|
-
_queueSync() {
|
|
301
|
-
this._syncQueued || (this._syncQueued = !0, queueMicrotask(() => {
|
|
302
|
-
this._syncQueued = !1, this.isConnected && this.hasUpdated && this._syncItems();
|
|
303
|
-
}));
|
|
304
|
-
}
|
|
305
|
-
_syncItems() {
|
|
306
|
-
this._$slot.assignedElements({ flatten: !0 });
|
|
307
|
-
const t = this._items().filter((r) => !r.hidden), e = this._expectedInputType();
|
|
308
|
-
for (const [r, i] of this._authoredItemState)
|
|
309
|
-
(!t.includes(r) || !e) && (this._restoreItem(r, i), this._authoredItemState.delete(r));
|
|
310
|
-
this.toggleAttribute(
|
|
311
|
-
"has-leading",
|
|
312
|
-
t.some((r) => r.hasAttribute("has-leading"))
|
|
313
|
-
), this.toggleAttribute(
|
|
314
|
-
"has-trailing",
|
|
315
|
-
t.some((r) => r.hasAttribute("has-trailing"))
|
|
316
|
-
);
|
|
317
|
-
for (const [r, i] of t.entries())
|
|
318
|
-
if (i.dataset.rcListPosition = t.length === 1 ? "only" : r === 0 ? "first" : r === t.length - 1 ? "last" : "middle", e) {
|
|
319
|
-
const s = this._inputFor(i);
|
|
320
|
-
this._authoredItemState.has(i) || this._authoredItemState.set(i, {
|
|
321
|
-
disabled: i.disabled,
|
|
322
|
-
interactive: i.interactive,
|
|
323
|
-
selected: i.selected
|
|
324
|
-
}), i.selected = s?.checked ?? !1, i.disabled = s?.disabled ?? !1, i.interactive = !!s;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
_restoreItem(t, e) {
|
|
328
|
-
t.selected = e.selected, t.disabled = e.disabled, t.interactive = e.interactive, delete t.dataset.rcListPosition;
|
|
329
|
-
}
|
|
330
|
-
_restoreAllItems() {
|
|
331
|
-
for (const [t, e] of this._authoredItemState)
|
|
332
|
-
this._restoreItem(t, e);
|
|
333
|
-
this._authoredItemState.clear();
|
|
334
|
-
}
|
|
335
|
-
_handleSlotChange() {
|
|
336
|
-
this._queueSync();
|
|
337
|
-
}
|
|
338
|
-
render() {
|
|
339
|
-
return v`
|
|
340
|
-
<div part="list">
|
|
341
|
-
<slot @slotchange=${this._handleSlotChange}></slot>
|
|
342
|
-
</div>
|
|
343
|
-
`;
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
u.styles = w;
|
|
347
|
-
let d = u;
|
|
348
|
-
h([
|
|
349
|
-
f("slot", !0)
|
|
350
|
-
], d.prototype, "_$slot");
|
|
351
|
-
h([
|
|
352
|
-
n({ reflect: !0 })
|
|
353
|
-
], d.prototype, "variant");
|
|
354
|
-
h([
|
|
355
|
-
n({ reflect: !0 })
|
|
356
|
-
], d.prototype, "selection");
|
|
357
|
-
export {
|
|
358
|
-
d as R,
|
|
359
|
-
a
|
|
360
|
-
};
|
|
361
|
-
//# sourceMappingURL=rc-list-DyOxApRJ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rc-list-DyOxApRJ.js","sources":["../src/rc-list-item.styles.ts","../src/rc-list-item.ts","../src/rc-list.styles.ts","../src/rc-list.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const listItemStyles = css`\n :host {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n min-inline-size: 0;\n color: var(--rc-list-item-color, CanvasText);\n color-scheme: inherit;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n [part='row'] {\n position: relative;\n display: grid;\n box-sizing: border-box;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n grid-template-rows: var(--rc-list-item-grid-template-rows, auto);\n align-items: center;\n row-gap: var(--rc-list-item-row-gap, 0);\n min-block-size: var(--rc-list-item-min-block-size, 3rem);\n min-inline-size: 0;\n padding-block: var(--rc-list-item-padding-block, 0.5rem);\n overflow: clip;\n border: var(--rc-list-item-border, 0);\n border-radius: var(--rc-list-item-border-radius, 0);\n background: var(--rc-list-item-background, transparent);\n box-shadow: var(--rc-list-item-box-shadow, none);\n transition:\n background-color var(--rc-list-item-transition-duration, 0ms)\n var(--rc-list-item-transition-easing, ease),\n box-shadow var(--rc-list-item-transition-duration, 0ms)\n var(--rc-list-item-transition-easing, ease);\n }\n\n [part='state-layer'] {\n position: absolute;\n z-index: 0;\n inset: 0;\n pointer-events: none;\n background: var(--rc-list-item-state-layer-color, currentColor);\n opacity: var(--rc-list-item-state-layer-opacity, 0);\n transition: opacity var(--rc-list-item-transition-duration, 0ms)\n var(--rc-list-item-transition-easing, ease);\n }\n\n [part='leading'],\n [part='content'],\n [part='trailing'] {\n position: relative;\n z-index: 1;\n min-inline-size: 0;\n }\n\n [part='leading'] {\n grid-column: var(--rc-list-item-leading-grid-column, leading-start / leading-end);\n grid-row: var(--rc-list-item-leading-grid-row, auto);\n }\n\n [part='content'] {\n grid-column: var(--rc-list-item-content-grid-column, content-start / content-end);\n grid-row: var(--rc-list-item-content-grid-row, auto);\n overflow: hidden;\n text-overflow: var(--rc-list-item-content-text-overflow, ellipsis);\n white-space: var(--rc-list-item-content-white-space, nowrap);\n }\n\n [part='trailing'] {\n grid-column: var(--rc-list-item-trailing-grid-column, trailing-start / trailing-end);\n grid-row: var(--rc-list-item-trailing-grid-row, auto);\n justify-self: var(--rc-list-item-trailing-justify-self, end);\n }\n\n [part='leading'][hidden],\n [part='trailing'][hidden] {\n display: none;\n }\n\n ::slotted(*) {\n min-inline-size: 0;\n }\n\n [part='content'] ::slotted(*) {\n overflow: hidden;\n text-overflow: inherit;\n }\n\n [part='divider'] {\n position: absolute;\n z-index: 1;\n inset-block-end: 0;\n inset-inline: var(--rc-list-item-divider-inset-inline, 0);\n border-block-end: var(--rc-list-item-divider, 0);\n pointer-events: none;\n }\n\n :host([interactive]:not([disabled])) {\n cursor: pointer;\n }\n\n :host([interactive]:not([disabled]):hover) [part='state-layer'] {\n opacity: var(--rc-list-item-hover-state-layer-opacity, 0.08);\n }\n\n :host([interactive]:not([disabled]):focus-within) [part='state-layer'] {\n opacity: var(--rc-list-item-focus-state-layer-opacity, 0.1);\n }\n\n :host([interactive]:not([disabled]):active) [part='state-layer'] {\n opacity: var(--rc-list-item-pressed-state-layer-opacity, 0.1);\n }\n\n :host([selected]) [part='row'] {\n color: var(--rc-list-item-selected-color, var(--rc-list-item-color, CanvasText));\n background: var(--rc-list-item-selected-background, transparent);\n }\n\n :host([disabled]) {\n cursor: default;\n opacity: var(--rc-list-item-disabled-opacity, 0.38);\n }\n\n @media (forced-colors: active) {\n [part='row'] {\n border-color: CanvasText;\n }\n\n :host([selected]) [part='row'] {\n outline: 2px solid Highlight;\n outline-offset: -2px;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n [part='row'],\n [part='state-layer'] {\n transition-duration: 0ms;\n }\n }\n`;\n\nexport default listItemStyles;\n","import { LitElement, html, type PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport { ClickDelegateController } from '@rcarls/rc-common';\n\nimport listItemStyles from './rc-list-item.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-list-item': RCListItem;\n }\n}\n\n/**\n * A list row whose leading, content, and trailing cells participate in the\n * column grid owned by the nearest `rc-list`.\n *\n * `selected` is presentational state. In a selecting `rc-list`, the group\n * mirrors it from a direct native radio or checkbox, which remains the source\n * of truth. Outside a selecting list, authors may control it directly.\n *\n * An `interactive` row forwards a plain click anywhere on its surface (that\n * hasn't already landed on one of its own interactive descendants — see\n * `@rcarls/rc-common`'s `ClickDelegateController`) to whichever of these\n * resolves first:\n * 1. `action-target`, the same same-root id-ref contract `rc-card` uses —\n * for a row whose primary action is a button/link that isn't itself a\n * selection control (opens a dialog, navigates, etc).\n * 2. A direct-child native `input[type=checkbox]`/`input[type=radio]` —\n * the existing selection-row behavior, unchanged.\n * Both exist because a CSS `::after`-overlay (\"stretched link\") on the\n * slotted control doesn't work here: it would need `[part=content]` as its\n * containing block, but that part's own `overflow: hidden` (required for\n * label truncation) clips the overlay right back down to its own bounds.\n *\n * @slot leading - Optional leading visual or native selection control. Add\n * `data-rc-list-leading` when a theme should apply its standard leading-icon geometry.\n * @slot - Primary row content. It truncates to one line by default.\n * @slot trailing - Optional trailing metadata or action.\n *\n * @csspart row - Row surface and subgrid.\n * @csspart state-layer - Hover, focus, and pressed state layer.\n * @csspart leading - Leading slot wrapper.\n * @csspart content - Default content slot wrapper.\n * @csspart trailing - Trailing slot wrapper.\n * @csspart divider - Row divider.\n *\n * @attr selected - Presentational selected state. Host writes are silent.\n * @attr disabled - Presentational disabled state. Host writes are silent.\n * @attr interactive - Enables row interaction styling and click delegation.\n * @attr action-target - ID of a same-root anchor or button that receives\n * forwarded surface clicks.\n * @attr [has-leading] - Reflected when the leading slot has content.\n * @attr [has-trailing] - Reflected when the trailing slot has content.\n * @attr [data-rc-list-position] - Visible row position assigned by the parent list.\n *\n * @cssprop [--rc-list-item-min-block-size=3rem] - Minimum rendered row height.\n * @cssprop [--rc-list-item-padding-block=0.5rem] - Row block padding.\n * @cssprop [--rc-list-item-color=CanvasText] - Row foreground color.\n * @cssprop [--rc-list-item-background=transparent] - Row surface color.\n * @cssprop [--rc-list-item-selected-color] - Selected foreground color.\n * @cssprop [--rc-list-item-selected-background=transparent] - Selected surface color.\n * @cssprop [--rc-list-item-border=0] - Row border shorthand.\n * @cssprop [--rc-list-item-border-radius=0] - Row corner radius.\n * @cssprop [--rc-list-item-box-shadow=none] - Row shadow.\n * @cssprop [--rc-list-item-divider=0] - Divider border shorthand.\n * @cssprop [--rc-list-item-divider-inset-inline=0] - Divider inline inset.\n * @cssprop [--rc-list-item-grid-template-rows=auto] - Internal row track definition.\n * @cssprop [--rc-list-item-row-gap=0] - Gap between internal row tracks.\n * @cssprop [--rc-list-item-leading-grid-column=leading-start / leading-end] - Leading region column placement.\n * @cssprop [--rc-list-item-leading-grid-row=auto] - Leading region row placement.\n * @cssprop [--rc-list-item-content-grid-column=content-start / content-end] - Content region column placement.\n * @cssprop [--rc-list-item-content-grid-row=auto] - Content region row placement.\n * @cssprop [--rc-list-item-content-white-space=nowrap] - Content wrapping behavior.\n * @cssprop [--rc-list-item-content-text-overflow=ellipsis] - Content overflow marker.\n * @cssprop [--rc-list-item-trailing-grid-column=trailing-start / trailing-end] - Trailing region column placement.\n * @cssprop [--rc-list-item-trailing-grid-row=auto] - Trailing region row placement.\n * @cssprop [--rc-list-item-trailing-justify-self=end] - Trailing region alignment within its grid area.\n * @cssprop [--rc-list-item-state-layer-color=currentColor] - Interaction state layer color.\n * @cssprop [--rc-list-item-state-layer-opacity=0] - Resting interaction state layer opacity.\n * @cssprop [--rc-list-item-hover-state-layer-opacity=0.08] - Hover state opacity.\n * @cssprop [--rc-list-item-focus-state-layer-opacity=0.1] - Focus state opacity.\n * @cssprop [--rc-list-item-pressed-state-layer-opacity=0.1] - Pressed state opacity.\n * @cssprop [--rc-list-item-disabled-opacity=0.38] - Disabled row opacity.\n * @cssprop [--rc-list-item-transition-duration=0ms] - Row state transition duration.\n * @cssprop [--rc-list-item-transition-easing=ease] - Row state transition easing.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-list rc-list documentation}\n */\nexport class RCListItem extends LitElement {\n static override styles = listItemStyles;\n\n private readonly _internals: ElementInternals;\n\n /** Presentational selected state. Host writes are silent. */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n /** Presentational disabled state. Host writes are silent. */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Enables row interaction styling. */\n @property({ type: Boolean, reflect: true })\n interactive = false;\n\n /**\n * ID of a same-root anchor or button that receives forwarded surface\n * clicks — the same contract as `rc-card`'s `action-target`. Checked\n * before the native radio/checkbox fallback, so a row can combine a\n * selection input with its own `action-target` if it ever needs to\n * (uncommon, but not fought against).\n */\n @property({ type: String, attribute: 'action-target' })\n actionTarget = '';\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n this._internals.role = 'listitem';\n\n new ClickDelegateController(this, {\n target: () => this._resolveActionTarget() ?? this._nativeInput(),\n disabled: () => !this.interactive || this.disabled,\n });\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'listitem');\n }\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n if (!import.meta.env.DEV) {\n return;\n }\n\n if (!changed.has('interactive') && !changed.has('actionTarget')) {\n return;\n }\n\n if (this.interactive && !this.actionTarget.trim() && !this._nativeInput()) {\n console.warn(\n `[rc-list-item] interactive is set with no action-target and no direct-child ` +\n `checkbox/radio, so surface clicks have nothing to forward to. Set action-target ` +\n `to a same-root <a> or <button>, or add one of those as a direct child.`,\n this,\n );\n }\n }\n\n private _hasAssignedElements(event: Event): boolean {\n return (event.currentTarget as HTMLSlotElement)\n .assignedNodes({ flatten: true })\n .some(($node) => {\n return $node.nodeType !== Node.TEXT_NODE || Boolean($node.textContent?.trim());\n });\n }\n\n private _handleNamedSlotChange(event: Event): void {\n const $slot = event.currentTarget as HTMLSlotElement;\n\n this.toggleAttribute(`has-${$slot.name}`, this._hasAssignedElements(event));\n }\n\n private _nativeInput(): HTMLInputElement | null {\n return this.querySelector(':scope > input:is([type=\"checkbox\"], [type=\"radio\"])');\n }\n\n private _resolveActionTarget(): HTMLAnchorElement | HTMLButtonElement | null {\n const id = this.actionTarget.trim();\n\n if (!id) {\n return null;\n }\n\n const $root = this.getRootNode();\n const $target =\n $root instanceof Document || $root instanceof ShadowRoot ? $root.getElementById(id) : null;\n\n if ($target instanceof HTMLAnchorElement || $target instanceof HTMLButtonElement) {\n return $target;\n }\n\n if (import.meta.env.DEV) {\n console.warn(\n `[rc-list-item] action-target=\"${id}\" must reference a same-root <a> or <button>.`,\n );\n }\n\n return null;\n }\n\n protected override firstUpdated(): void {\n for (const $slot of this.shadowRoot?.querySelectorAll<HTMLSlotElement>('slot[name]') ?? []) {\n this.toggleAttribute(`has-${$slot.name}`, $slot.assignedNodes({ flatten: true }).length > 0);\n }\n }\n\n protected override render() {\n return html`\n <div part=\"row\">\n <span part=\"state-layer\" aria-hidden=\"true\"></span>\n <span part=\"leading\">\n <slot name=\"leading\" @slotchange=${this._handleNamedSlotChange}></slot>\n </span>\n <span part=\"content\"><slot></slot></span>\n <span part=\"trailing\">\n <slot name=\"trailing\" @slotchange=${this._handleNamedSlotChange}></slot>\n </span>\n <span part=\"divider\" aria-hidden=\"true\"></span>\n </div>\n `;\n }\n}\n","import { css } from 'lit';\n\nexport const listStyles = css`\n :host {\n --_rc-list-leading-gap: 0;\n --_rc-list-leading-size: 0;\n --_rc-list-trailing-gap: 0;\n --_rc-list-trailing-size: 0;\n\n display: block;\n min-inline-size: 0;\n color-scheme: inherit;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n :host([has-leading]) {\n --_rc-list-leading-gap: var(--rc-list-leading-gap, 1rem);\n --_rc-list-leading-size: var(--rc-list-leading-size, minmax(0, max-content));\n }\n\n :host([has-trailing]) {\n --_rc-list-trailing-gap: var(--rc-list-trailing-gap, 1rem);\n --_rc-list-trailing-size: var(--rc-list-trailing-size, minmax(0, max-content));\n }\n\n [part='list'] {\n display: grid;\n grid-template-columns:\n [item-start] var(--rc-list-padding-inline, 0)\n [leading-start] var(--_rc-list-leading-size) [leading-end]\n var(--_rc-list-leading-gap)\n [content-start] minmax(0, 1fr) [content-end]\n var(--_rc-list-trailing-gap)\n [trailing-start] var(--_rc-list-trailing-size) [trailing-end]\n var(--rc-list-padding-inline, 0) [item-end];\n min-inline-size: 0;\n padding-block: var(--rc-list-padding-block, 0);\n row-gap: var(--rc-list-row-gap, 0);\n }\n\n ::slotted(rc-list-item) {\n grid-column: item-start / item-end;\n }\n`;\n\nexport default listStyles;\n","import { LitElement, html } from 'lit';\nimport { property, query } from 'lit/decorators.js';\n\nimport type { RCListItem } from './rc-list-item.js';\n\nimport listStyles from './rc-list.styles.js';\n\nexport type RCListVariant = 'standard' | 'segmented';\nexport type RCListSelection = 'none' | 'single' | 'multiple';\n\ninterface AuthoredItemState {\n disabled: boolean;\n interactive: boolean;\n selected: boolean;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-list': RCList;\n }\n}\n\n/**\n * Shared-column list layout with optional native-backed selection.\n *\n * In `single` and `multiple` selection modes, each direct `rc-list-item`\n * must contain one direct native radio or checkbox respectively. Native\n * checked and disabled state remain authoritative; the list only mirrors\n * them to the row for styling and makes non-control row surfaces operable.\n *\n * @slot - Direct `rc-list-item` children.\n *\n * @csspart list - Shared list grid.\n *\n * @attr variant - Appearance hint: `standard` or `segmented`.\n * @attr selection - Native selection coordination: `none`, `single`, or `multiple`.\n * @attr [has-leading] - Reflected when a visible item uses the leading slot.\n * @attr [has-trailing] - Reflected when a visible item uses the trailing slot.\n *\n * @cssprop [--rc-list-padding-inline=0] - Shared inline content padding.\n * @cssprop [--rc-list-padding-block=0] - List block padding.\n * @cssprop [--rc-list-leading-size=minmax(0, max-content)] - Shared leading column size when any visible item has leading content.\n * @cssprop [--rc-list-leading-gap=1rem] - Gap after the leading column.\n * @cssprop [--rc-list-trailing-size=minmax(0, max-content)] - Shared trailing column size when any visible item has trailing content.\n * @cssprop [--rc-list-trailing-gap=1rem] - Gap before the trailing column.\n * @cssprop [--rc-list-row-gap=0] - Gap between rows.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-list rc-list documentation}\n * @see {@link https://m3.material.io/components/lists/overview Material Design lists}\n */\nexport class RCList extends LitElement {\n static override styles = listStyles;\n\n private readonly _internals: ElementInternals;\n private _syncQueued = false;\n private readonly _warnedInvalidChildren = new WeakSet<Element>();\n private readonly _warnedInvalidSelection = new WeakMap<RCListItem, RCListSelection>();\n private readonly _authoredItemState = new Map<RCListItem, AuthoredItemState>();\n\n @query('slot', true)\n private _$slot!: HTMLSlotElement;\n\n private _mutationObserver: MutationObserver | null = null;\n\n /** Appearance hint. */\n @property({ reflect: true })\n variant: RCListVariant = 'standard';\n\n /** Native selection coordination mode. */\n @property({ reflect: true })\n selection: RCListSelection = 'none';\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n this._internals.role = 'list';\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'list');\n }\n\n this.addEventListener('change', this._handleChange);\n\n if (typeof MutationObserver === 'function') {\n this._mutationObserver ??= new MutationObserver(() => this._queueSync());\n\n this._mutationObserver.observe(this, {\n attributes: true,\n subtree: true,\n attributeFilter: ['checked', 'disabled', 'has-leading', 'has-trailing', 'hidden'],\n });\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('change', this._handleChange);\n this._mutationObserver?.disconnect();\n this._restoreAllItems();\n }\n\n protected override firstUpdated(): void {\n this._syncItems();\n }\n\n protected override updated(changed: Map<PropertyKey, unknown>): void {\n if (changed.has('selection')) {\n this._queueSync();\n }\n }\n\n private _items(): RCListItem[] {\n return this._$slot\n .assignedElements({ flatten: true })\n .filter((element): element is RCListItem => element.localName === 'rc-list-item');\n }\n\n private _expectedInputType(): 'radio' | 'checkbox' | undefined {\n if (this.selection === 'single') {\n return 'radio';\n }\n\n if (this.selection === 'multiple') {\n return 'checkbox';\n }\n\n return undefined;\n }\n\n private _inputFor(item: RCListItem): HTMLInputElement | null {\n const expectedType = this._expectedInputType();\n\n if (!expectedType) {\n return null;\n }\n\n return item.querySelector(`:scope > input[type=\"${expectedType}\"]`);\n }\n\n private _queueSync(): void {\n if (this._syncQueued) {\n return;\n }\n\n this._syncQueued = true;\n\n queueMicrotask(() => {\n this._syncQueued = false;\n\n if (this.isConnected && this.hasUpdated) {\n this._syncItems();\n }\n });\n }\n\n private _syncItems(): void {\n const assigned = this._$slot.assignedElements({ flatten: true });\n const items = this._items().filter((item) => !item.hidden);\n const expectedType = this._expectedInputType();\n\n for (const [$item, state] of this._authoredItemState) {\n if (!items.includes($item) || !expectedType) {\n this._restoreItem($item, state);\n this._authoredItemState.delete($item);\n }\n }\n\n this.toggleAttribute(\n 'has-leading',\n items.some((item) => item.hasAttribute('has-leading')),\n );\n\n this.toggleAttribute(\n 'has-trailing',\n items.some((item) => item.hasAttribute('has-trailing')),\n );\n\n for (const [index, item] of items.entries()) {\n item.dataset.rcListPosition =\n items.length === 1\n ? 'only'\n : index === 0\n ? 'first'\n : index === items.length - 1\n ? 'last'\n : 'middle';\n\n if (expectedType) {\n const input = this._inputFor(item);\n\n if (!this._authoredItemState.has(item)) {\n this._authoredItemState.set(item, {\n disabled: item.disabled,\n interactive: item.interactive,\n selected: item.selected,\n });\n }\n\n item.selected = input?.checked ?? false;\n item.disabled = input?.disabled ?? false;\n item.interactive = Boolean(input);\n }\n }\n\n if (import.meta.env.DEV) {\n const invalidChildren = assigned.filter(\n (element) =>\n element.localName !== 'rc-list-item' && !this._warnedInvalidChildren.has(element),\n );\n\n if (invalidChildren.length > 0) {\n console.warn('[rc-list] Direct children should be rc-list-item elements.', invalidChildren);\n invalidChildren.forEach((element) => this._warnedInvalidChildren.add(element));\n }\n\n if (expectedType) {\n const invalidItems = items.filter(\n (item) =>\n !this._inputFor(item) && this._warnedInvalidSelection.get(item) !== this.selection,\n );\n\n if (invalidItems.length > 0) {\n console.warn(\n `[rc-list] selection=\"${this.selection}\" expects each rc-list-item to contain a direct native ${expectedType} input.`,\n invalidItems,\n );\n\n invalidItems.forEach((item) => this._warnedInvalidSelection.set(item, this.selection));\n }\n }\n }\n }\n\n private _restoreItem($item: RCListItem, state: AuthoredItemState): void {\n $item.selected = state.selected;\n $item.disabled = state.disabled;\n $item.interactive = state.interactive;\n delete $item.dataset.rcListPosition;\n }\n\n private _restoreAllItems(): void {\n for (const [$item, state] of this._authoredItemState) {\n this._restoreItem($item, state);\n }\n\n this._authoredItemState.clear();\n }\n\n private readonly _handleChange = (event: Event): void => {\n if (\n this.selection !== 'none' &&\n event.target instanceof HTMLInputElement &&\n event.target.parentElement?.localName === 'rc-list-item' &&\n event.target.type === this._expectedInputType()\n ) {\n this._queueSync();\n }\n };\n\n private _handleSlotChange(): void {\n this._queueSync();\n }\n\n protected override render() {\n return html`\n <div part=\"list\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n"],"names":["listItemStyles","css","_RCListItem","LitElement","ClickDelegateController","changed","event","$node","$slot","id","$root","$target","html","RCListItem","__decorateClass","property","listStyles","_RCList","element","item","expectedType","items","$item","state","index","input","RCList","query"],"mappings":"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"}
|