@rcarls/rc-chip 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @rcarls/rc-chip
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ffcbf11: Add adaptive chip-group layouts, native-backed filter chips, and shared
8
+ input-chip rendering. Native-backed chips preserve controlled host state,
9
+ follow form resets when uncontrolled, and accept native link actions. Groups
10
+ restore author-owned chip variants when coordination ends. Keep search input
11
+ chrome inside the search surface and align contextual icon sizes with Material 3.
12
+ - 0a462c5: Add `--rc-chip-touch-target-overlap-block-start` and `-block-end`, zero by
13
+ default. A theme or consumer sets one to let a chip's accessible
14
+ touch-target inflation on that side overlap into whatever sits just
15
+ outside the host, such as a height-constrained field's own block padding
16
+ (a multi-select value area in `rc-search-bar` or `rc-combobox`, say),
17
+ instead of also reserving layout space there. The block-axis counterpart
18
+ to `@rcarls/rc-button`'s, `@rcarls/rc-menu-button`'s, and
19
+ `@rcarls/rc-adaptive-menu`'s own inline-axis touch-target overlap tokens.
20
+
21
+ ### Patch Changes
22
+
23
+ - 7adbd76: Keep development diagnostics concise and prevent expected test fixtures from emitting noisy warnings.
24
+
25
+ ## 0.5.0
26
+
3
27
  ## 0.4.2
4
28
 
5
29
  ## 0.4.1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @rcarls/rc-chip
2
2
 
3
- Chip wrapper for native button-based actions, filters, and inputs.
3
+ Chip wrapper for native actions, links, filters, and inputs.
4
4
 
5
5
  ```html
6
6
  <rc-chip variant="filter">
@@ -12,6 +12,14 @@ The native button remains connected for keyboard behavior and progressive enhanc
12
12
  Native tap highlighting is suppressed because the component's clipped state layer
13
13
  provides hover, focus, and pressed feedback within the chip shape.
14
14
 
15
+ Navigation chips preserve the same native-link behavior:
16
+
17
+ ```html
18
+ <rc-chip>
19
+ <a href="/recipes">Recipes</a>
20
+ </rc-chip>
21
+ ```
22
+
15
23
  Use `rc-toolbar` when a group of interactive chips should form one tab stop
16
24
  with arrow-key navigation. Import `@rcarls/rc-toolbar/define` separately when
17
25
  you are not using the aggregate package:
@@ -62,7 +62,7 @@
62
62
  "declarations": [
63
63
  {
64
64
  "kind": "class",
65
- "description": "Chip wrapper that preserves a direct native `<button>` child for interactive\nchips and accepts a direct `[data-rc-chip-label]` child for read-only chips.",
65
+ "description": "Chip wrapper that preserves a direct native `<button>` child for action chips,\na direct `<a href>` for navigation chips, or a direct `<label>` containing a\nnative checkbox/radio for filter chips. Read-only chips accept a direct\n`[data-rc-chip-label]` child.",
66
66
  "name": "RCChip",
67
67
  "cssProperties": [
68
68
  {
@@ -74,6 +74,21 @@
74
74
  "description": "Minimum chip block size (defers to native button/anchor sizing when unset).",
75
75
  "name": "--rc-chip-block-size"
76
76
  },
77
+ {
78
+ "description": "Minimum interactive touch target size.",
79
+ "name": "--rc-chip-touch-target-block-size",
80
+ "default": "3rem"
81
+ },
82
+ {
83
+ "description": "Zero by default. A theme or consumer sets this on a chip that sits at a real block-axis leading edge (no neighbor on that side), such as inside a height-constrained field, to let its touch-target inflation overlap into whatever sits just outside the host instead of also reserving layout space there.",
84
+ "name": "--rc-chip-touch-target-overlap-block-start",
85
+ "default": "0px"
86
+ },
87
+ {
88
+ "description": "The block-axis trailing-edge counterpart to `--rc-chip-touch-target-overlap-block-start`.",
89
+ "name": "--rc-chip-touch-target-overlap-block-end",
90
+ "default": "0px"
91
+ },
77
92
  {
78
93
  "description": "Block-axis padding of the slotted button, anchor, or label (defers to native padding when unset).",
79
94
  "name": "--rc-chip-padding-block"
@@ -203,7 +218,7 @@
203
218
  ],
204
219
  "slots": [
205
220
  {
206
- "description": "A direct native `<button>` child, or `[data-rc-chip-label]` when `readonly`.",
221
+ "description": "A direct native `<button>` child, `<a href>`, native-backed filter `<label>`, or `[data-rc-chip-label]` when `readonly`.",
207
222
  "name": ""
208
223
  },
209
224
  {
@@ -212,6 +227,33 @@
212
227
  }
213
228
  ],
214
229
  "members": [
230
+ {
231
+ "kind": "field",
232
+ "name": "_styledRoots",
233
+ "privacy": "private",
234
+ "static": true,
235
+ "readonly": true,
236
+ "default": "new WeakSet<Document | ShadowRoot>()"
237
+ },
238
+ {
239
+ "kind": "method",
240
+ "name": "_ensureBaseStyles",
241
+ "privacy": "private",
242
+ "static": true,
243
+ "return": {
244
+ "type": {
245
+ "text": "void"
246
+ }
247
+ },
248
+ "parameters": [
249
+ {
250
+ "name": "root",
251
+ "type": {
252
+ "text": "Document | ShadowRoot"
253
+ }
254
+ }
255
+ ]
256
+ },
215
257
  {
216
258
  "kind": "field",
217
259
  "name": "_selected",
@@ -229,6 +271,14 @@
229
271
  "privacy": "private",
230
272
  "default": "false"
231
273
  },
274
+ {
275
+ "kind": "field",
276
+ "name": "_uncontrolledSelected",
277
+ "type": {
278
+ "text": "boolean | undefined"
279
+ },
280
+ "privacy": "private"
281
+ },
232
282
  {
233
283
  "kind": "field",
234
284
  "name": "_selectedInitialized",
@@ -249,7 +299,25 @@
249
299
  },
250
300
  {
251
301
  "kind": "field",
252
- "name": "_buttonObserver",
302
+ "name": "_$input",
303
+ "type": {
304
+ "text": "HTMLInputElement | null"
305
+ },
306
+ "privacy": "private",
307
+ "default": "null"
308
+ },
309
+ {
310
+ "kind": "field",
311
+ "name": "_$form",
312
+ "type": {
313
+ "text": "HTMLFormElement | null"
314
+ },
315
+ "privacy": "private",
316
+ "default": "null"
317
+ },
318
+ {
319
+ "kind": "field",
320
+ "name": "_controlObserver",
253
321
  "type": {
254
322
  "text": "MutationObserver | null"
255
323
  },
@@ -283,6 +351,15 @@
283
351
  "privacy": "private",
284
352
  "default": "false"
285
353
  },
354
+ {
355
+ "kind": "field",
356
+ "name": "_lastChildWarning",
357
+ "type": {
358
+ "text": "string | null"
359
+ },
360
+ "privacy": "private",
361
+ "default": "null"
362
+ },
286
363
  {
287
364
  "kind": "field",
288
365
  "name": "variant",
@@ -364,7 +441,19 @@
364
441
  "type": {
365
442
  "text": "void"
366
443
  }
367
- }
444
+ },
445
+ "parameters": [
446
+ {
447
+ "name": "deferInitialSelectionUpdate",
448
+ "default": "false"
449
+ }
450
+ ]
451
+ },
452
+ {
453
+ "kind": "field",
454
+ "name": "_handleNativeChange",
455
+ "privacy": "private",
456
+ "readonly": true
368
457
  },
369
458
  {
370
459
  "kind": "field",
@@ -392,6 +481,32 @@
392
481
  }
393
482
  }
394
483
  },
484
+ {
485
+ "kind": "method",
486
+ "name": "_syncCheckedState",
487
+ "privacy": "private",
488
+ "return": {
489
+ "type": {
490
+ "text": "void"
491
+ }
492
+ }
493
+ },
494
+ {
495
+ "kind": "method",
496
+ "name": "_syncCheckedFromNative",
497
+ "privacy": "private",
498
+ "return": {
499
+ "type": {
500
+ "text": "void"
501
+ }
502
+ }
503
+ },
504
+ {
505
+ "kind": "field",
506
+ "name": "_handleFormReset",
507
+ "privacy": "private",
508
+ "readonly": true
509
+ },
395
510
  {
396
511
  "kind": "method",
397
512
  "name": "_syncPressedState",
@@ -0,0 +1,440 @@
1
+ import { css as p, LitElement as u, html as h } from "lit";
2
+ import { property as l } from "lit/decorators.js";
3
+ const b = p`
4
+ :host {
5
+ display: inline-grid;
6
+ position: relative;
7
+ place-items: center;
8
+ min-block-size: var(--rc-chip-touch-target-block-size, 3rem);
9
+ color-scheme: inherit;
10
+ vertical-align: middle;
11
+ /*
12
+ * Zero by default. Unlike rc-button's touch-target inflation (opt-in via
13
+ * icon-only), a chip's accessible touch-target minimum applies
14
+ * unconditionally, so it's a common fit inside a height-constrained
15
+ * field -- rc-search-bar's or rc-combobox's multi-select value area, say
16
+ * -- where 3rem per chip would force the field taller than its own
17
+ * content needs. A theme or consumer sets one of these on a chip that
18
+ * sits at a real block-axis edge (no neighbor on that side within the
19
+ * field) to let the touch target overlap into the field's own block
20
+ * padding instead of also reserving layout space there. The same
21
+ * pattern as rc-button's, rc-menu-button's, and rc-adaptive-menu's own
22
+ * touch-target overlap tokens, but on the block axis: a chip's own
23
+ * touch-target inflation is vertical, not horizontal.
24
+ */
25
+ margin-block-start: calc(-1 * var(--rc-chip-touch-target-overlap-block-start, 0px));
26
+ margin-block-end: calc(-1 * var(--rc-chip-touch-target-overlap-block-end, 0px));
27
+ }
28
+
29
+ :host([readonly]) {
30
+ min-block-size: var(--rc-chip-block-size, auto);
31
+ }
32
+
33
+ :host([hidden]) {
34
+ display: none;
35
+ }
36
+
37
+ ::slotted(button),
38
+ ::slotted(a),
39
+ ::slotted(label),
40
+ ::slotted([data-rc-chip-label]) {
41
+ display: inline-flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ gap: var(--rc-chip-gap, 0px);
45
+ min-block-size: var(--rc-chip-block-size);
46
+ padding-block: var(--rc-chip-padding-block, revert);
47
+ padding-inline: var(--rc-chip-padding-inline, revert);
48
+ border: var(--rc-chip-border, revert);
49
+ border-radius: var(--rc-chip-radius, revert);
50
+ background: var(--rc-chip-bg, revert);
51
+ color: var(--rc-chip-color, revert);
52
+ font: var(--rc-chip-font, revert);
53
+ text-decoration: var(--rc-chip-text-decoration, revert);
54
+ white-space: nowrap;
55
+ -webkit-tap-highlight-color: transparent;
56
+ }
57
+
58
+ :host([selected]) ::slotted(button),
59
+ :host([selected]) ::slotted(a),
60
+ :host([selected]) ::slotted(label),
61
+ :host([selected]) ::slotted([data-rc-chip-label]) {
62
+ border-color: var(--rc-chip-selected-border-color, revert);
63
+ background: var(--rc-chip-selected-bg, revert);
64
+ color: var(--rc-chip-selected-color, revert);
65
+ }
66
+
67
+ :host([disabled]) ::slotted(button) {
68
+ opacity: var(--rc-chip-disabled-opacity, revert);
69
+ }
70
+
71
+ :host(:focus-within) ::slotted(button),
72
+ :host(:focus-within) ::slotted(a),
73
+ :host(:focus-within) ::slotted(label) {
74
+ outline: var(--rc-chip-focus-ring, revert);
75
+ outline-offset: var(--rc-chip-focus-ring-offset, revert);
76
+ }
77
+
78
+ [part='state-layer'] {
79
+ pointer-events: none;
80
+ position: absolute;
81
+ z-index: 2;
82
+ inset-inline: 0;
83
+ inset-block-start: 50%;
84
+ block-size: var(--rc-chip-block-size, 100%);
85
+ translate: 0 -50%;
86
+ border-radius: var(--rc-chip-radius, 0);
87
+ background: var(--rc-chip-state-layer-color, currentColor);
88
+ opacity: 0;
89
+ transition: opacity
90
+ var(--rc-chip-state-layer-transition-duration, var(--rc-motion-effects-duration-fast, 80ms))
91
+ var(--rc-chip-state-layer-transition-easing, var(--rc-motion-effects-easing-fast, ease-out));
92
+ }
93
+
94
+ :host([selected]) [part='state-layer'] {
95
+ background: var(
96
+ --rc-chip-selected-state-layer-color,
97
+ var(--rc-chip-state-layer-color, currentColor)
98
+ );
99
+ }
100
+
101
+ @media (hover: hover) {
102
+ :host(:not([disabled], [readonly]):hover) [part='state-layer'] {
103
+ opacity: var(--rc-chip-hover-state-layer-opacity, 0.08);
104
+ }
105
+ }
106
+
107
+ :host(:not([disabled], [readonly]):focus-within) [part='state-layer'] {
108
+ opacity: var(--rc-chip-focus-state-layer-opacity, 0.12);
109
+ }
110
+
111
+ :host(:not([disabled], [readonly]):active) [part='state-layer'] {
112
+ opacity: var(--rc-chip-pressed-state-layer-opacity, 0.12);
113
+ }
114
+
115
+ [part='remove'] {
116
+ position: absolute;
117
+ z-index: 3;
118
+ pointer-events: none;
119
+ inset-block-start: 50%;
120
+ inset-inline-end: var(--rc-chip-remove-offset-inline, 0.125rem);
121
+ display: none;
122
+ place-items: center;
123
+ min-inline-size: var(--rc-chip-remove-target-size, 1.5rem);
124
+ min-block-size: var(--rc-chip-remove-target-size, 1.5rem);
125
+ translate: 0 -50%;
126
+ border: 0;
127
+ border-radius: var(--rc-chip-remove-radius, 9999px);
128
+ background: transparent;
129
+ color: inherit;
130
+ font: inherit;
131
+ }
132
+
133
+ :host([removable]) [part='remove'] {
134
+ display: inline-grid;
135
+ }
136
+
137
+ ::slotted([slot='remove-icon']) {
138
+ /* Keep icon-font utility classes from overriding the chip's compact icon size. */
139
+ font-size: var(--rc-chip-remove-icon-size, smaller) !important;
140
+ }
141
+
142
+ :host([removable]) ::slotted(button),
143
+ :host([removable]) ::slotted(a),
144
+ :host([removable]) ::slotted(label),
145
+ :host([removable]) ::slotted([data-rc-chip-label]) {
146
+ padding-inline-end: var(
147
+ --rc-chip-removable-padding-inline-end,
148
+ calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))
149
+ );
150
+ }
151
+
152
+ @media (forced-colors: active) {
153
+ [part='state-layer'] {
154
+ display: none;
155
+ }
156
+
157
+ ::slotted(button),
158
+ ::slotted(a),
159
+ ::slotted(label),
160
+ ::slotted([data-rc-chip-label]) {
161
+ border-color: ButtonBorder;
162
+ background: ButtonFace;
163
+ color: ButtonText;
164
+ }
165
+
166
+ :host([selected]) ::slotted(button),
167
+ :host([selected]) ::slotted(a),
168
+ :host([selected]) ::slotted(label),
169
+ :host([selected]) ::slotted([data-rc-chip-label]) {
170
+ border-color: Highlight;
171
+ background: Highlight;
172
+ color: HighlightText;
173
+ }
174
+ }
175
+ `;
176
+ var v = Object.defineProperty, f = Object.getOwnPropertyDescriptor, n = (d, e, t, s) => {
177
+ for (var i = s > 1 ? void 0 : s ? f(e, t) : e, o = d.length - 1, c; o >= 0; o--)
178
+ (c = d[o]) && (i = (s ? c(e, t, i) : c(i)) || i);
179
+ return s && i && v(e, t, i), i;
180
+ };
181
+ const _ = /* @__PURE__ */ new Set(["checkbox", "menuitemcheckbox", "menuitemradio", "radio", "switch"]), y = `
182
+ rc-chip > :is(button, a, label, [data-rc-chip-label]) {
183
+ position: relative;
184
+ display: inline-flex;
185
+ box-sizing: border-box;
186
+ align-items: center;
187
+ justify-content: center;
188
+ gap: var(--rc-chip-gap, 0px);
189
+ min-block-size: var(--rc-chip-block-size, revert);
190
+ margin: 0;
191
+ padding-block: var(--rc-chip-padding-block, revert);
192
+ padding-inline: var(--rc-chip-padding-inline, revert);
193
+ border: var(--rc-chip-border, revert);
194
+ border-radius: var(--rc-chip-radius, revert);
195
+ background: var(--rc-chip-bg, revert);
196
+ color: var(--rc-chip-color, revert);
197
+ font: var(--rc-chip-font, revert);
198
+ text-decoration: var(--rc-chip-text-decoration, revert);
199
+ white-space: nowrap;
200
+ -webkit-tap-highlight-color: transparent;
201
+ }
202
+
203
+ rc-chip:not([readonly]) > :is(button, a, label)::before {
204
+ content: '';
205
+ position: absolute;
206
+ z-index: 1;
207
+ inset-block: calc(
208
+ (var(--rc-chip-touch-target-block-size, 3rem) - max(100%, var(--rc-chip-block-size, 0px))) /
209
+ -2
210
+ );
211
+ inset-inline: 0;
212
+ border-radius: inherit;
213
+ }
214
+
215
+ rc-chip[selected] > :is(button, a, label, [data-rc-chip-label]),
216
+ rc-chip > label:has(> input:is([type='checkbox'], [type='radio']):checked) {
217
+ border-color: var(--rc-chip-selected-border-color, revert);
218
+ background: var(--rc-chip-selected-bg, revert);
219
+ color: var(--rc-chip-selected-color, revert);
220
+ }
221
+
222
+ rc-chip[disabled] > :is(button, label),
223
+ rc-chip > label:has(> input:is([type='checkbox'], [type='radio']):disabled) {
224
+ opacity: var(--rc-chip-disabled-opacity, revert);
225
+ }
226
+
227
+ rc-chip > :is(button, a):focus-visible,
228
+ rc-chip > label:has(> input:is([type='checkbox'], [type='radio']):focus-visible) {
229
+ outline: var(--rc-chip-focus-ring, revert);
230
+ outline-offset: var(--rc-chip-focus-ring-offset, revert);
231
+ }
232
+
233
+ rc-chip > label > input:is([type='checkbox'], [type='radio']) {
234
+ position: absolute;
235
+ inline-size: 1px;
236
+ block-size: 1px;
237
+ margin: -1px;
238
+ padding: 0;
239
+ overflow: hidden;
240
+ clip-path: inset(50%);
241
+ white-space: nowrap;
242
+ }
243
+
244
+ rc-chip[removable] > :is(button, a, label, [data-rc-chip-label]) {
245
+ padding-inline-end: var(
246
+ --rc-chip-removable-padding-inline-end,
247
+ calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))
248
+ );
249
+ }
250
+
251
+ @media (forced-colors: active) {
252
+ rc-chip > :is(button, a, label, [data-rc-chip-label]) {
253
+ border-color: ButtonBorder;
254
+ background: ButtonFace;
255
+ color: ButtonText;
256
+ }
257
+
258
+ rc-chip[selected] > :is(button, a, label, [data-rc-chip-label]),
259
+ rc-chip > label:has(> input:is([type='checkbox'], [type='radio']):checked) {
260
+ border-color: Highlight;
261
+ background: Highlight;
262
+ color: HighlightText;
263
+ }
264
+ }
265
+ `;
266
+ var r;
267
+ const a = (r = class extends u {
268
+ constructor() {
269
+ super(...arguments), this._defaultSelected = !1, this._selectedInitialized = !1, this._$button = null, this._$input = null, this._$form = null, this._controlObserver = null, this._disabledOwned = !1, this._pressedOwned = !1, this._slotMicrotaskQueued = !1, this._lastChildWarning = null, this.variant = "assist", this.disabled = !1, this.readonly = !1, this.removable = !1, this._handleNativeChange = () => {
270
+ const e = this._$input;
271
+ if (!e || this.disabled || this.readonly)
272
+ return;
273
+ const t = this.selected, s = e.checked;
274
+ this._selected === void 0 ? (this._uncontrolledSelected = s, this._selectedInitialized = !0, this.requestUpdate("selected", t)) : this._syncCheckedState(), this.dispatchEvent(
275
+ new CustomEvent("rc-chip-change", {
276
+ bubbles: !0,
277
+ composed: !0,
278
+ detail: { selected: s }
279
+ })
280
+ );
281
+ }, this._handleButtonClick = () => {
282
+ if (this.disabled || this.readonly)
283
+ return;
284
+ if (this.removable) {
285
+ this._dispatchRemove();
286
+ return;
287
+ }
288
+ if (this.variant !== "filter")
289
+ return;
290
+ const e = this._$button?.getAttribute("aria-haspopup");
291
+ if (e && e !== "false")
292
+ return;
293
+ const t = this.selected, s = !t;
294
+ this._selected === void 0 && (this._uncontrolledSelected = s, this._selectedInitialized = !0, this._syncPressedState(), this.requestUpdate("selected", t)), this.dispatchEvent(
295
+ new CustomEvent("rc-chip-change", {
296
+ bubbles: !0,
297
+ composed: !0,
298
+ detail: { selected: s }
299
+ })
300
+ );
301
+ }, this._handleFormReset = () => {
302
+ queueMicrotask(() => this._syncCheckedFromNative());
303
+ };
304
+ }
305
+ static _ensureBaseStyles(e) {
306
+ if (r._styledRoots.has(e))
307
+ return;
308
+ r._styledRoots.add(e);
309
+ const t = (e instanceof Document ? e : e.ownerDocument).createElement("style");
310
+ t.setAttribute("data-rc-light-dom-base", "rc-chip"), t.textContent = y, e instanceof Document ? e.head.append(t) : e.append(t);
311
+ }
312
+ get selected() {
313
+ return this._selected ?? this._uncontrolledSelected ?? this._defaultSelected;
314
+ }
315
+ set selected(e) {
316
+ const t = this.selected;
317
+ this._selected = e, this._selectedInitialized = !0, this._syncCheckedState(), this._syncPressedState(), this.requestUpdate("selected", t);
318
+ }
319
+ get defaultSelected() {
320
+ return this._defaultSelected;
321
+ }
322
+ set defaultSelected(e) {
323
+ const t = this._defaultSelected;
324
+ this._defaultSelected = e, !this._selectedInitialized && this._selected === void 0 && this._uncontrolledSelected === void 0 && (this._syncPressedState(), this.requestUpdate("selected", t)), this.requestUpdate("defaultSelected", t);
325
+ }
326
+ connectedCallback() {
327
+ super.connectedCallback(), r._ensureBaseStyles(this.getRootNode());
328
+ }
329
+ disconnectedCallback() {
330
+ this._$button?.removeEventListener("click", this._handleButtonClick), this._$input?.removeEventListener("change", this._handleNativeChange), this._$form?.removeEventListener("reset", this._handleFormReset), this._controlObserver?.disconnect(), this._controlObserver = null, super.disconnectedCallback();
331
+ }
332
+ /** Synchronizes uncontrolled filter state from the direct native input. @internal */
333
+ syncNativeSelection() {
334
+ this._syncCheckedFromNative();
335
+ }
336
+ firstUpdated() {
337
+ this._syncSlottedButton(!0);
338
+ }
339
+ updated(e) {
340
+ (e.has("disabled") || e.has("readonly")) && this._syncDisabled(), (e.has("variant") || e.has("selected") || e.has("readonly") || e.has("removable")) && this._syncPressedState(), e.has("selected") && this._syncCheckedState();
341
+ }
342
+ render() {
343
+ return h`
344
+ <slot @slotchange=${this._handleSlotChange}></slot>
345
+ <span part="state-layer" aria-hidden="true"></span>
346
+ ${this.removable ? h`
347
+ <span part="remove" aria-hidden="true">
348
+ <slot name="remove-icon">×</slot>
349
+ </span>
350
+ ` : ""}
351
+ `;
352
+ }
353
+ _handleSlotChange() {
354
+ this._slotMicrotaskQueued || (this._slotMicrotaskQueued = !0, queueMicrotask(() => {
355
+ this._slotMicrotaskQueued = !1, this.isConnected && this._syncSlottedButton();
356
+ }));
357
+ }
358
+ _syncSlottedButton(e = !1) {
359
+ const t = this.querySelector(":scope > button");
360
+ this.querySelector(":scope > a[href]");
361
+ const i = this.querySelector(":scope > label")?.querySelector(
362
+ ':scope > input:is([type="checkbox"], [type="radio"])'
363
+ ) ?? null;
364
+ if (t === this._$button && i === this._$input) {
365
+ this._syncDisabled(), this._syncCheckedState(), this._syncPressedState();
366
+ return;
367
+ }
368
+ if (this._$button?.removeEventListener("click", this._handleButtonClick), this._$input?.removeEventListener("change", this._handleNativeChange), this._$form?.removeEventListener("reset", this._handleFormReset), this._controlObserver?.disconnect(), this._controlObserver = null, this._$button = t, this._$input = i, this._$form = i?.form ?? null, this._disabledOwned = !1, this._pressedOwned = !1, t && t.addEventListener("click", this._handleButtonClick), i) {
369
+ if (this._selected === void 0 && this._uncontrolledSelected === void 0) {
370
+ const c = this.selected;
371
+ this._uncontrolledSelected = i.checked, this._selectedInitialized = !0, e ? queueMicrotask(() => this.requestUpdate("selected", c)) : this.requestUpdate("selected", c);
372
+ } else
373
+ this._syncCheckedState();
374
+ i.addEventListener("change", this._handleNativeChange), this._$form?.addEventListener("reset", this._handleFormReset);
375
+ }
376
+ const o = i ?? t;
377
+ o && (this._controlObserver = new MutationObserver(() => {
378
+ this._syncDisabled(), this._syncCheckedFromNative(), this._syncPressedState();
379
+ }), this._controlObserver.observe(o, {
380
+ attributeFilter: ["aria-pressed", "role", "disabled", "checked"]
381
+ })), this._syncDisabled(), this._syncCheckedState(), this._syncPressedState();
382
+ }
383
+ _dispatchRemove() {
384
+ this.dispatchEvent(
385
+ new CustomEvent("rc-chip-remove", {
386
+ bubbles: !0,
387
+ composed: !0,
388
+ detail: { chip: this }
389
+ })
390
+ );
391
+ }
392
+ _syncDisabled() {
393
+ const e = this._$input ?? this._$button;
394
+ e && (this.disabled || this.readonly ? (e.disabled || (this._disabledOwned = !0), e.disabled = !0) : this._disabledOwned && (e.disabled = !1, this._disabledOwned = !1));
395
+ }
396
+ _syncCheckedState() {
397
+ const e = this._$input;
398
+ e && e.checked !== this.selected && (e.checked = this.selected);
399
+ }
400
+ _syncCheckedFromNative() {
401
+ const e = this._$input;
402
+ if (!e || e.checked === this.selected)
403
+ return;
404
+ const t = this.selected;
405
+ this._selected === void 0 ? (this._uncontrolledSelected = e.checked, this._selectedInitialized = !0, this.requestUpdate("selected", t)) : this._syncCheckedState();
406
+ }
407
+ _syncPressedState() {
408
+ const e = this._$button;
409
+ if (!e)
410
+ return;
411
+ const t = e.getAttribute("role"), s = e.hasAttribute("aria-pressed") && !this._pressedOwned || (t ? _.has(t) : !1);
412
+ if (!this.readonly && !this.removable && this.variant === "filter" && !s) {
413
+ const i = this.selected ? "true" : "false";
414
+ e.getAttribute("aria-pressed") !== i && e.setAttribute("aria-pressed", i), this._pressedOwned = !0;
415
+ } else this._pressedOwned && (e.removeAttribute("aria-pressed"), this._pressedOwned = !1);
416
+ }
417
+ }, r.styles = b, r._styledRoots = /* @__PURE__ */ new WeakSet(), r);
418
+ n([
419
+ l({ type: String, reflect: !0 })
420
+ ], a.prototype, "variant", 2);
421
+ n([
422
+ l({ type: Boolean, reflect: !0 })
423
+ ], a.prototype, "selected", 1);
424
+ n([
425
+ l({ type: Boolean, attribute: "default-selected" })
426
+ ], a.prototype, "defaultSelected", 1);
427
+ n([
428
+ l({ type: Boolean, reflect: !0 })
429
+ ], a.prototype, "disabled", 2);
430
+ n([
431
+ l({ type: Boolean, reflect: !0 })
432
+ ], a.prototype, "readonly", 2);
433
+ n([
434
+ l({ type: Boolean, reflect: !0 })
435
+ ], a.prototype, "removable", 2);
436
+ let k = a;
437
+ export {
438
+ k as R
439
+ };
440
+ //# sourceMappingURL=rc-chip-B71-Icgf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-chip-B71-Icgf.js","sources":["../src/rc-chip.styles.ts","../src/rc-chip.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const chipStyles = css`\n :host {\n display: inline-grid;\n position: relative;\n place-items: center;\n min-block-size: var(--rc-chip-touch-target-block-size, 3rem);\n color-scheme: inherit;\n vertical-align: middle;\n /*\n * Zero by default. Unlike rc-button's touch-target inflation (opt-in via\n * icon-only), a chip's accessible touch-target minimum applies\n * unconditionally, so it's a common fit inside a height-constrained\n * field -- rc-search-bar's or rc-combobox's multi-select value area, say\n * -- where 3rem per chip would force the field taller than its own\n * content needs. A theme or consumer sets one of these on a chip that\n * sits at a real block-axis edge (no neighbor on that side within the\n * field) to let the touch target overlap into the field's own block\n * padding instead of also reserving layout space there. The same\n * pattern as rc-button's, rc-menu-button's, and rc-adaptive-menu's own\n * touch-target overlap tokens, but on the block axis: a chip's own\n * touch-target inflation is vertical, not horizontal.\n */\n margin-block-start: calc(-1 * var(--rc-chip-touch-target-overlap-block-start, 0px));\n margin-block-end: calc(-1 * var(--rc-chip-touch-target-overlap-block-end, 0px));\n }\n\n :host([readonly]) {\n min-block-size: var(--rc-chip-block-size, auto);\n }\n\n :host([hidden]) {\n display: none;\n }\n\n ::slotted(button),\n ::slotted(a),\n ::slotted(label),\n ::slotted([data-rc-chip-label]) {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--rc-chip-gap, 0px);\n min-block-size: var(--rc-chip-block-size);\n padding-block: var(--rc-chip-padding-block, revert);\n padding-inline: var(--rc-chip-padding-inline, revert);\n border: var(--rc-chip-border, revert);\n border-radius: var(--rc-chip-radius, revert);\n background: var(--rc-chip-bg, revert);\n color: var(--rc-chip-color, revert);\n font: var(--rc-chip-font, revert);\n text-decoration: var(--rc-chip-text-decoration, revert);\n white-space: nowrap;\n -webkit-tap-highlight-color: transparent;\n }\n\n :host([selected]) ::slotted(button),\n :host([selected]) ::slotted(a),\n :host([selected]) ::slotted(label),\n :host([selected]) ::slotted([data-rc-chip-label]) {\n border-color: var(--rc-chip-selected-border-color, revert);\n background: var(--rc-chip-selected-bg, revert);\n color: var(--rc-chip-selected-color, revert);\n }\n\n :host([disabled]) ::slotted(button) {\n opacity: var(--rc-chip-disabled-opacity, revert);\n }\n\n :host(:focus-within) ::slotted(button),\n :host(:focus-within) ::slotted(a),\n :host(:focus-within) ::slotted(label) {\n outline: var(--rc-chip-focus-ring, revert);\n outline-offset: var(--rc-chip-focus-ring-offset, revert);\n }\n\n [part='state-layer'] {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n inset-inline: 0;\n inset-block-start: 50%;\n block-size: var(--rc-chip-block-size, 100%);\n translate: 0 -50%;\n border-radius: var(--rc-chip-radius, 0);\n background: var(--rc-chip-state-layer-color, currentColor);\n opacity: 0;\n transition: opacity\n var(--rc-chip-state-layer-transition-duration, var(--rc-motion-effects-duration-fast, 80ms))\n var(--rc-chip-state-layer-transition-easing, var(--rc-motion-effects-easing-fast, ease-out));\n }\n\n :host([selected]) [part='state-layer'] {\n background: var(\n --rc-chip-selected-state-layer-color,\n var(--rc-chip-state-layer-color, currentColor)\n );\n }\n\n @media (hover: hover) {\n :host(:not([disabled], [readonly]):hover) [part='state-layer'] {\n opacity: var(--rc-chip-hover-state-layer-opacity, 0.08);\n }\n }\n\n :host(:not([disabled], [readonly]):focus-within) [part='state-layer'] {\n opacity: var(--rc-chip-focus-state-layer-opacity, 0.12);\n }\n\n :host(:not([disabled], [readonly]):active) [part='state-layer'] {\n opacity: var(--rc-chip-pressed-state-layer-opacity, 0.12);\n }\n\n [part='remove'] {\n position: absolute;\n z-index: 3;\n pointer-events: none;\n inset-block-start: 50%;\n inset-inline-end: var(--rc-chip-remove-offset-inline, 0.125rem);\n display: none;\n place-items: center;\n min-inline-size: var(--rc-chip-remove-target-size, 1.5rem);\n min-block-size: var(--rc-chip-remove-target-size, 1.5rem);\n translate: 0 -50%;\n border: 0;\n border-radius: var(--rc-chip-remove-radius, 9999px);\n background: transparent;\n color: inherit;\n font: inherit;\n }\n\n :host([removable]) [part='remove'] {\n display: inline-grid;\n }\n\n ::slotted([slot='remove-icon']) {\n /* Keep icon-font utility classes from overriding the chip's compact icon size. */\n font-size: var(--rc-chip-remove-icon-size, smaller) !important;\n }\n\n :host([removable]) ::slotted(button),\n :host([removable]) ::slotted(a),\n :host([removable]) ::slotted(label),\n :host([removable]) ::slotted([data-rc-chip-label]) {\n padding-inline-end: var(\n --rc-chip-removable-padding-inline-end,\n calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))\n );\n }\n\n @media (forced-colors: active) {\n [part='state-layer'] {\n display: none;\n }\n\n ::slotted(button),\n ::slotted(a),\n ::slotted(label),\n ::slotted([data-rc-chip-label]) {\n border-color: ButtonBorder;\n background: ButtonFace;\n color: ButtonText;\n }\n\n :host([selected]) ::slotted(button),\n :host([selected]) ::slotted(a),\n :host([selected]) ::slotted(label),\n :host([selected]) ::slotted([data-rc-chip-label]) {\n border-color: Highlight;\n background: Highlight;\n color: HighlightText;\n }\n }\n`;\n\nexport default chipStyles;\n","import { LitElement, html } from 'lit';\nimport type { PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport chipStyles from './rc-chip.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-chip': RCChip;\n }\n\n interface HTMLElementEventMap {\n 'rc-chip-change': CustomEvent<RCChipChangeDetail>;\n 'rc-chip-remove': CustomEvent<RCChipRemoveDetail>;\n }\n}\n\nconst TOGGLE_ROLES = new Set(['checkbox', 'menuitemcheckbox', 'menuitemradio', 'radio', 'switch']);\n\nconst LIGHT_DOM_CSS = `\nrc-chip > :is(button, a, label, [data-rc-chip-label]) {\n position: relative;\n display: inline-flex;\n box-sizing: border-box;\n align-items: center;\n justify-content: center;\n gap: var(--rc-chip-gap, 0px);\n min-block-size: var(--rc-chip-block-size, revert);\n margin: 0;\n padding-block: var(--rc-chip-padding-block, revert);\n padding-inline: var(--rc-chip-padding-inline, revert);\n border: var(--rc-chip-border, revert);\n border-radius: var(--rc-chip-radius, revert);\n background: var(--rc-chip-bg, revert);\n color: var(--rc-chip-color, revert);\n font: var(--rc-chip-font, revert);\n text-decoration: var(--rc-chip-text-decoration, revert);\n white-space: nowrap;\n -webkit-tap-highlight-color: transparent;\n}\n\nrc-chip:not([readonly]) > :is(button, a, label)::before {\n content: '';\n position: absolute;\n z-index: 1;\n inset-block: calc(\n (var(--rc-chip-touch-target-block-size, 3rem) - max(100%, var(--rc-chip-block-size, 0px))) /\n -2\n );\n inset-inline: 0;\n border-radius: inherit;\n}\n\nrc-chip[selected] > :is(button, a, label, [data-rc-chip-label]),\nrc-chip > label:has(> input:is([type='checkbox'], [type='radio']):checked) {\n border-color: var(--rc-chip-selected-border-color, revert);\n background: var(--rc-chip-selected-bg, revert);\n color: var(--rc-chip-selected-color, revert);\n}\n\nrc-chip[disabled] > :is(button, label),\nrc-chip > label:has(> input:is([type='checkbox'], [type='radio']):disabled) {\n opacity: var(--rc-chip-disabled-opacity, revert);\n}\n\nrc-chip > :is(button, a):focus-visible,\nrc-chip > label:has(> input:is([type='checkbox'], [type='radio']):focus-visible) {\n outline: var(--rc-chip-focus-ring, revert);\n outline-offset: var(--rc-chip-focus-ring-offset, revert);\n}\n\nrc-chip > label > input:is([type='checkbox'], [type='radio']) {\n position: absolute;\n inline-size: 1px;\n block-size: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\nrc-chip[removable] > :is(button, a, label, [data-rc-chip-label]) {\n padding-inline-end: var(\n --rc-chip-removable-padding-inline-end,\n calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))\n );\n}\n\n@media (forced-colors: active) {\n rc-chip > :is(button, a, label, [data-rc-chip-label]) {\n border-color: ButtonBorder;\n background: ButtonFace;\n color: ButtonText;\n }\n\n rc-chip[selected] > :is(button, a, label, [data-rc-chip-label]),\n rc-chip > label:has(> input:is([type='checkbox'], [type='radio']):checked) {\n border-color: Highlight;\n background: Highlight;\n color: HighlightText;\n }\n}\n`;\n\n/** Supported chip variants. */\nexport type RCChipVariant = 'assist' | 'filter' | 'input' | 'suggestion';\n\n/** Detail payload for `rc-chip-change`. */\nexport interface RCChipChangeDetail {\n /** Selected state after user interaction. */\n selected: boolean;\n}\n\n/** Detail payload for `rc-chip-remove`. */\nexport interface RCChipRemoveDetail {\n /** The host chip requesting removal. */\n chip: RCChip;\n}\n\n/**\n * Chip wrapper that preserves a direct native `<button>` child for action chips,\n * a direct `<a href>` for navigation chips, or a direct `<label>` containing a\n * native checkbox/radio for filter chips. Read-only chips accept a direct\n * `[data-rc-chip-label]` child.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-chip rc-chip docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/button/ WAI-ARIA button pattern}\n *\n * @slot - A direct native `<button>` child, `<a href>`, native-backed filter\n * `<label>`, or `[data-rc-chip-label]` when `readonly`.\n * @slot remove-icon - Optional presentational remove icon.\n *\n * @fires rc-chip-change - Fired when a user toggles a filter chip.\n * @fires rc-chip-remove - Fired when a user activates a removable chip's native button.\n *\n * @csspart state-layer - Overlay layer for hover, focus, pressed, ripple, or design-system effects.\n * @csspart remove - Presentational trailing remove indicator.\n *\n * @cssprop [--rc-chip-gap=0px] - Gap between the slotted button/anchor/label's content.\n * @cssprop [--rc-chip-block-size] - Minimum chip block size (defers to native button/anchor\n * sizing when unset).\n * @cssprop [--rc-chip-touch-target-block-size=3rem] - Minimum interactive touch target size.\n * @cssprop [--rc-chip-touch-target-overlap-block-start=0px] - Zero by default. A theme or\n * consumer sets this on a chip that sits at a real block-axis leading edge (no neighbor on\n * that side), such as inside a height-constrained field, to let its touch-target inflation\n * overlap into whatever sits just outside the host instead of also reserving layout space\n * there.\n * @cssprop [--rc-chip-touch-target-overlap-block-end=0px] - The block-axis trailing-edge\n * counterpart to `--rc-chip-touch-target-overlap-block-start`.\n * @cssprop [--rc-chip-padding-block] - Block-axis padding of the slotted button, anchor, or\n * label (defers to native padding when unset).\n * @cssprop [--rc-chip-padding-inline] - Inline-axis padding of the slotted button, anchor, or\n * label (defers to native padding when unset).\n * @cssprop [--rc-chip-border] - Border of the slotted button, anchor, or label (defers to\n * native border when unset).\n * @cssprop [--rc-chip-radius] - Border radius of the slotted button/anchor/label and the\n * state-layer overlay (defers to native border-radius when unset; the state-layer overlay\n * falls back to 0).\n * @cssprop [--rc-chip-bg] - Background of the slotted button, anchor, or label (defers to\n * native background when unset).\n * @cssprop [--rc-chip-color] - Text color of the slotted button, anchor, or label (defers to\n * native color when unset).\n * @cssprop [--rc-chip-font] - Font shorthand for the slotted button, anchor, or label (defers\n * to native font when unset).\n * @cssprop [--rc-chip-text-decoration] - Text decoration for the slotted anchor (defers to\n * native text-decoration when unset).\n * @cssprop [--rc-chip-selected-border-color] - Border color when `selected` (defers to native\n * styling when unset).\n * @cssprop [--rc-chip-selected-bg] - Background when `selected` (defers to native styling when\n * unset).\n * @cssprop [--rc-chip-selected-color] - Text color when `selected` (defers to native styling\n * when unset).\n * @cssprop [--rc-chip-disabled-opacity] - Opacity of the slotted button when `disabled` (defers\n * to native disabled styling when unset).\n * @cssprop [--rc-chip-focus-ring] - Outline shown while focus-within (defers to native focus\n * styling when unset).\n * @cssprop [--rc-chip-focus-ring-offset] - Outline offset while focus-within (defers to native\n * focus styling when unset).\n * @cssprop [--rc-chip-state-layer-color=currentColor] - Hover/focus/pressed state-layer color.\n * @cssprop [--rc-chip-selected-state-layer-color=var(--rc-chip-state-layer-color, currentColor)] - Selected chip state-layer color.\n * @cssprop [--rc-chip-hover-state-layer-opacity=0.08] - Hover state-layer opacity.\n * @cssprop [--rc-chip-focus-state-layer-opacity=0.12] - Focus state-layer opacity.\n * @cssprop [--rc-chip-pressed-state-layer-opacity=0.12] - Pressed state-layer opacity.\n * @cssprop [--rc-chip-state-layer-transition-duration=var(--rc-motion-effects-duration-fast,80ms)] - State-layer effects duration.\n * @cssprop [--rc-chip-state-layer-transition-easing=var(--rc-motion-effects-easing-fast,ease-out)] - State-layer effects easing.\n * @cssprop [--rc-chip-remove-offset-inline=0.125rem] - Inline offset of the remove indicator\n * from the chip edge.\n * @cssprop [--rc-chip-remove-target-size=1.5rem] - Minimum inline and block size of the remove\n * indicator's hit target.\n * @cssprop [--rc-chip-remove-radius=9999px] - Border radius of the remove indicator.\n * @cssprop [--rc-chip-remove-icon-size=smaller] - Font size for a slotted remove icon.\n * @cssprop [--rc-chip-removable-padding-inline-end=calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))] - Override for removable chip content end padding.\n *\n * @attr variant - Chip variant: `assist`, `filter`, `input`, or `suggestion`.\n * @attr selected - Declarative selected state for filter/input chips.\n * @attr default-selected - Initial selected state for uncontrolled usage.\n * @attr disabled - Mirrors disabled state to the native child button.\n * @attr readonly - Marks the chip as non-interactive display content.\n * @attr removable - Shows a trailing remove affordance.\n */\nexport class RCChip extends LitElement {\n static override styles = chipStyles;\n\n private static readonly _styledRoots = new WeakSet<Document | ShadowRoot>();\n\n private static _ensureBaseStyles(root: Document | ShadowRoot): void {\n if (RCChip._styledRoots.has(root)) {\n return;\n }\n\n RCChip._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-chip');\n $style.textContent = LIGHT_DOM_CSS;\n\n if (root instanceof Document) {\n root.head.append($style);\n } else {\n root.append($style);\n }\n }\n\n private _selected: boolean | undefined;\n private _defaultSelected = false;\n private _uncontrolledSelected: boolean | undefined;\n private _selectedInitialized = false;\n private _$button: HTMLButtonElement | null = null;\n private _$input: HTMLInputElement | null = null;\n private _$form: HTMLFormElement | null = null;\n private _controlObserver: MutationObserver | null = null;\n private _disabledOwned = false;\n private _pressedOwned = false;\n private _slotMicrotaskQueued = false;\n private _lastChildWarning: string | null = null;\n\n /** Chip variant. */\n @property({ type: String, reflect: true })\n variant: RCChipVariant = 'assist';\n\n /** Current selected state. Host writes are silent. */\n @property({ type: Boolean, reflect: true })\n get selected(): boolean {\n return this._selected ?? this._uncontrolledSelected ?? this._defaultSelected;\n }\n\n set selected(value: boolean | undefined) {\n const oldValue = this.selected;\n\n this._selected = value;\n this._selectedInitialized = true;\n this._syncCheckedState();\n this._syncPressedState();\n this.requestUpdate('selected', oldValue);\n }\n\n /** Initial selected state for uncontrolled usage. */\n @property({ type: Boolean, attribute: 'default-selected' })\n get defaultSelected(): boolean {\n return this._defaultSelected;\n }\n\n set defaultSelected(value: boolean) {\n const oldValue = this._defaultSelected;\n\n this._defaultSelected = value;\n\n if (\n !this._selectedInitialized &&\n this._selected === undefined &&\n this._uncontrolledSelected === undefined\n ) {\n this._syncPressedState();\n this.requestUpdate('selected', oldValue);\n }\n\n this.requestUpdate('defaultSelected', oldValue);\n }\n\n /** Mirror disabled state to the native child button. */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Mark this chip as non-interactive display content. */\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /** Show a trailing remove affordance. */\n @property({ type: Boolean, reflect: true })\n removable = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n RCChip._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n }\n\n override disconnectedCallback(): void {\n this._$button?.removeEventListener('click', this._handleButtonClick);\n this._$input?.removeEventListener('change', this._handleNativeChange);\n this._$form?.removeEventListener('reset', this._handleFormReset);\n this._controlObserver?.disconnect();\n this._controlObserver = null;\n super.disconnectedCallback();\n }\n\n /** Synchronizes uncontrolled filter state from the direct native input. @internal */\n syncNativeSelection(): void {\n this._syncCheckedFromNative();\n }\n\n protected override firstUpdated(): void {\n this._syncSlottedButton(true);\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n if (changed.has('disabled') || changed.has('readonly')) {\n this._syncDisabled();\n }\n\n if (\n changed.has('variant') ||\n changed.has('selected') ||\n changed.has('readonly') ||\n changed.has('removable')\n ) {\n this._syncPressedState();\n }\n\n if (changed.has('selected')) {\n this._syncCheckedState();\n }\n }\n\n protected override render() {\n return html`\n <slot @slotchange=${this._handleSlotChange}></slot>\n <span part=\"state-layer\" aria-hidden=\"true\"></span>\n ${this.removable\n ? html`\n <span part=\"remove\" aria-hidden=\"true\">\n <slot name=\"remove-icon\">×</slot>\n </span>\n `\n : ''}\n `;\n }\n\n private _handleSlotChange(): void {\n if (this._slotMicrotaskQueued) {\n return;\n }\n\n this._slotMicrotaskQueued = true;\n\n queueMicrotask(() => {\n this._slotMicrotaskQueued = false;\n\n if (this.isConnected) {\n this._syncSlottedButton();\n }\n });\n }\n\n private _syncSlottedButton(deferInitialSelectionUpdate = false): void {\n const $nextButton = this.querySelector<HTMLButtonElement>(':scope > button');\n const $anchor = this.querySelector<HTMLAnchorElement>(':scope > a[href]');\n const $label = this.querySelector<HTMLLabelElement>(':scope > label');\n const $nextInput =\n $label?.querySelector<HTMLInputElement>(\n ':scope > input:is([type=\"checkbox\"], [type=\"radio\"])',\n ) ?? null;\n\n if (import.meta.env.DEV) {\n let childWarning: string | null = null;\n\n if (!$nextButton && !$anchor && !$label && !this.readonly) {\n childWarning =\n '[rc-chip] No supported direct child found. Place a native <button>, <a href>, or a <label> containing a direct checkbox/radio inside <rc-chip>, or use readonly with a [data-rc-chip-label] child.';\n } else if ($label && !$nextInput && !this.readonly) {\n childWarning =\n '[rc-chip] A direct child <label> must contain a direct <input type=\"checkbox\"> or <input type=\"radio\">.';\n }\n\n if (childWarning && childWarning !== this._lastChildWarning) {\n console.warn(childWarning);\n }\n\n this._lastChildWarning = childWarning;\n }\n\n if ($nextButton === this._$button && $nextInput === this._$input) {\n this._syncDisabled();\n this._syncCheckedState();\n this._syncPressedState();\n\n return;\n }\n\n this._$button?.removeEventListener('click', this._handleButtonClick);\n this._$input?.removeEventListener('change', this._handleNativeChange);\n this._$form?.removeEventListener('reset', this._handleFormReset);\n this._controlObserver?.disconnect();\n this._controlObserver = null;\n this._$button = $nextButton;\n this._$input = $nextInput;\n this._$form = $nextInput?.form ?? null;\n this._disabledOwned = false;\n this._pressedOwned = false;\n\n if ($nextButton) {\n $nextButton.addEventListener('click', this._handleButtonClick);\n }\n\n if ($nextInput) {\n if (this._selected === undefined && this._uncontrolledSelected === undefined) {\n const oldValue = this.selected;\n\n this._uncontrolledSelected = $nextInput.checked;\n this._selectedInitialized = true;\n\n if (deferInitialSelectionUpdate) {\n queueMicrotask(() => this.requestUpdate('selected', oldValue));\n } else {\n this.requestUpdate('selected', oldValue);\n }\n } else {\n this._syncCheckedState();\n }\n\n $nextInput.addEventListener('change', this._handleNativeChange);\n this._$form?.addEventListener('reset', this._handleFormReset);\n }\n\n const $observedControl = $nextInput ?? $nextButton;\n\n if ($observedControl) {\n this._controlObserver = new MutationObserver(() => {\n this._syncDisabled();\n this._syncCheckedFromNative();\n this._syncPressedState();\n });\n\n this._controlObserver.observe($observedControl, {\n attributeFilter: ['aria-pressed', 'role', 'disabled', 'checked'],\n });\n }\n\n this._syncDisabled();\n this._syncCheckedState();\n this._syncPressedState();\n }\n\n private readonly _handleNativeChange = (): void => {\n const $input = this._$input;\n\n if (!$input || this.disabled || this.readonly) {\n return;\n }\n\n const oldValue = this.selected;\n const requestedSelected = $input.checked;\n\n if (this._selected === undefined) {\n this._uncontrolledSelected = requestedSelected;\n this._selectedInitialized = true;\n this.requestUpdate('selected', oldValue);\n } else {\n this._syncCheckedState();\n }\n\n this.dispatchEvent(\n new CustomEvent<RCChipChangeDetail>('rc-chip-change', {\n bubbles: true,\n composed: true,\n detail: { selected: requestedSelected },\n }),\n );\n };\n\n private readonly _handleButtonClick = (): void => {\n if (this.disabled || this.readonly) {\n return;\n }\n\n if (this.removable) {\n this._dispatchRemove();\n\n return;\n }\n\n if (this.variant !== 'filter') {\n return;\n }\n\n // Menu-backed filter chips expose filter affordance, but their menu owns\n // the eventual selected state. Preserve that author-controlled behavior.\n const hasPopup = this._$button?.getAttribute('aria-haspopup');\n\n if (hasPopup && hasPopup !== 'false') {\n return;\n }\n\n const oldValue = this.selected;\n const requestedSelected = !oldValue;\n\n if (this._selected === undefined) {\n this._uncontrolledSelected = requestedSelected;\n this._selectedInitialized = true;\n this._syncPressedState();\n this.requestUpdate('selected', oldValue);\n }\n\n this.dispatchEvent(\n new CustomEvent<RCChipChangeDetail>('rc-chip-change', {\n bubbles: true,\n composed: true,\n detail: { selected: requestedSelected },\n }),\n );\n };\n\n private _dispatchRemove(): void {\n this.dispatchEvent(\n new CustomEvent<RCChipRemoveDetail>('rc-chip-remove', {\n bubbles: true,\n composed: true,\n detail: { chip: this },\n }),\n );\n }\n\n private _syncDisabled(): void {\n const $control = this._$input ?? this._$button;\n\n if (!$control) {\n return;\n }\n\n if (this.disabled || this.readonly) {\n if (!$control.disabled) {\n this._disabledOwned = true;\n }\n\n $control.disabled = true;\n } else if (this._disabledOwned) {\n $control.disabled = false;\n this._disabledOwned = false;\n }\n }\n\n private _syncCheckedState(): void {\n const $input = this._$input;\n\n if ($input && $input.checked !== this.selected) {\n $input.checked = this.selected;\n }\n }\n\n private _syncCheckedFromNative(): void {\n const $input = this._$input;\n\n if (!$input || $input.checked === this.selected) {\n return;\n }\n\n const oldValue = this.selected;\n\n if (this._selected === undefined) {\n this._uncontrolledSelected = $input.checked;\n this._selectedInitialized = true;\n this.requestUpdate('selected', oldValue);\n } else {\n this._syncCheckedState();\n }\n }\n\n private readonly _handleFormReset = (): void => {\n queueMicrotask(() => this._syncCheckedFromNative());\n };\n\n private _syncPressedState(): void {\n const $button = this._$button;\n\n if (!$button) {\n return;\n }\n\n const role = $button.getAttribute('role');\n const authorOwnsState =\n ($button.hasAttribute('aria-pressed') && !this._pressedOwned) ||\n (role ? TOGGLE_ROLES.has(role) : false);\n\n if (!this.readonly && !this.removable && this.variant === 'filter' && !authorOwnsState) {\n const pressed = this.selected ? 'true' : 'false';\n\n if ($button.getAttribute('aria-pressed') !== pressed) {\n $button.setAttribute('aria-pressed', pressed);\n }\n\n this._pressedOwned = true;\n } else if (this._pressedOwned) {\n $button.removeAttribute('aria-pressed');\n this._pressedOwned = false;\n }\n }\n}\n\nexport default RCChip;\n"],"names":["chipStyles","css","TOGGLE_ROLES","LIGHT_DOM_CSS","_RCChip","_a","LitElement","$input","oldValue","requestedSelected","hasPopup","root","$style","value","changed","html","deferInitialSelectionUpdate","$nextButton","$nextInput","$observedControl","$control","$button","role","authorOwnsState","pressed","__decorateClass","property","RCChip"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { R as e } from "./rc-chip-Do50B5yx.js";
1
+ import { R as e } from "./rc-chip-B71-Icgf.js";
2
2
  customElements.get("rc-chip") || customElements.define("rc-chip", e);
3
3
  //# sourceMappingURL=rc-chip-define.js.map
package/dist/rc-chip.js CHANGED
@@ -1,4 +1,4 @@
1
- import { R as r } from "./rc-chip-Do50B5yx.js";
1
+ import { R as r } from "./rc-chip-B71-Icgf.js";
2
2
  export {
3
3
  r as RCChip
4
4
  };
@@ -21,13 +21,16 @@ export interface RCChipRemoveDetail {
21
21
  chip: RCChip;
22
22
  }
23
23
  /**
24
- * Chip wrapper that preserves a direct native `<button>` child for interactive
25
- * chips and accepts a direct `[data-rc-chip-label]` child for read-only chips.
24
+ * Chip wrapper that preserves a direct native `<button>` child for action chips,
25
+ * a direct `<a href>` for navigation chips, or a direct `<label>` containing a
26
+ * native checkbox/radio for filter chips. Read-only chips accept a direct
27
+ * `[data-rc-chip-label]` child.
26
28
  *
27
29
  * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-chip rc-chip docs}
28
30
  * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/button/ WAI-ARIA button pattern}
29
31
  *
30
- * @slot - A direct native `<button>` child, or `[data-rc-chip-label]` when `readonly`.
32
+ * @slot - A direct native `<button>` child, `<a href>`, native-backed filter
33
+ * `<label>`, or `[data-rc-chip-label]` when `readonly`.
31
34
  * @slot remove-icon - Optional presentational remove icon.
32
35
  *
33
36
  * @fires rc-chip-change - Fired when a user toggles a filter chip.
@@ -39,6 +42,14 @@ export interface RCChipRemoveDetail {
39
42
  * @cssprop [--rc-chip-gap=0px] - Gap between the slotted button/anchor/label's content.
40
43
  * @cssprop [--rc-chip-block-size] - Minimum chip block size (defers to native button/anchor
41
44
  * sizing when unset).
45
+ * @cssprop [--rc-chip-touch-target-block-size=3rem] - Minimum interactive touch target size.
46
+ * @cssprop [--rc-chip-touch-target-overlap-block-start=0px] - Zero by default. A theme or
47
+ * consumer sets this on a chip that sits at a real block-axis leading edge (no neighbor on
48
+ * that side), such as inside a height-constrained field, to let its touch-target inflation
49
+ * overlap into whatever sits just outside the host instead of also reserving layout space
50
+ * there.
51
+ * @cssprop [--rc-chip-touch-target-overlap-block-end=0px] - The block-axis trailing-edge
52
+ * counterpart to `--rc-chip-touch-target-overlap-block-start`.
42
53
  * @cssprop [--rc-chip-padding-block] - Block-axis padding of the slotted button, anchor, or
43
54
  * label (defers to native padding when unset).
44
55
  * @cssprop [--rc-chip-padding-inline] - Inline-axis padding of the slotted button, anchor, or
@@ -92,14 +103,20 @@ export interface RCChipRemoveDetail {
92
103
  */
93
104
  export declare class RCChip extends LitElement {
94
105
  static styles: import('lit').CSSResult;
106
+ private static readonly _styledRoots;
107
+ private static _ensureBaseStyles;
95
108
  private _selected;
96
109
  private _defaultSelected;
110
+ private _uncontrolledSelected;
97
111
  private _selectedInitialized;
98
112
  private _$button;
99
- private _buttonObserver;
113
+ private _$input;
114
+ private _$form;
115
+ private _controlObserver;
100
116
  private _disabledOwned;
101
117
  private _pressedOwned;
102
118
  private _slotMicrotaskQueued;
119
+ private _lastChildWarning;
103
120
  /** Chip variant. */
104
121
  variant: RCChipVariant;
105
122
  /** Current selected state. Host writes are silent. */
@@ -114,15 +131,22 @@ export declare class RCChip extends LitElement {
114
131
  readonly: boolean;
115
132
  /** Show a trailing remove affordance. */
116
133
  removable: boolean;
134
+ connectedCallback(): void;
117
135
  disconnectedCallback(): void;
136
+ /** Synchronizes uncontrolled filter state from the direct native input. @internal */
137
+ syncNativeSelection(): void;
118
138
  protected firstUpdated(): void;
119
139
  protected updated(changed: PropertyValues<this>): void;
120
140
  protected render(): import('lit').TemplateResult<1>;
121
141
  private _handleSlotChange;
122
142
  private _syncSlottedButton;
143
+ private readonly _handleNativeChange;
123
144
  private readonly _handleButtonClick;
124
145
  private _dispatchRemove;
125
146
  private _syncDisabled;
147
+ private _syncCheckedState;
148
+ private _syncCheckedFromNative;
149
+ private readonly _handleFormReset;
126
150
  private _syncPressedState;
127
151
  }
128
152
  export default RCChip;
package/package.json CHANGED
@@ -3,8 +3,8 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.2",
7
- "description": "Chip wrapper for native button-based actions, filters, and inputs.",
6
+ "version": "0.6.0",
7
+ "description": "Chip wrapper for native actions, links, filters, and inputs.",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/richardcarls/rc-webcomponents.git",
@@ -1,267 +0,0 @@
1
- import { css as p, LitElement as u, html as h } from "lit";
2
- import { property as a } from "lit/decorators.js";
3
- const b = p`
4
- :host {
5
- display: inline-grid;
6
- position: relative;
7
- color-scheme: inherit;
8
- vertical-align: middle;
9
- }
10
-
11
- :host([hidden]) {
12
- display: none;
13
- }
14
-
15
- ::slotted(button),
16
- ::slotted(a),
17
- ::slotted([data-rc-chip-label]) {
18
- display: inline-flex;
19
- align-items: center;
20
- justify-content: center;
21
- gap: var(--rc-chip-gap, 0px);
22
- min-block-size: var(--rc-chip-block-size);
23
- padding-block: var(--rc-chip-padding-block, revert);
24
- padding-inline: var(--rc-chip-padding-inline, revert);
25
- border: var(--rc-chip-border, revert);
26
- border-radius: var(--rc-chip-radius, revert);
27
- background: var(--rc-chip-bg, revert);
28
- color: var(--rc-chip-color, revert);
29
- font: var(--rc-chip-font, revert);
30
- text-decoration: var(--rc-chip-text-decoration, revert);
31
- white-space: nowrap;
32
- -webkit-tap-highlight-color: transparent;
33
- }
34
-
35
- :host([selected]) ::slotted(button),
36
- :host([selected]) ::slotted(a),
37
- :host([selected]) ::slotted([data-rc-chip-label]) {
38
- border-color: var(--rc-chip-selected-border-color, revert);
39
- background: var(--rc-chip-selected-bg, revert);
40
- color: var(--rc-chip-selected-color, revert);
41
- }
42
-
43
- :host([disabled]) ::slotted(button) {
44
- opacity: var(--rc-chip-disabled-opacity, revert);
45
- }
46
-
47
- :host(:focus-within) ::slotted(button),
48
- :host(:focus-within) ::slotted(a) {
49
- outline: var(--rc-chip-focus-ring, revert);
50
- outline-offset: var(--rc-chip-focus-ring-offset, revert);
51
- }
52
-
53
- [part='state-layer'] {
54
- pointer-events: none;
55
- position: absolute;
56
- inset: 0;
57
- border-radius: var(--rc-chip-radius, 0);
58
- background: var(--rc-chip-state-layer-color, currentColor);
59
- opacity: 0;
60
- transition: opacity
61
- var(--rc-chip-state-layer-transition-duration, var(--rc-motion-effects-duration-fast, 80ms))
62
- var(--rc-chip-state-layer-transition-easing, var(--rc-motion-effects-easing-fast, ease-out));
63
- }
64
-
65
- :host([selected]) [part='state-layer'] {
66
- background: var(
67
- --rc-chip-selected-state-layer-color,
68
- var(--rc-chip-state-layer-color, currentColor)
69
- );
70
- }
71
-
72
- @media (hover: hover) {
73
- :host(:not([disabled], [readonly]):hover) [part='state-layer'] {
74
- opacity: var(--rc-chip-hover-state-layer-opacity, 0.08);
75
- }
76
- }
77
-
78
- :host(:not([disabled], [readonly]):focus-within) [part='state-layer'] {
79
- opacity: var(--rc-chip-focus-state-layer-opacity, 0.12);
80
- }
81
-
82
- :host(:not([disabled], [readonly]):active) [part='state-layer'] {
83
- opacity: var(--rc-chip-pressed-state-layer-opacity, 0.12);
84
- }
85
-
86
- [part='remove'] {
87
- position: absolute;
88
- pointer-events: none;
89
- inset-block: 0;
90
- inset-inline-end: var(--rc-chip-remove-offset-inline, 0.125rem);
91
- display: none;
92
- place-items: center;
93
- min-inline-size: var(--rc-chip-remove-target-size, 1.5rem);
94
- min-block-size: var(--rc-chip-remove-target-size, 1.5rem);
95
- margin: auto 0;
96
- border: 0;
97
- border-radius: var(--rc-chip-remove-radius, 9999px);
98
- background: transparent;
99
- color: inherit;
100
- font: inherit;
101
- }
102
-
103
- :host([removable]) [part='remove'] {
104
- display: inline-grid;
105
- }
106
-
107
- ::slotted([slot='remove-icon']) {
108
- /* Keep icon-font utility classes from overriding the chip's compact icon size. */
109
- font-size: var(--rc-chip-remove-icon-size, smaller) !important;
110
- }
111
-
112
- :host([removable]) ::slotted(button),
113
- :host([removable]) ::slotted(a),
114
- :host([removable]) ::slotted([data-rc-chip-label]) {
115
- padding-inline-end: var(
116
- --rc-chip-removable-padding-inline-end,
117
- calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))
118
- );
119
- }
120
-
121
- @media (forced-colors: active) {
122
- [part='state-layer'] {
123
- display: none;
124
- }
125
-
126
- ::slotted(button),
127
- ::slotted(a),
128
- ::slotted([data-rc-chip-label]) {
129
- border-color: ButtonBorder;
130
- background: ButtonFace;
131
- color: ButtonText;
132
- }
133
-
134
- :host([selected]) ::slotted(button),
135
- :host([selected]) ::slotted(a),
136
- :host([selected]) ::slotted([data-rc-chip-label]) {
137
- border-color: Highlight;
138
- background: Highlight;
139
- color: HighlightText;
140
- }
141
- }
142
- `;
143
- var v = Object.defineProperty, f = Object.getOwnPropertyDescriptor, o = (d, e, t, i) => {
144
- for (var s = i > 1 ? void 0 : i ? f(e, t) : e, l = d.length - 1, c; l >= 0; l--)
145
- (c = d[l]) && (s = (i ? c(e, t, s) : c(s)) || s);
146
- return i && s && v(e, t, s), s;
147
- };
148
- const y = /* @__PURE__ */ new Set(["checkbox", "menuitemcheckbox", "menuitemradio", "radio", "switch"]), n = class n extends u {
149
- constructor() {
150
- super(...arguments), this._defaultSelected = !1, this._selectedInitialized = !1, this._$button = null, this._buttonObserver = null, this._disabledOwned = !1, this._pressedOwned = !1, this._slotMicrotaskQueued = !1, this.variant = "assist", this.disabled = !1, this.readonly = !1, this.removable = !1, this._handleButtonClick = () => {
151
- if (this.disabled || this.readonly)
152
- return;
153
- if (this.removable) {
154
- this._dispatchRemove();
155
- return;
156
- }
157
- if (this.variant !== "filter")
158
- return;
159
- const e = this.selected;
160
- this._selected = !this.selected, this._selectedInitialized = !0, this._syncPressedState(), this.requestUpdate("selected", e), this.dispatchEvent(
161
- new CustomEvent("rc-chip-change", {
162
- bubbles: !0,
163
- composed: !0,
164
- detail: { selected: this.selected }
165
- })
166
- );
167
- };
168
- }
169
- get selected() {
170
- return this._selected ?? this._defaultSelected;
171
- }
172
- set selected(e) {
173
- const t = this.selected;
174
- this._selected = e, this._selectedInitialized = !0, this._syncPressedState(), this.requestUpdate("selected", t);
175
- }
176
- get defaultSelected() {
177
- return this._defaultSelected;
178
- }
179
- set defaultSelected(e) {
180
- const t = this._defaultSelected;
181
- this._defaultSelected = e, !this._selectedInitialized && this._selected === void 0 && (this._syncPressedState(), this.requestUpdate("selected", t)), this.requestUpdate("defaultSelected", t);
182
- }
183
- disconnectedCallback() {
184
- this._$button?.removeEventListener("click", this._handleButtonClick), this._buttonObserver?.disconnect(), this._buttonObserver = null, super.disconnectedCallback();
185
- }
186
- firstUpdated() {
187
- this._syncSlottedButton();
188
- }
189
- updated(e) {
190
- (e.has("disabled") || e.has("readonly")) && this._syncDisabled(), (e.has("variant") || e.has("selected") || e.has("readonly") || e.has("removable")) && this._syncPressedState();
191
- }
192
- render() {
193
- return h`
194
- <slot @slotchange=${this._handleSlotChange}></slot>
195
- <span part="state-layer" aria-hidden="true"></span>
196
- ${this.removable ? h`
197
- <span part="remove" aria-hidden="true">
198
- <slot name="remove-icon">×</slot>
199
- </span>
200
- ` : ""}
201
- `;
202
- }
203
- _handleSlotChange() {
204
- this._slotMicrotaskQueued || (this._slotMicrotaskQueued = !0, queueMicrotask(() => {
205
- this._slotMicrotaskQueued = !1, this.isConnected && this._syncSlottedButton();
206
- }));
207
- }
208
- _syncSlottedButton() {
209
- const e = this.querySelector(":scope > button");
210
- if (!e && this.readonly, e === this._$button) {
211
- this._syncDisabled(), this._syncPressedState();
212
- return;
213
- }
214
- this._$button?.removeEventListener("click", this._handleButtonClick), this._buttonObserver?.disconnect(), this._buttonObserver = null, this._$button = e, this._disabledOwned = !1, this._pressedOwned = !1, e && (e.addEventListener("click", this._handleButtonClick), this._buttonObserver = new MutationObserver(() => {
215
- this._syncDisabled(), this._syncPressedState();
216
- }), this._buttonObserver.observe(e, {
217
- attributeFilter: ["aria-pressed", "role", "disabled"]
218
- })), this._syncDisabled(), this._syncPressedState();
219
- }
220
- _dispatchRemove() {
221
- this.dispatchEvent(
222
- new CustomEvent("rc-chip-remove", {
223
- bubbles: !0,
224
- composed: !0,
225
- detail: { chip: this }
226
- })
227
- );
228
- }
229
- _syncDisabled() {
230
- const e = this._$button;
231
- e && (this.disabled || this.readonly ? (e.disabled || (this._disabledOwned = !0), e.disabled = !0) : this._disabledOwned && (e.disabled = !1, this._disabledOwned = !1));
232
- }
233
- _syncPressedState() {
234
- const e = this._$button;
235
- if (!e)
236
- return;
237
- const t = e.getAttribute("role"), i = e.hasAttribute("aria-pressed") && !this._pressedOwned || (t ? y.has(t) : !1);
238
- if (!this.readonly && !this.removable && this.variant === "filter" && !i) {
239
- const s = this.selected ? "true" : "false";
240
- e.getAttribute("aria-pressed") !== s && e.setAttribute("aria-pressed", s), this._pressedOwned = !0;
241
- } else this._pressedOwned && (e.removeAttribute("aria-pressed"), this._pressedOwned = !1);
242
- }
243
- };
244
- n.styles = b;
245
- let r = n;
246
- o([
247
- a({ type: String, reflect: !0 })
248
- ], r.prototype, "variant", 2);
249
- o([
250
- a({ type: Boolean, reflect: !0 })
251
- ], r.prototype, "selected", 1);
252
- o([
253
- a({ type: Boolean, attribute: "default-selected" })
254
- ], r.prototype, "defaultSelected", 1);
255
- o([
256
- a({ type: Boolean, reflect: !0 })
257
- ], r.prototype, "disabled", 2);
258
- o([
259
- a({ type: Boolean, reflect: !0 })
260
- ], r.prototype, "readonly", 2);
261
- o([
262
- a({ type: Boolean, reflect: !0 })
263
- ], r.prototype, "removable", 2);
264
- export {
265
- r as R
266
- };
267
- //# sourceMappingURL=rc-chip-Do50B5yx.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rc-chip-Do50B5yx.js","sources":["../src/rc-chip.styles.ts","../src/rc-chip.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const chipStyles = css`\n :host {\n display: inline-grid;\n position: relative;\n color-scheme: inherit;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n ::slotted(button),\n ::slotted(a),\n ::slotted([data-rc-chip-label]) {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--rc-chip-gap, 0px);\n min-block-size: var(--rc-chip-block-size);\n padding-block: var(--rc-chip-padding-block, revert);\n padding-inline: var(--rc-chip-padding-inline, revert);\n border: var(--rc-chip-border, revert);\n border-radius: var(--rc-chip-radius, revert);\n background: var(--rc-chip-bg, revert);\n color: var(--rc-chip-color, revert);\n font: var(--rc-chip-font, revert);\n text-decoration: var(--rc-chip-text-decoration, revert);\n white-space: nowrap;\n -webkit-tap-highlight-color: transparent;\n }\n\n :host([selected]) ::slotted(button),\n :host([selected]) ::slotted(a),\n :host([selected]) ::slotted([data-rc-chip-label]) {\n border-color: var(--rc-chip-selected-border-color, revert);\n background: var(--rc-chip-selected-bg, revert);\n color: var(--rc-chip-selected-color, revert);\n }\n\n :host([disabled]) ::slotted(button) {\n opacity: var(--rc-chip-disabled-opacity, revert);\n }\n\n :host(:focus-within) ::slotted(button),\n :host(:focus-within) ::slotted(a) {\n outline: var(--rc-chip-focus-ring, revert);\n outline-offset: var(--rc-chip-focus-ring-offset, revert);\n }\n\n [part='state-layer'] {\n pointer-events: none;\n position: absolute;\n inset: 0;\n border-radius: var(--rc-chip-radius, 0);\n background: var(--rc-chip-state-layer-color, currentColor);\n opacity: 0;\n transition: opacity\n var(--rc-chip-state-layer-transition-duration, var(--rc-motion-effects-duration-fast, 80ms))\n var(--rc-chip-state-layer-transition-easing, var(--rc-motion-effects-easing-fast, ease-out));\n }\n\n :host([selected]) [part='state-layer'] {\n background: var(\n --rc-chip-selected-state-layer-color,\n var(--rc-chip-state-layer-color, currentColor)\n );\n }\n\n @media (hover: hover) {\n :host(:not([disabled], [readonly]):hover) [part='state-layer'] {\n opacity: var(--rc-chip-hover-state-layer-opacity, 0.08);\n }\n }\n\n :host(:not([disabled], [readonly]):focus-within) [part='state-layer'] {\n opacity: var(--rc-chip-focus-state-layer-opacity, 0.12);\n }\n\n :host(:not([disabled], [readonly]):active) [part='state-layer'] {\n opacity: var(--rc-chip-pressed-state-layer-opacity, 0.12);\n }\n\n [part='remove'] {\n position: absolute;\n pointer-events: none;\n inset-block: 0;\n inset-inline-end: var(--rc-chip-remove-offset-inline, 0.125rem);\n display: none;\n place-items: center;\n min-inline-size: var(--rc-chip-remove-target-size, 1.5rem);\n min-block-size: var(--rc-chip-remove-target-size, 1.5rem);\n margin: auto 0;\n border: 0;\n border-radius: var(--rc-chip-remove-radius, 9999px);\n background: transparent;\n color: inherit;\n font: inherit;\n }\n\n :host([removable]) [part='remove'] {\n display: inline-grid;\n }\n\n ::slotted([slot='remove-icon']) {\n /* Keep icon-font utility classes from overriding the chip's compact icon size. */\n font-size: var(--rc-chip-remove-icon-size, smaller) !important;\n }\n\n :host([removable]) ::slotted(button),\n :host([removable]) ::slotted(a),\n :host([removable]) ::slotted([data-rc-chip-label]) {\n padding-inline-end: var(\n --rc-chip-removable-padding-inline-end,\n calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))\n );\n }\n\n @media (forced-colors: active) {\n [part='state-layer'] {\n display: none;\n }\n\n ::slotted(button),\n ::slotted(a),\n ::slotted([data-rc-chip-label]) {\n border-color: ButtonBorder;\n background: ButtonFace;\n color: ButtonText;\n }\n\n :host([selected]) ::slotted(button),\n :host([selected]) ::slotted(a),\n :host([selected]) ::slotted([data-rc-chip-label]) {\n border-color: Highlight;\n background: Highlight;\n color: HighlightText;\n }\n }\n`;\n\nexport default chipStyles;\n","import { LitElement, html } from 'lit';\nimport type { PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport chipStyles from './rc-chip.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-chip': RCChip;\n }\n\n interface HTMLElementEventMap {\n 'rc-chip-change': CustomEvent<RCChipChangeDetail>;\n 'rc-chip-remove': CustomEvent<RCChipRemoveDetail>;\n }\n}\n\nconst TOGGLE_ROLES = new Set(['checkbox', 'menuitemcheckbox', 'menuitemradio', 'radio', 'switch']);\n\n/** Supported chip variants. */\nexport type RCChipVariant = 'assist' | 'filter' | 'input' | 'suggestion';\n\n/** Detail payload for `rc-chip-change`. */\nexport interface RCChipChangeDetail {\n /** Selected state after user interaction. */\n selected: boolean;\n}\n\n/** Detail payload for `rc-chip-remove`. */\nexport interface RCChipRemoveDetail {\n /** The host chip requesting removal. */\n chip: RCChip;\n}\n\n/**\n * Chip wrapper that preserves a direct native `<button>` child for interactive\n * chips and accepts a direct `[data-rc-chip-label]` child for read-only chips.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-chip rc-chip docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/button/ WAI-ARIA button pattern}\n *\n * @slot - A direct native `<button>` child, or `[data-rc-chip-label]` when `readonly`.\n * @slot remove-icon - Optional presentational remove icon.\n *\n * @fires rc-chip-change - Fired when a user toggles a filter chip.\n * @fires rc-chip-remove - Fired when a user activates a removable chip's native button.\n *\n * @csspart state-layer - Overlay layer for hover, focus, pressed, ripple, or design-system effects.\n * @csspart remove - Presentational trailing remove indicator.\n *\n * @cssprop [--rc-chip-gap=0px] - Gap between the slotted button/anchor/label's content.\n * @cssprop [--rc-chip-block-size] - Minimum chip block size (defers to native button/anchor\n * sizing when unset).\n * @cssprop [--rc-chip-padding-block] - Block-axis padding of the slotted button, anchor, or\n * label (defers to native padding when unset).\n * @cssprop [--rc-chip-padding-inline] - Inline-axis padding of the slotted button, anchor, or\n * label (defers to native padding when unset).\n * @cssprop [--rc-chip-border] - Border of the slotted button, anchor, or label (defers to\n * native border when unset).\n * @cssprop [--rc-chip-radius] - Border radius of the slotted button/anchor/label and the\n * state-layer overlay (defers to native border-radius when unset; the state-layer overlay\n * falls back to 0).\n * @cssprop [--rc-chip-bg] - Background of the slotted button, anchor, or label (defers to\n * native background when unset).\n * @cssprop [--rc-chip-color] - Text color of the slotted button, anchor, or label (defers to\n * native color when unset).\n * @cssprop [--rc-chip-font] - Font shorthand for the slotted button, anchor, or label (defers\n * to native font when unset).\n * @cssprop [--rc-chip-text-decoration] - Text decoration for the slotted anchor (defers to\n * native text-decoration when unset).\n * @cssprop [--rc-chip-selected-border-color] - Border color when `selected` (defers to native\n * styling when unset).\n * @cssprop [--rc-chip-selected-bg] - Background when `selected` (defers to native styling when\n * unset).\n * @cssprop [--rc-chip-selected-color] - Text color when `selected` (defers to native styling\n * when unset).\n * @cssprop [--rc-chip-disabled-opacity] - Opacity of the slotted button when `disabled` (defers\n * to native disabled styling when unset).\n * @cssprop [--rc-chip-focus-ring] - Outline shown while focus-within (defers to native focus\n * styling when unset).\n * @cssprop [--rc-chip-focus-ring-offset] - Outline offset while focus-within (defers to native\n * focus styling when unset).\n * @cssprop [--rc-chip-state-layer-color=currentColor] - Hover/focus/pressed state-layer color.\n * @cssprop [--rc-chip-selected-state-layer-color=var(--rc-chip-state-layer-color, currentColor)] - Selected chip state-layer color.\n * @cssprop [--rc-chip-hover-state-layer-opacity=0.08] - Hover state-layer opacity.\n * @cssprop [--rc-chip-focus-state-layer-opacity=0.12] - Focus state-layer opacity.\n * @cssprop [--rc-chip-pressed-state-layer-opacity=0.12] - Pressed state-layer opacity.\n * @cssprop [--rc-chip-state-layer-transition-duration=var(--rc-motion-effects-duration-fast,80ms)] - State-layer effects duration.\n * @cssprop [--rc-chip-state-layer-transition-easing=var(--rc-motion-effects-easing-fast,ease-out)] - State-layer effects easing.\n * @cssprop [--rc-chip-remove-offset-inline=0.125rem] - Inline offset of the remove indicator\n * from the chip edge.\n * @cssprop [--rc-chip-remove-target-size=1.5rem] - Minimum inline and block size of the remove\n * indicator's hit target.\n * @cssprop [--rc-chip-remove-radius=9999px] - Border radius of the remove indicator.\n * @cssprop [--rc-chip-remove-icon-size=smaller] - Font size for a slotted remove icon.\n * @cssprop [--rc-chip-removable-padding-inline-end=calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))] - Override for removable chip content end padding.\n *\n * @attr variant - Chip variant: `assist`, `filter`, `input`, or `suggestion`.\n * @attr selected - Declarative selected state for filter/input chips.\n * @attr default-selected - Initial selected state for uncontrolled usage.\n * @attr disabled - Mirrors disabled state to the native child button.\n * @attr readonly - Marks the chip as non-interactive display content.\n * @attr removable - Shows a trailing remove affordance.\n */\nexport class RCChip extends LitElement {\n static override styles = chipStyles;\n\n private _selected: boolean | undefined;\n private _defaultSelected = false;\n private _selectedInitialized = false;\n private _$button: HTMLButtonElement | null = null;\n private _buttonObserver: MutationObserver | null = null;\n private _disabledOwned = false;\n private _pressedOwned = false;\n private _slotMicrotaskQueued = false;\n\n /** Chip variant. */\n @property({ type: String, reflect: true })\n variant: RCChipVariant = 'assist';\n\n /** Current selected state. Host writes are silent. */\n @property({ type: Boolean, reflect: true })\n get selected(): boolean {\n return this._selected ?? this._defaultSelected;\n }\n\n set selected(value: boolean | undefined) {\n const oldValue = this.selected;\n\n this._selected = value;\n this._selectedInitialized = true;\n this._syncPressedState();\n this.requestUpdate('selected', oldValue);\n }\n\n /** Initial selected state for uncontrolled usage. */\n @property({ type: Boolean, attribute: 'default-selected' })\n get defaultSelected(): boolean {\n return this._defaultSelected;\n }\n\n set defaultSelected(value: boolean) {\n const oldValue = this._defaultSelected;\n\n this._defaultSelected = value;\n\n if (!this._selectedInitialized && this._selected === undefined) {\n this._syncPressedState();\n this.requestUpdate('selected', oldValue);\n }\n\n this.requestUpdate('defaultSelected', oldValue);\n }\n\n /** Mirror disabled state to the native child button. */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Mark this chip as non-interactive display content. */\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /** Show a trailing remove affordance. */\n @property({ type: Boolean, reflect: true })\n removable = false;\n\n override disconnectedCallback(): void {\n this._$button?.removeEventListener('click', this._handleButtonClick);\n this._buttonObserver?.disconnect();\n this._buttonObserver = null;\n super.disconnectedCallback();\n }\n\n protected override firstUpdated(): void {\n this._syncSlottedButton();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n if (changed.has('disabled') || changed.has('readonly')) {\n this._syncDisabled();\n }\n\n if (\n changed.has('variant') ||\n changed.has('selected') ||\n changed.has('readonly') ||\n changed.has('removable')\n ) {\n this._syncPressedState();\n }\n }\n\n protected override render() {\n return html`\n <slot @slotchange=${this._handleSlotChange}></slot>\n <span part=\"state-layer\" aria-hidden=\"true\"></span>\n ${this.removable\n ? html`\n <span part=\"remove\" aria-hidden=\"true\">\n <slot name=\"remove-icon\">×</slot>\n </span>\n `\n : ''}\n `;\n }\n\n private _handleSlotChange(): void {\n if (this._slotMicrotaskQueued) {\n return;\n }\n\n this._slotMicrotaskQueued = true;\n\n queueMicrotask(() => {\n this._slotMicrotaskQueued = false;\n\n if (this.isConnected) {\n this._syncSlottedButton();\n }\n });\n }\n\n private _syncSlottedButton(): void {\n const $nextButton = this.querySelector<HTMLButtonElement>(':scope > button');\n\n if (!$nextButton && !this.readonly && import.meta.env.DEV) {\n console.warn(\n '[rc-chip] No direct child <button> found. Place a native <button> inside <rc-chip>, or use readonly with a [data-rc-chip-label] child.',\n this,\n );\n }\n\n if ($nextButton === this._$button) {\n this._syncDisabled();\n this._syncPressedState();\n\n return;\n }\n\n this._$button?.removeEventListener('click', this._handleButtonClick);\n this._buttonObserver?.disconnect();\n this._buttonObserver = null;\n this._$button = $nextButton;\n this._disabledOwned = false;\n this._pressedOwned = false;\n\n if ($nextButton) {\n $nextButton.addEventListener('click', this._handleButtonClick);\n\n this._buttonObserver = new MutationObserver(() => {\n this._syncDisabled();\n this._syncPressedState();\n });\n\n this._buttonObserver.observe($nextButton, {\n attributeFilter: ['aria-pressed', 'role', 'disabled'],\n });\n }\n\n this._syncDisabled();\n this._syncPressedState();\n }\n\n private readonly _handleButtonClick = (): void => {\n if (this.disabled || this.readonly) {\n return;\n }\n\n if (this.removable) {\n this._dispatchRemove();\n\n return;\n }\n\n if (this.variant !== 'filter') {\n return;\n }\n\n const oldValue = this.selected;\n\n this._selected = !this.selected;\n this._selectedInitialized = true;\n this._syncPressedState();\n this.requestUpdate('selected', oldValue);\n\n this.dispatchEvent(\n new CustomEvent<RCChipChangeDetail>('rc-chip-change', {\n bubbles: true,\n composed: true,\n detail: { selected: this.selected },\n }),\n );\n };\n\n private _dispatchRemove(): void {\n this.dispatchEvent(\n new CustomEvent<RCChipRemoveDetail>('rc-chip-remove', {\n bubbles: true,\n composed: true,\n detail: { chip: this },\n }),\n );\n }\n\n private _syncDisabled(): void {\n const $button = this._$button;\n\n if (!$button) {\n return;\n }\n\n if (this.disabled || this.readonly) {\n if (!$button.disabled) {\n this._disabledOwned = true;\n }\n\n $button.disabled = true;\n } else if (this._disabledOwned) {\n $button.disabled = false;\n this._disabledOwned = false;\n }\n }\n\n private _syncPressedState(): void {\n const $button = this._$button;\n\n if (!$button) {\n return;\n }\n\n const role = $button.getAttribute('role');\n const authorOwnsState =\n ($button.hasAttribute('aria-pressed') && !this._pressedOwned) ||\n (role ? TOGGLE_ROLES.has(role) : false);\n\n if (!this.readonly && !this.removable && this.variant === 'filter' && !authorOwnsState) {\n const pressed = this.selected ? 'true' : 'false';\n\n if ($button.getAttribute('aria-pressed') !== pressed) {\n $button.setAttribute('aria-pressed', pressed);\n }\n\n this._pressedOwned = true;\n } else if (this._pressedOwned) {\n $button.removeAttribute('aria-pressed');\n this._pressedOwned = false;\n }\n }\n}\n\nexport default RCChip;\n"],"names":["chipStyles","css","TOGGLE_ROLES","_RCChip","LitElement","oldValue","value","changed","html","$nextButton","$button","role","authorOwnsState","pressed","RCChip","__decorateClass","property"],"mappings":"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"}
File without changes