@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.
@@ -0,0 +1,325 @@
1
+ import { css as b, LitElement as _, html as f } from "lit";
2
+ import { property as n, query as y } from "lit/decorators.js";
3
+ import { ClickDelegateController as x, cssText as w, ReorderController as A, observeLocale as S } from "@rcarls/rc-common";
4
+ const I = b`:host{grid-column:1/-1;grid-template-columns:subgrid;isolation:isolate;min-inline-size:0;color:var(--rc-list-item-color,CanvasText);color-scheme:inherit;display:grid}:host([hidden]){display:none}[part=row]{box-sizing:border-box;grid-column:1/-1;grid-template-columns:subgrid;grid-template-rows:var(--rc-list-item-grid-template-rows,auto);align-items:center;row-gap:var(--rc-list-item-row-gap,0);min-block-size:var(--rc-list-item-min-block-size,3rem);min-inline-size:0;padding-block:var(--rc-list-item-padding-block,.5rem);border:var(--rc-list-item-border,0);border-radius:var(--rc-list-item-border-radius,0);background:var(--rc-list-item-background,transparent);box-shadow:var(--rc-list-item-box-shadow,none);transition:background-color var(--rc-list-item-transition-duration,0s) var(--rc-list-item-transition-easing,ease), box-shadow var(--rc-list-item-transition-duration,0s) var(--rc-list-item-transition-easing,ease);display:grid;position:relative;overflow:clip}[part=state-layer]{z-index:0;pointer-events:none;background:var(--rc-list-item-state-layer-color,currentColor);opacity:var(--rc-list-item-state-layer-opacity,0);transition:opacity var(--rc-list-item-transition-duration,0s) var(--rc-list-item-transition-easing,ease);position:absolute;inset:0}[part=leading],[part=content],[part=trailing]{z-index:1;min-inline-size:0;position:relative}[part=leading]{grid-column:var(--rc-list-item-leading-grid-column,leading-start / leading-end);grid-row:var(--rc-list-item-leading-grid-row,auto)}[part=content]{grid-column:var(--rc-list-item-content-grid-column,content-start / content-end);grid-row:var(--rc-list-item-content-grid-row,auto);text-overflow:var(--rc-list-item-content-text-overflow,ellipsis);white-space:var(--rc-list-item-content-white-space,nowrap);overflow:hidden}[part=trailing]{grid-column:var(--rc-list-item-trailing-grid-column,trailing-start / trailing-end);grid-row:var(--rc-list-item-trailing-grid-row,auto);justify-self:var(--rc-list-item-trailing-justify-self,end)}[part=leading][hidden],[part=trailing][hidden],[part=details][hidden]{display:none}[part=details]{z-index:1;grid-column:var(--rc-list-item-details-grid-column,content-start / trailing-end);min-inline-size:0;color:var(--rc-list-item-details-color,inherit);animation:rc-list-item-details-reveal var(--rc-list-item-details-duration,0s) var(--rc-list-item-transition-easing,ease);padding-block-end:var(--rc-list-item-details-padding-block-end,0);position:relative}@keyframes rc-list-item-details-reveal{0%{opacity:0}}::slotted(*){min-inline-size:0}::slotted([slot=trailing][aria-hidden=true]){pointer-events:none}[part=content] ::slotted(*){text-overflow:inherit;overflow:hidden}[part=divider]{z-index:1;inset-block-end:0;inset-inline:var(--rc-list-item-divider-inset-inline,0);border-block-end:var(--rc-list-item-divider,0);pointer-events:none;position:absolute}:host([interactive]:not([disabled])){cursor:pointer}:host([interactive]:not([disabled]):hover) [part=state-layer]{opacity:var(--rc-list-item-hover-state-layer-opacity,.08)}:host([interactive]:not([disabled]):focus-within) [part=state-layer]{opacity:var(--rc-list-item-focus-state-layer-opacity,.1)}:host([interactive]:not([disabled]):active) [part=state-layer]{opacity:var(--rc-list-item-pressed-state-layer-opacity,.1)}:host([selected]) [part=row]{color:var(--rc-list-item-selected-color,var(--rc-list-item-color,CanvasText));background:var(--rc-list-item-selected-background,transparent)}:host([data-dragging]){z-index:1;position:relative}:host([data-dragging]) [part=row]{background:var(--rc-list-item-dragged-background,var(--rc-list-item-background,Canvas));box-shadow:var(--rc-list-item-dragged-box-shadow,var(--rc-list-item-box-shadow,none))}:host([data-dragging]) [part=state-layer]{opacity:var(--rc-list-item-dragged-state-layer-opacity,.16)}:host([disabled]){cursor:default;opacity:var(--rc-list-item-disabled-opacity,.38)}@media (forced-colors:active){[part=row]{border-color:canvastext}:host([selected]) [part=row],:host([data-dragging]) [part=row]{outline-offset:-2px;outline:2px solid highlight}}@media (prefers-reduced-motion:reduce){[part=row],[part=state-layer]{transition-duration:50ms}[part=details]{animation-duration:min(var(--rc-list-item-details-duration,0s), 50ms)}}`;
5
+ var k = Object.defineProperty, E = Object.getOwnPropertyDescriptor, c = (a, e, t, s) => {
6
+ for (var i = s > 1 ? void 0 : s ? E(e, t) : e, r = a.length - 1, o; r >= 0; r--)
7
+ (o = a[r]) && (i = (s ? o(e, t, i) : o(i)) || i);
8
+ return s && i && k(e, t, i), i;
9
+ };
10
+ const C = "[data-rc-list-item-toggle]";
11
+ let z = 0;
12
+ const p = class p extends _ {
13
+ constructor() {
14
+ super(), this.selected = !1, this.disabled = !1, this.interactive = !1, this.actionTarget = "", this.defaultExpanded = !1, this._hasDetails = !1, this._handleToggleClick = (e) => {
15
+ const t = this._toggle();
16
+ if (!t || !e.composedPath().includes(t) || !this._details())
17
+ return;
18
+ const s = !this.expanded;
19
+ if (this._controlledExpanded === void 0) {
20
+ const i = this.expanded;
21
+ this._uncontrolledExpanded = s, this.requestUpdate("expanded", i);
22
+ }
23
+ this.dispatchEvent(
24
+ new CustomEvent("rc-list-item-toggle", {
25
+ bubbles: !0,
26
+ composed: !0,
27
+ detail: { expanded: s }
28
+ })
29
+ );
30
+ }, this._internals = this.attachInternals(), this._internals.role = "listitem", this.addEventListener("click", this._handleToggleClick), new x(this, {
31
+ target: () => this._resolveActionTarget() ?? this._nativeInput(),
32
+ disabled: () => !this.interactive || this.disabled
33
+ });
34
+ }
35
+ get expanded() {
36
+ return this._controlledExpanded ?? this._uncontrolledExpanded ?? this.defaultExpanded;
37
+ }
38
+ set expanded(e) {
39
+ const t = this.expanded;
40
+ this._controlledExpanded = e ?? void 0, this.requestUpdate("expanded", t);
41
+ }
42
+ connectedCallback() {
43
+ super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "listitem");
44
+ }
45
+ updated(e) {
46
+ this._syncDetails();
47
+ }
48
+ _hasAssignedElements(e) {
49
+ return e.currentTarget.assignedNodes({ flatten: !0 }).some((t) => t.nodeType !== Node.TEXT_NODE || !!t.textContent?.trim());
50
+ }
51
+ _handleNamedSlotChange(e) {
52
+ const t = e.currentTarget;
53
+ this.toggleAttribute(`has-${t.name}`, this._hasAssignedElements(e)), this._syncDetails();
54
+ }
55
+ _handleDetailsSlotChange(e) {
56
+ const t = this._hasAssignedElements(e);
57
+ t !== this._hasDetails && (this._hasDetails = t, this.requestUpdate()), this._syncDetails();
58
+ }
59
+ _toggle() {
60
+ const e = this.querySelector(C);
61
+ return e?.closest("rc-list-item") === this ? e : null;
62
+ }
63
+ _details() {
64
+ return this.querySelector(':scope > [slot="details"]');
65
+ }
66
+ /** Mirror the expanded state to the authored toggle and details region. */
67
+ _syncDetails() {
68
+ const e = this._details(), t = this._toggle(), s = this.expanded;
69
+ e && (e.id || (e.id = `rc-list-item-details-${++z}`), e.hidden = !s), t && (t.setAttribute("aria-expanded", String(s)), e ? t.setAttribute("aria-controls", e.id) : t.removeAttribute("aria-controls"));
70
+ }
71
+ _nativeInput() {
72
+ return this.querySelector(':scope > input:is([type="checkbox"], [type="radio"])');
73
+ }
74
+ _resolveActionTarget() {
75
+ const e = this.actionTarget.trim();
76
+ if (!e)
77
+ return null;
78
+ const t = this.getRootNode(), s = t instanceof Document || t instanceof ShadowRoot ? t.getElementById(e) : null;
79
+ return s instanceof HTMLAnchorElement || s instanceof HTMLButtonElement ? s : null;
80
+ }
81
+ firstUpdated() {
82
+ for (const e of this.shadowRoot?.querySelectorAll("slot[name]") ?? [])
83
+ this.toggleAttribute(`has-${e.name}`, e.assignedNodes({ flatten: !0 }).length > 0);
84
+ }
85
+ render() {
86
+ return f`
87
+ <div part="row">
88
+ <span part="state-layer" aria-hidden="true"></span>
89
+ <span part="leading">
90
+ <slot name="leading" @slotchange=${this._handleNamedSlotChange}></slot>
91
+ </span>
92
+ <span part="content"><slot></slot></span>
93
+ <span part="trailing">
94
+ <slot name="trailing" @slotchange=${this._handleNamedSlotChange}></slot>
95
+ </span>
96
+ <div part="details" ?hidden=${!this._hasDetails || !this.expanded}>
97
+ <slot name="details" @slotchange=${this._handleDetailsSlotChange}></slot>
98
+ </div>
99
+ <span part="divider" aria-hidden="true"></span>
100
+ </div>
101
+ `;
102
+ }
103
+ };
104
+ p.styles = I;
105
+ let l = p;
106
+ c([
107
+ n({ type: Boolean, reflect: !0 })
108
+ ], l.prototype, "selected", 2);
109
+ c([
110
+ n({ type: Boolean, reflect: !0 })
111
+ ], l.prototype, "disabled", 2);
112
+ c([
113
+ n({ type: Boolean, reflect: !0 })
114
+ ], l.prototype, "interactive", 2);
115
+ c([
116
+ n({ type: String, attribute: "action-target" })
117
+ ], l.prototype, "actionTarget", 2);
118
+ c([
119
+ n({ type: Boolean, attribute: "default-expanded" })
120
+ ], l.prototype, "defaultExpanded", 2);
121
+ c([
122
+ n({ type: Boolean, reflect: !0, noAccessor: !0 })
123
+ ], l.prototype, "expanded", 1);
124
+ const T = w`@layer rc-base{rc-list[reorderable] [data-rc-reorder-handle]{touch-action:none;cursor:grab}rc-list[data-reordering]{-webkit-user-select:none;user-select:none}rc-list[data-reordering] [data-rc-reorder-handle]{cursor:grabbing}rc-list[data-reordering]>rc-list-item:not([data-dragging]){transition:translate var(--rc-list-item-reorder-duration,0s) var(--rc-list-item-reorder-easing,ease)}@media (prefers-reduced-motion:reduce){rc-list[data-reordering]>rc-list-item{transition-duration:0s}}}`, m = /* @__PURE__ */ new WeakSet();
125
+ function D(a) {
126
+ if (m.has(a))
127
+ return;
128
+ m.add(a);
129
+ const e = (a instanceof Document ? a : a.ownerDocument).createElement("style");
130
+ e.setAttribute("data-rc-light-dom-base", "rc-list"), e.textContent = T, a instanceof Document ? a.head.append(e) : a.append(e);
131
+ }
132
+ const $ = b`:host{--_rc-list-leading-gap:0;--_rc-list-leading-size:0;--_rc-list-trailing-gap:0;--_rc-list-trailing-size:0;min-inline-size:0;color-scheme:inherit;display:block}:host([hidden]){display:none}:host([has-leading]){--_rc-list-leading-gap:var(--rc-list-leading-gap,1rem);--_rc-list-leading-size:var(--rc-list-leading-size,minmax(0, max-content))}:host([has-trailing]){--_rc-list-trailing-gap:var(--rc-list-trailing-gap,1rem);--_rc-list-trailing-size:var(--rc-list-trailing-size,minmax(0, max-content))}[part=list]{grid-template-columns:[item-start] var(--rc-list-padding-inline,0) [leading-start] var(--_rc-list-leading-size) [leading-end] var(--_rc-list-leading-gap) [content-start] minmax(0, 1fr) [content-end] var(--_rc-list-trailing-gap) [trailing-start] var(--_rc-list-trailing-size) [trailing-end] var(--rc-list-padding-inline,0) [item-end];min-inline-size:0;padding-block:var(--rc-list-padding-block,0);row-gap:var(--rc-list-row-gap,0);display:grid}::slotted(rc-list-item){grid-column:item-start/item-end}:host([reorderable]) ::slotted(rc-list-item){-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}`;
133
+ var O = Object.defineProperty, h = (a, e, t, s) => {
134
+ for (var i = void 0, r = a.length - 1, o; r >= 0; r--)
135
+ (o = a[r]) && (i = o(e, t, i) || i);
136
+ return i && O(e, t, i), i;
137
+ };
138
+ const v = "[data-rc-reorder-handle]";
139
+ function u(a, e, t) {
140
+ a.getAttribute(e) !== t && a.setAttribute(e, t);
141
+ }
142
+ function q(a, e, t) {
143
+ const s = Number(a.getAttribute("aria-posinset")), i = Number(a.getAttribute("aria-setsize")), [r, o] = s > 0 && i > 0 ? [s - 1, i] : [e, t];
144
+ return o === 1 ? "only" : r === 0 ? "first" : r === o - 1 ? "last" : "middle";
145
+ }
146
+ const g = class g extends _ {
147
+ constructor() {
148
+ super(), this._syncQueued = !1, this._warnedInvalidChildren = /* @__PURE__ */ new WeakSet(), this._warnedInvalidSelection = /* @__PURE__ */ new WeakMap(), this._authoredItemState = /* @__PURE__ */ new Map(), this._mutationObserver = null, this._unobserveLocale = null, this.variant = "standard", this.selection = "none", this.ordered = !1, this.reorderable = !1, this._describedHandles = /* @__PURE__ */ new Map(), this._positionedItems = /* @__PURE__ */ new Map(), this._handleChange = (e) => {
149
+ this.selection !== "none" && e.target instanceof HTMLInputElement && e.target.parentElement?.localName === "rc-list-item" && e.target.type === this._expectedInputType() && this._queueSync();
150
+ }, this._internals = this.attachInternals(), this._internals.role = "list", this._reorder = new A(this, {
151
+ items: () => this.reorderable ? this._visibleItems() : [],
152
+ handleSelector: v,
153
+ disabled: () => !this.reorderable,
154
+ messages: () => this.reorderMessages,
155
+ onMove: (e, t, s) => this._moveItem(e, t, s),
156
+ onActiveChange: (e) => {
157
+ this.toggleAttribute("data-reordering", e !== null), this._items().forEach((t) => t.toggleAttribute("data-dragging", t === e));
158
+ }
159
+ });
160
+ }
161
+ connectedCallback() {
162
+ super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "list"), this.addEventListener("change", this._handleChange), this._unobserveLocale ??= S(() => this._queueSync(), this);
163
+ const e = this.getRootNode();
164
+ D(e instanceof ShadowRoot ? e : this.ownerDocument), typeof MutationObserver == "function" && (this._mutationObserver ??= new MutationObserver(() => this._queueSync()), this._mutationObserver.observe(this, {
165
+ attributes: !0,
166
+ childList: !0,
167
+ subtree: !0,
168
+ attributeFilter: [
169
+ "aria-description",
170
+ "aria-posinset",
171
+ "aria-setsize",
172
+ "checked",
173
+ "disabled",
174
+ "has-leading",
175
+ "has-trailing",
176
+ "hidden"
177
+ ]
178
+ }));
179
+ }
180
+ disconnectedCallback() {
181
+ super.disconnectedCallback(), this.removeEventListener("change", this._handleChange), this._mutationObserver?.disconnect(), this._unobserveLocale?.(), this._unobserveLocale = null, this._restoreAllItems();
182
+ }
183
+ firstUpdated() {
184
+ this._syncItems();
185
+ }
186
+ updated(e) {
187
+ (e.has("selection") || e.has("ordered") || e.has("reorderable") || e.has("reorderMessages")) && this._queueSync(), e.has("reorderable") && !this.reorderable && this._reorder.active && this._reorder.cancel();
188
+ }
189
+ _items() {
190
+ return this._$slot.assignedElements({ flatten: !0 }).filter((e) => e.localName === "rc-list-item");
191
+ }
192
+ _visibleItems() {
193
+ return this._items().filter((e) => !e.hidden);
194
+ }
195
+ _expectedInputType() {
196
+ if (this.selection === "single")
197
+ return "radio";
198
+ if (this.selection === "multiple")
199
+ return "checkbox";
200
+ }
201
+ _inputFor(e) {
202
+ const t = this._expectedInputType();
203
+ return t ? e.querySelector(`:scope > input[type="${t}"]`) : null;
204
+ }
205
+ _queueSync() {
206
+ this._syncQueued || (this._syncQueued = !0, queueMicrotask(() => {
207
+ this._syncQueued = !1, this.isConnected && this.hasUpdated && this._syncItems();
208
+ }));
209
+ }
210
+ _syncItems() {
211
+ this._$slot.assignedElements({ flatten: !0 });
212
+ const e = this._visibleItems(), t = this._expectedInputType();
213
+ for (const [s, i] of this._authoredItemState)
214
+ (!e.includes(s) || !t) && (this._restoreItem(s, i), this._authoredItemState.delete(s));
215
+ this.toggleAttribute(
216
+ "has-leading",
217
+ e.some((s) => s.hasAttribute("has-leading"))
218
+ ), this.toggleAttribute(
219
+ "has-trailing",
220
+ e.some((s) => s.hasAttribute("has-trailing"))
221
+ ), this._syncOrderedPositions(e), this._syncHandleDescriptions(e);
222
+ for (const [s, i] of e.entries())
223
+ if (i.dataset.rcListPosition = q(i, s, e.length), t) {
224
+ const r = this._inputFor(i);
225
+ this._authoredItemState.has(i) || this._authoredItemState.set(i, {
226
+ disabled: i.disabled,
227
+ interactive: i.interactive,
228
+ selected: i.selected
229
+ }), i.selected = r?.checked ?? !1, i.disabled = r?.disabled ?? !1, i.interactive = !!r;
230
+ }
231
+ }
232
+ /**
233
+ * Expose each visible item's position in an ordered list. Items that carry
234
+ * authored positions (a virtualized slice) keep them; positions this list
235
+ * wrote are released when the item leaves or the list stops being ordered.
236
+ */
237
+ _syncOrderedPositions(e) {
238
+ for (const [t, s] of this._positionedItems)
239
+ t.getAttribute("aria-posinset") !== s.posinset || t.getAttribute("aria-setsize") !== s.setsize ? this._positionedItems.delete(t) : (!this._isOrdered() || !e.includes(t)) && this._releasePosition(t);
240
+ if (this._isOrdered())
241
+ for (const [t, s] of e.entries()) {
242
+ if (!this._positionedItems.has(s) && s.hasAttribute("aria-posinset"))
243
+ continue;
244
+ const i = { posinset: String(t + 1), setsize: String(e.length) };
245
+ this._positionedItems.set(s, i), u(s, "aria-posinset", i.posinset), u(s, "aria-setsize", i.setsize);
246
+ }
247
+ }
248
+ _isOrdered() {
249
+ return this.ordered || this.reorderable;
250
+ }
251
+ /**
252
+ * Give each handle a keyboard hint unless its author described it. A
253
+ * description the author rewrites afterward is theirs from then on.
254
+ */
255
+ _syncHandleDescriptions(e) {
256
+ const t = this.reorderable ? e.flatMap((i) => [...i.querySelectorAll(v)]) : [], s = this._reorder.message("instructions");
257
+ for (const [i, r] of this._describedHandles)
258
+ i.getAttribute("aria-description") !== r ? this._describedHandles.delete(i) : (!t.includes(i) || r !== s) && (i.removeAttribute("aria-description"), this._describedHandles.delete(i));
259
+ for (const i of t)
260
+ !this._describedHandles.has(i) && i.hasAttribute("aria-description") || (this._describedHandles.set(i, s), u(i, "aria-description", s));
261
+ }
262
+ /** Dispatch a reorder and, unless a consumer took it over, move the node. */
263
+ _moveItem(e, t, s) {
264
+ const i = new CustomEvent("rc-list-reorder", {
265
+ bubbles: !0,
266
+ composed: !0,
267
+ cancelable: !0,
268
+ detail: { item: e, from: t, to: s }
269
+ });
270
+ if (!this.dispatchEvent(i))
271
+ return;
272
+ const r = this._visibleItems()[s];
273
+ !r || r === e || (s > t ? r.after(e) : r.before(e));
274
+ }
275
+ _releasePosition(e) {
276
+ e.removeAttribute("aria-posinset"), e.removeAttribute("aria-setsize"), this._positionedItems.delete(e);
277
+ }
278
+ _restoreItem(e, t) {
279
+ e.selected = t.selected, e.disabled = t.disabled, e.interactive = t.interactive, delete e.dataset.rcListPosition;
280
+ }
281
+ _restoreAllItems() {
282
+ for (const [e, t] of this._authoredItemState)
283
+ this._restoreItem(e, t);
284
+ for (const e of this._positionedItems.keys())
285
+ this._releasePosition(e);
286
+ for (const e of this._describedHandles.keys())
287
+ e.removeAttribute("aria-description");
288
+ this._describedHandles.clear(), this._authoredItemState.clear();
289
+ }
290
+ _handleSlotChange() {
291
+ this._queueSync();
292
+ }
293
+ render() {
294
+ return f`
295
+ <div part="list">
296
+ <slot @slotchange=${this._handleSlotChange}></slot>
297
+ </div>
298
+ `;
299
+ }
300
+ };
301
+ g.styles = $;
302
+ let d = g;
303
+ h([
304
+ y("slot", !0)
305
+ ], d.prototype, "_$slot");
306
+ h([
307
+ n({ reflect: !0 })
308
+ ], d.prototype, "variant");
309
+ h([
310
+ n({ reflect: !0 })
311
+ ], d.prototype, "selection");
312
+ h([
313
+ n({ type: Boolean, reflect: !0 })
314
+ ], d.prototype, "ordered");
315
+ h([
316
+ n({ type: Boolean, reflect: !0 })
317
+ ], d.prototype, "reorderable");
318
+ h([
319
+ n({ attribute: !1 })
320
+ ], d.prototype, "reorderMessages");
321
+ export {
322
+ d as R,
323
+ l as a
324
+ };
325
+ //# sourceMappingURL=rc-list-BqQXmC0M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-list-BqQXmC0M.js","sources":["../src/rc-list-item.styles.ts","../src/rc-list-item.ts","../src/listBaseStyles.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 /* Keep internal z-index layers below a different item when it is lifted. */\n isolation: isolate;\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 [part='details'][hidden] {\n display: none;\n }\n\n /* The supporting region spans the text and trailing columns on its own row,\n outside the content cell's single-line clipping. */\n [part='details'] {\n position: relative;\n z-index: 1;\n grid-column: var(--rc-list-item-details-grid-column, content-start / trailing-end);\n min-inline-size: 0;\n padding-block-end: var(--rc-list-item-details-padding-block-end, 0);\n color: var(--rc-list-item-details-color, inherit);\n animation: rc-list-item-details-reveal var(--rc-list-item-details-duration, 0ms)\n var(--rc-list-item-transition-easing, ease);\n }\n\n @keyframes rc-list-item-details-reveal {\n from {\n opacity: 0;\n }\n }\n\n ::slotted(*) {\n min-inline-size: 0;\n }\n\n ::slotted([slot='trailing'][aria-hidden='true']) {\n pointer-events: none;\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 /* The lifted item paints above the items it passes over. */\n :host([data-dragging]) {\n position: relative;\n z-index: 1;\n }\n\n :host([data-dragging]) [part='row'] {\n background: var(--rc-list-item-dragged-background, var(--rc-list-item-background, Canvas));\n box-shadow: var(--rc-list-item-dragged-box-shadow, var(--rc-list-item-box-shadow, none));\n }\n\n :host([data-dragging]) [part='state-layer'] {\n opacity: var(--rc-list-item-dragged-state-layer-opacity, 0.16);\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 :host([data-dragging]) [part='row'] {\n outline: 2px solid Highlight;\n outline-offset: -2px;\n }\n }\n\n /*\n * background-color, box-shadow, and opacity are all effects motion (no\n * translate, scale, or layout property here), so reduced motion shortens\n * the shared duration instead of zeroing it.\n */\n @media (prefers-reduced-motion: reduce) {\n [part='row'],\n [part='state-layer'] {\n transition-duration: 50ms;\n }\n\n [part='details'] {\n animation-duration: min(var(--rc-list-item-details-duration, 0ms), 50ms);\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 interface HTMLElementEventMap {\n 'rc-list-item-toggle': CustomEvent<RCListItemToggleDetail>;\n }\n}\n\n/** Detail shape for `rc-list-item-toggle`. */\nexport interface RCListItemToggleDetail {\n /** Expanded state the user requested. */\n expanded: boolean;\n}\n\nconst TOGGLE_SELECTOR = '[data-rc-list-item-toggle]';\n\nlet detailsIdCounter = 0;\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 * @slot details - Optional supporting region below the row, shown while expanded. A descendant\n * `button[data-rc-list-item-toggle]` (usually in `trailing`) toggles it; the item wires the\n * button's `aria-expanded` and `aria-controls` and the region's `hidden` state.\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 * @csspart details - Expanded supporting region wrapper.\n *\n * @fires rc-list-item-toggle - Fires when the toggle button requests a new expanded state.\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 expanded - Controlled expanded state of the `details` region, reflected from the\n * current state. Host writes are silent.\n * @attr default-expanded - Initial expanded state for uncontrolled usage.\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-dragging] - Set by a `reorderable` parent list while this item is lifted.\n * @attr [data-rc-list-position] - Row position assigned by the parent list: from `aria-posinset`\n * and `aria-setsize` when the row has them (a virtualized slice), otherwise from rendered order.\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-dragged-background=Canvas] - Surface of an item lifted for reordering.\n * Falls back to `--rc-list-item-background`, then `Canvas`, so the item stays opaque.\n * @cssprop [--rc-list-item-dragged-box-shadow=none] - Shadow of a lifted item. Falls back to\n * `--rc-list-item-box-shadow`.\n * @cssprop [--rc-list-item-dragged-state-layer-opacity=0.16] - Lifted item state opacity.\n * @cssprop [--rc-list-item-reorder-duration=0ms] - Duration of the shift that makes room for a\n * lifted item. Read from the item, applied from light-DOM base styles.\n * @cssprop [--rc-list-item-reorder-easing=ease] - Easing of that shift.\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 * @cssprop [--rc-list-item-details-grid-column=content-start / trailing-end] - Details region\n * column placement.\n * @cssprop [--rc-list-item-details-padding-block-end=0] - Space below the details region.\n * @cssprop [--rc-list-item-details-color=inherit] - Details region foreground.\n * @cssprop [--rc-list-item-details-duration=0ms] - Details reveal duration.\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 /** Initial expanded state of the `details` region for uncontrolled usage. */\n @property({ type: Boolean, attribute: 'default-expanded' })\n defaultExpanded = false;\n\n private _controlledExpanded: boolean | undefined;\n private _uncontrolledExpanded: boolean | undefined;\n private _hasDetails = false;\n\n /**\n * Current expanded state of the `details` region. Host writes are silent and\n * take control; assign `undefined` to release control.\n */\n @property({ type: Boolean, reflect: true, noAccessor: true })\n get expanded(): boolean {\n return this._controlledExpanded ?? this._uncontrolledExpanded ?? this.defaultExpanded;\n }\n\n set expanded(value: boolean | undefined) {\n const previous = this.expanded;\n\n this._controlledExpanded = value ?? undefined;\n this.requestUpdate('expanded', previous);\n }\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n this._internals.role = 'listitem';\n\n this.addEventListener('click', this._handleToggleClick);\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 this._syncDetails();\n\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 this._syncDetails();\n }\n\n private _handleDetailsSlotChange(event: Event): void {\n const hasDetails = this._hasAssignedElements(event);\n\n if (hasDetails !== this._hasDetails) {\n this._hasDetails = hasDetails;\n this.requestUpdate();\n }\n\n this._syncDetails();\n }\n\n private _toggle(): HTMLElement | null {\n const $toggle = this.querySelector<HTMLElement>(TOGGLE_SELECTOR);\n\n return $toggle?.closest('rc-list-item') === this ? $toggle : null;\n }\n\n private _details(): HTMLElement | null {\n return this.querySelector<HTMLElement>(':scope > [slot=\"details\"]');\n }\n\n /** Mirror the expanded state to the authored toggle and details region. */\n private _syncDetails(): void {\n const $details = this._details();\n const $toggle = this._toggle();\n const expanded = this.expanded;\n\n if ($details) {\n if (!$details.id) {\n $details.id = `rc-list-item-details-${++detailsIdCounter}`;\n }\n\n $details.hidden = !expanded;\n }\n\n if ($toggle) {\n $toggle.setAttribute('aria-expanded', String(expanded));\n\n if ($details) {\n $toggle.setAttribute('aria-controls', $details.id);\n } else {\n $toggle.removeAttribute('aria-controls');\n }\n }\n }\n\n private readonly _handleToggleClick = (event: MouseEvent): void => {\n const $toggle = this._toggle();\n\n if (!$toggle || !event.composedPath().includes($toggle) || !this._details()) {\n return;\n }\n\n const requested = !this.expanded;\n\n if (this._controlledExpanded === undefined) {\n const previous = this.expanded;\n\n this._uncontrolledExpanded = requested;\n this.requestUpdate('expanded', previous);\n }\n\n this.dispatchEvent(\n new CustomEvent<RCListItemToggleDetail>('rc-list-item-toggle', {\n bubbles: true,\n composed: true,\n detail: { expanded: requested },\n }),\n );\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 <div part=\"details\" ?hidden=${!this._hasDetails || !this.expanded}>\n <slot name=\"details\" @slotchange=${this._handleDetailsSlotChange}></slot>\n </div>\n <span part=\"divider\" aria-hidden=\"true\"></span>\n </div>\n `;\n }\n}\n","import { cssText } from '@rcarls/rc-common';\n\n/**\n * Light-DOM base styles for `rc-list` reordering.\n *\n * Reorder handles are consumer-authored buttons in light DOM, so the list's\n * shadow styles cannot reach them. A handle must not start native panning, or\n * a touch drag scrolls the page instead of moving the item.\n */\nexport const LIST_BASE_CSS = cssText`\n@layer rc-base {\n rc-list[reorderable] [data-rc-reorder-handle] {\n touch-action: none;\n cursor: grab;\n }\n\n rc-list[data-reordering] {\n user-select: none;\n -webkit-user-select: none;\n }\n\n rc-list[data-reordering] [data-rc-reorder-handle] {\n cursor: grabbing;\n }\n\n /* Items shifting out of the lifted item's way. The lifted item follows the pointer. */\n rc-list[data-reordering] > rc-list-item:not([data-dragging]) {\n transition: translate var(--rc-list-item-reorder-duration, 0ms)\n var(--rc-list-item-reorder-easing, ease);\n }\n\n @media (prefers-reduced-motion: reduce) {\n rc-list[data-reordering] > rc-list-item {\n transition-duration: 0ms;\n }\n }\n}\n`;\n\nconst styledRoots = new WeakSet<Document | ShadowRoot>();\n\n/** Installs the shared list reorder styles once per containing root. */\nexport function ensureListBaseStyles(root: Document | ShadowRoot): void {\n if (styledRoots.has(root)) {\n return;\n }\n\n styledRoots.add(root);\n\n const $style = (root instanceof Document ? root : root.ownerDocument).createElement('style');\n\n $style.setAttribute('data-rc-light-dom-base', 'rc-list');\n $style.textContent = LIST_BASE_CSS;\n\n if (root instanceof Document) {\n root.head.append($style);\n } else {\n root.append($style);\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 /* A long press on a reorderable item picks it up, not its text. */\n :host([reorderable]) ::slotted(rc-list-item) {\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n user-select: none;\n }\n`;\n\nexport default listStyles;\n","import { LitElement, html } from 'lit';\nimport { property, query } from 'lit/decorators.js';\n\nimport { ReorderController, observeLocale, type ReorderMessages } from '@rcarls/rc-common';\nimport type { RCListItem } from './rc-list-item.js';\nimport { ensureListBaseStyles } from './listBaseStyles.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 interface HTMLElementEventMap {\n 'rc-list-reorder': CustomEvent<RCListReorderDetail>;\n }\n}\n\n/** Detail shape for `rc-list-reorder`. Positions are 0-based among visible items. */\nexport interface RCListReorderDetail {\n /** The moved item. */\n item: RCListItem;\n /** Position the item is moving from. */\n from: number;\n /** Position the item is moving to. */\n to: number;\n}\n\n/** Overridable reorder announcements. Positions passed to the functions are 1-based. */\nexport type RCListReorderMessages = Partial<ReorderMessages>;\n\nconst REORDER_HANDLE = '[data-rc-reorder-handle]';\n\n/**\n * A row's position in the whole set. A virtualized list renders only a slice,\n * so rows that carry `aria-posinset` and `aria-setsize` are placed by those,\n * and only the set's real first and last rows get end styling. Other rows are\n * placed by their rendered order.\n */\n// Writing an unchanged value would still notify the list's own attribute observer.\nfunction setAttributeIfChanged($element: Element, name: string, value: string): void {\n if ($element.getAttribute(name) !== value) {\n $element.setAttribute(name, value);\n }\n}\n\nfunction rowPosition(item: Element, index: number, count: number): RCListPosition {\n const position = Number(item.getAttribute('aria-posinset'));\n const size = Number(item.getAttribute('aria-setsize'));\n const [at, of] = position > 0 && size > 0 ? [position - 1, size] : [index, count];\n\n if (of === 1) {\n return 'only';\n }\n\n return at === 0 ? 'first' : at === of - 1 ? 'last' : 'middle';\n}\n\ntype RCListPosition = 'only' | 'first' | 'middle' | 'last';\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 ordered - Marks the item order as meaningful. Visible items without authored\n * `aria-posinset`/`aria-setsize` receive their position so assistive technology reports it.\n * No counters are rendered; item content carries any visible numbering.\n * @attr reorderable - Lets people reorder items with a handle, by pointer or keyboard.\n * Implies `ordered`. Each item provides a native `<button data-rc-reorder-handle>`.\n * @attr [data-reordering] - Reflected while an item is lifted.\n *\n * @fires rc-list-reorder - Fires, cancelable, when a reorder moves an item;\n * `detail: { item, from, to }`. Unless the event is canceled the list moves the item's\n * node itself. A framework that renders the items cancels it and reorders its own data.\n * A pointer drag fires once on drop; the keyboard fires on each step, and once more to\n * move the item back when the reorder is canceled.\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 * ## Reordering\n *\n * With `reorderable`, a native `<button data-rc-reorder-handle>` inside an item starts a\n * reorder. Label the button yourself, for example \"Reorder Photo 2\". Handles without an\n * authored `aria-description` get a short keyboard hint.\n *\n * - Pointer: press the handle and drag. The lifted item follows the pointer, the items\n * it passes shift out of its way, and the nearest scroll container scrolls near its\n * edges. Escape cancels.\n * - Touch and pen: as on Android, a long press anywhere on an item also picks it up, then\n * drag. Moving before the press completes scrolls the list instead. A mouse drags only\n * by the handle. Item text cannot be selected in a reorderable list.\n * - Keyboard: Space or Enter picks the item up, the block-axis arrow keys, Home, and End\n * move it, Space or Enter drops it, and Escape returns it. Leaving the handle drops it.\n *\n * Each step is announced through a polite live region mounted in the nearest open\n * `dialog` or popover, else the document body; override the text with `reorderMessages`. Focus stays on the moved item's handle, and is restored to\n * the item at the new position when a framework replaces the item's nodes.\n *\n * The lifted item carries `data-dragging`, and the list carries `data-reordering`. The\n * list writes inline `translate` offsets to items while a pointer drag previews a move.\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 private _unobserveLocale: (() => void) | 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 /** Whether item order is meaningful; positions are exposed without rendered counters. */\n @property({ type: Boolean, reflect: true })\n ordered = false;\n\n /** Whether people can reorder items with a handle. Implies `ordered`. */\n @property({ type: Boolean, reflect: true })\n reorderable = false;\n\n /** Overrides for the reorder announcements and the handle hint. */\n @property({ attribute: false })\n reorderMessages: RCListReorderMessages | undefined;\n\n private readonly _reorder: ReorderController;\n\n /** Handle descriptions this list wrote, released when no longer reorderable. */\n private readonly _describedHandles = new Map<HTMLElement, string>();\n\n /**\n * Positions this list wrote, by item. An item whose attributes no longer\n * match was repositioned by its author, possibly after the first sync, and\n * is left alone from then on.\n */\n private readonly _positionedItems = new Map<RCListItem, { posinset: string; setsize: string }>();\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n this._internals.role = 'list';\n\n this._reorder = new ReorderController(this, {\n items: () => (this.reorderable ? this._visibleItems() : []),\n handleSelector: REORDER_HANDLE,\n disabled: () => !this.reorderable,\n messages: () => this.reorderMessages,\n onMove: (item, from, to) => this._moveItem(item as RCListItem, from, to),\n onActiveChange: (item) => {\n this.toggleAttribute('data-reordering', item !== null);\n this._items().forEach(($item) => $item.toggleAttribute('data-dragging', $item === item));\n },\n });\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 // Handle hints are written into light DOM, so a new locale or registered text must rewrite them.\n this._unobserveLocale ??= observeLocale(() => this._queueSync(), this);\n\n const root = this.getRootNode();\n\n ensureListBaseStyles(root instanceof ShadowRoot ? root : this.ownerDocument);\n\n if (typeof MutationObserver === 'function') {\n this._mutationObserver ??= new MutationObserver(() => this._queueSync());\n\n this._mutationObserver.observe(this, {\n attributes: true,\n childList: true,\n subtree: true,\n attributeFilter: [\n 'aria-description',\n 'aria-posinset',\n 'aria-setsize',\n 'checked',\n 'disabled',\n 'has-leading',\n 'has-trailing',\n 'hidden',\n ],\n });\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('change', this._handleChange);\n this._mutationObserver?.disconnect();\n this._unobserveLocale?.();\n this._unobserveLocale = null;\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 (\n changed.has('selection') ||\n changed.has('ordered') ||\n changed.has('reorderable') ||\n changed.has('reorderMessages')\n ) {\n this._queueSync();\n }\n\n if (changed.has('reorderable') && !this.reorderable && this._reorder.active) {\n this._reorder.cancel();\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 _visibleItems(): RCListItem[] {\n return this._items().filter((item) => !item.hidden);\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._visibleItems();\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 this._syncOrderedPositions(items);\n this._syncHandleDescriptions(items);\n\n for (const [index, item] of items.entries()) {\n item.dataset.rcListPosition = rowPosition(item, index, items.length);\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 /**\n * Expose each visible item's position in an ordered list. Items that carry\n * authored positions (a virtualized slice) keep them; positions this list\n * wrote are released when the item leaves or the list stops being ordered.\n */\n private _syncOrderedPositions(items: RCListItem[]): void {\n for (const [$item, written] of this._positionedItems) {\n if (\n $item.getAttribute('aria-posinset') !== written.posinset ||\n $item.getAttribute('aria-setsize') !== written.setsize\n ) {\n // Authored after this list positioned it: hand the attributes over.\n this._positionedItems.delete($item);\n } else if (!this._isOrdered() || !items.includes($item)) {\n this._releasePosition($item);\n }\n }\n\n if (!this._isOrdered()) {\n return;\n }\n\n for (const [index, $item] of items.entries()) {\n if (!this._positionedItems.has($item) && $item.hasAttribute('aria-posinset')) {\n continue;\n }\n\n const written = { posinset: String(index + 1), setsize: String(items.length) };\n\n this._positionedItems.set($item, written);\n setAttributeIfChanged($item, 'aria-posinset', written.posinset);\n setAttributeIfChanged($item, 'aria-setsize', written.setsize);\n }\n }\n\n private _isOrdered(): boolean {\n return this.ordered || this.reorderable;\n }\n\n /**\n * Give each handle a keyboard hint unless its author described it. A\n * description the author rewrites afterward is theirs from then on.\n */\n private _syncHandleDescriptions(items: RCListItem[]): void {\n const handles = this.reorderable\n ? items.flatMap(($item) => [...$item.querySelectorAll<HTMLElement>(REORDER_HANDLE)])\n : [];\n const hint = this._reorder.message('instructions');\n\n for (const [$handle, written] of this._describedHandles) {\n if ($handle.getAttribute('aria-description') !== written) {\n this._describedHandles.delete($handle);\n } else if (!handles.includes($handle) || written !== hint) {\n $handle.removeAttribute('aria-description');\n this._describedHandles.delete($handle);\n }\n }\n\n for (const $handle of handles) {\n if (!this._describedHandles.has($handle) && $handle.hasAttribute('aria-description')) {\n continue;\n }\n\n this._describedHandles.set($handle, hint);\n setAttributeIfChanged($handle, 'aria-description', hint);\n }\n }\n\n /** Dispatch a reorder and, unless a consumer took it over, move the node. */\n private _moveItem(item: RCListItem, from: number, to: number): void {\n const event = new CustomEvent<RCListReorderDetail>('rc-list-reorder', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: { item, from, to },\n });\n\n if (!this.dispatchEvent(event)) {\n return;\n }\n\n const $target = this._visibleItems()[to];\n\n if (!$target || $target === item) {\n return;\n }\n\n if (to > from) {\n $target.after(item);\n } else {\n $target.before(item);\n }\n }\n\n private _releasePosition($item: RCListItem): void {\n $item.removeAttribute('aria-posinset');\n $item.removeAttribute('aria-setsize');\n this._positionedItems.delete($item);\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 for (const $item of this._positionedItems.keys()) {\n this._releasePosition($item);\n }\n\n for (const $handle of this._describedHandles.keys()) {\n $handle.removeAttribute('aria-description');\n }\n\n this._describedHandles.clear();\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","TOGGLE_SELECTOR","detailsIdCounter","_RCListItem","LitElement","event","$toggle","requested","previous","ClickDelegateController","value","changed","$node","$slot","hasDetails","$details","expanded","id","$root","$target","html","RCListItem","__decorateClass","property","LIST_BASE_CSS","cssText","styledRoots","ensureListBaseStyles","root","$style","listStyles","REORDER_HANDLE","setAttributeIfChanged","$element","name","rowPosition","item","index","count","position","size","at","of","_RCList","ReorderController","from","to","$item","observeLocale","element","expectedType","items","state","input","written","handles","hint","$handle","RCList","query"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { a as t, R as e } from "./rc-list-DyOxApRJ.js";
1
+ import { a as t, R as e } from "./rc-list-BqQXmC0M.js";
2
2
  customElements.get("rc-list-item") || customElements.define("rc-list-item", t);
3
3
  customElements.get("rc-list") || customElements.define("rc-list", e);
4
4
  export {
package/dist/rc-list.js CHANGED
@@ -1,4 +1,4 @@
1
- import { R as a, a as R } from "./rc-list-DyOxApRJ.js";
1
+ import { R as a, a as R } from "./rc-list-BqQXmC0M.js";
2
2
  export {
3
3
  a as RCList,
4
4
  R as RCListItem
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Light-DOM base styles for `rc-list` reordering.
3
+ *
4
+ * Reorder handles are consumer-authored buttons in light DOM, so the list's
5
+ * shadow styles cannot reach them. A handle must not start native panning, or
6
+ * a touch drag scrolls the page instead of moving the item.
7
+ */
8
+ export declare const LIST_BASE_CSS: string;
9
+ /** Installs the shared list reorder styles once per containing root. */
10
+ export declare function ensureListBaseStyles(root: Document | ShadowRoot): void;
@@ -3,6 +3,14 @@ declare global {
3
3
  interface HTMLElementTagNameMap {
4
4
  'rc-list-item': RCListItem;
5
5
  }
6
+ interface HTMLElementEventMap {
7
+ 'rc-list-item-toggle': CustomEvent<RCListItemToggleDetail>;
8
+ }
9
+ }
10
+ /** Detail shape for `rc-list-item-toggle`. */
11
+ export interface RCListItemToggleDetail {
12
+ /** Expanded state the user requested. */
13
+ expanded: boolean;
6
14
  }
7
15
  /**
8
16
  * A list row whose leading, content, and trailing cells participate in the
@@ -30,6 +38,9 @@ declare global {
30
38
  * `data-rc-list-leading` when a theme should apply its standard leading-icon geometry.
31
39
  * @slot - Primary row content. It truncates to one line by default.
32
40
  * @slot trailing - Optional trailing metadata or action.
41
+ * @slot details - Optional supporting region below the row, shown while expanded. A descendant
42
+ * `button[data-rc-list-item-toggle]` (usually in `trailing`) toggles it; the item wires the
43
+ * button's `aria-expanded` and `aria-controls` and the region's `hidden` state.
33
44
  *
34
45
  * @csspart row - Row surface and subgrid.
35
46
  * @csspart state-layer - Hover, focus, and pressed state layer.
@@ -37,15 +48,23 @@ declare global {
37
48
  * @csspart content - Default content slot wrapper.
38
49
  * @csspart trailing - Trailing slot wrapper.
39
50
  * @csspart divider - Row divider.
51
+ * @csspart details - Expanded supporting region wrapper.
52
+ *
53
+ * @fires rc-list-item-toggle - Fires when the toggle button requests a new expanded state.
40
54
  *
41
55
  * @attr selected - Presentational selected state. Host writes are silent.
42
56
  * @attr disabled - Presentational disabled state. Host writes are silent.
43
57
  * @attr interactive - Enables row interaction styling and click delegation.
44
58
  * @attr action-target - ID of a same-root anchor or button that receives
45
59
  * forwarded surface clicks.
60
+ * @attr expanded - Controlled expanded state of the `details` region, reflected from the
61
+ * current state. Host writes are silent.
62
+ * @attr default-expanded - Initial expanded state for uncontrolled usage.
46
63
  * @attr [has-leading] - Reflected when the leading slot has content.
47
64
  * @attr [has-trailing] - Reflected when the trailing slot has content.
48
- * @attr [data-rc-list-position] - Visible row position assigned by the parent list.
65
+ * @attr [data-dragging] - Set by a `reorderable` parent list while this item is lifted.
66
+ * @attr [data-rc-list-position] - Row position assigned by the parent list: from `aria-posinset`
67
+ * and `aria-setsize` when the row has them (a virtualized slice), otherwise from rendered order.
49
68
  *
50
69
  * @cssprop [--rc-list-item-min-block-size=3rem] - Minimum rendered row height.
51
70
  * @cssprop [--rc-list-item-padding-block=0.5rem] - Row block padding.
@@ -75,8 +94,21 @@ declare global {
75
94
  * @cssprop [--rc-list-item-focus-state-layer-opacity=0.1] - Focus state opacity.
76
95
  * @cssprop [--rc-list-item-pressed-state-layer-opacity=0.1] - Pressed state opacity.
77
96
  * @cssprop [--rc-list-item-disabled-opacity=0.38] - Disabled row opacity.
97
+ * @cssprop [--rc-list-item-dragged-background=Canvas] - Surface of an item lifted for reordering.
98
+ * Falls back to `--rc-list-item-background`, then `Canvas`, so the item stays opaque.
99
+ * @cssprop [--rc-list-item-dragged-box-shadow=none] - Shadow of a lifted item. Falls back to
100
+ * `--rc-list-item-box-shadow`.
101
+ * @cssprop [--rc-list-item-dragged-state-layer-opacity=0.16] - Lifted item state opacity.
102
+ * @cssprop [--rc-list-item-reorder-duration=0ms] - Duration of the shift that makes room for a
103
+ * lifted item. Read from the item, applied from light-DOM base styles.
104
+ * @cssprop [--rc-list-item-reorder-easing=ease] - Easing of that shift.
78
105
  * @cssprop [--rc-list-item-transition-duration=0ms] - Row state transition duration.
79
106
  * @cssprop [--rc-list-item-transition-easing=ease] - Row state transition easing.
107
+ * @cssprop [--rc-list-item-details-grid-column=content-start / trailing-end] - Details region
108
+ * column placement.
109
+ * @cssprop [--rc-list-item-details-padding-block-end=0] - Space below the details region.
110
+ * @cssprop [--rc-list-item-details-color=inherit] - Details region foreground.
111
+ * @cssprop [--rc-list-item-details-duration=0ms] - Details reveal duration.
80
112
  *
81
113
  * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-list rc-list documentation}
82
114
  */
@@ -97,13 +129,30 @@ export declare class RCListItem extends LitElement {
97
129
  * (uncommon, but not fought against).
98
130
  */
99
131
  actionTarget: string;
132
+ /** Initial expanded state of the `details` region for uncontrolled usage. */
133
+ defaultExpanded: boolean;
134
+ private _controlledExpanded;
135
+ private _uncontrolledExpanded;
136
+ private _hasDetails;
137
+ /**
138
+ * Current expanded state of the `details` region. Host writes are silent and
139
+ * take control; assign `undefined` to release control.
140
+ */
141
+ get expanded(): boolean;
142
+ set expanded(value: boolean | undefined);
100
143
  constructor();
101
144
  connectedCallback(): void;
102
145
  protected updated(changed: PropertyValues<this>): void;
103
146
  private _hasAssignedElements;
104
147
  private _handleNamedSlotChange;
148
+ private _handleDetailsSlotChange;
149
+ private _toggle;
150
+ private _details;
151
+ /** Mirror the expanded state to the authored toggle and details region. */
152
+ private _syncDetails;
153
+ private readonly _handleToggleClick;
105
154
  private _nativeInput;
106
155
  private _resolveActionTarget;
107
156
  protected firstUpdated(): void;
108
- protected render(): import('lit').TemplateResult<1>;
157
+ protected render(): import('lit-html').TemplateResult<1>;
109
158
  }