@rcarls/rc-chip 0.4.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/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @rcarls/rc-chip
2
+
3
+ Chip wrapper for native button-based actions, filters, and inputs.
4
+
5
+ ```html
6
+ <rc-chip variant="filter">
7
+ <button type="button">Vegetarian</button>
8
+ </rc-chip>
9
+ ```
10
+
11
+ The native button remains connected for keyboard behavior and progressive enhancement.
12
+ Native tap highlighting is suppressed because the component's clipped state layer
13
+ provides hover, focus, and pressed feedback within the chip shape.
14
+
15
+ Use `rc-toolbar` when a group of interactive chips should form one tab stop
16
+ with arrow-key navigation. Import `@rcarls/rc-toolbar/define` separately when
17
+ you are not using the aggregate package:
18
+
19
+ ```html
20
+ <rc-toolbar label="Recipe filters">
21
+ <rc-chip variant="filter">
22
+ <button type="button">Quick</button>
23
+ </rc-chip>
24
+ <rc-chip variant="filter">
25
+ <button type="button">Vegetarian</button>
26
+ </rc-chip>
27
+ </rc-toolbar>
28
+ ```
29
+
30
+ For a removable chip, the direct native button is the only interactive
31
+ control. Activating it fires `rc-chip-remove`; the trailing remove icon is
32
+ presentational. Give the button an action-oriented accessible name:
33
+
34
+ ```html
35
+ <rc-chip variant="input" removable>
36
+ <button type="button" aria-label="Remove basil">Basil</button>
37
+ </rc-chip>
38
+ ```
@@ -0,0 +1,501 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "readme": "",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "src/define.ts",
8
+ "declarations": [],
9
+ "exports": [
10
+ {
11
+ "kind": "custom-element-definition",
12
+ "name": "rc-chip",
13
+ "declaration": {
14
+ "name": "RCChip",
15
+ "module": "/src/rc-chip.js"
16
+ }
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "kind": "javascript-module",
22
+ "path": "src/index.ts",
23
+ "declarations": [],
24
+ "exports": [
25
+ {
26
+ "kind": "js",
27
+ "name": "RCChip",
28
+ "declaration": {
29
+ "name": "default",
30
+ "module": "./rc-chip.js"
31
+ }
32
+ },
33
+ {
34
+ "kind": "js",
35
+ "name": "RCChipChangeDetail",
36
+ "declaration": {
37
+ "name": "RCChipChangeDetail",
38
+ "module": "./rc-chip.js"
39
+ }
40
+ },
41
+ {
42
+ "kind": "js",
43
+ "name": "RCChipRemoveDetail",
44
+ "declaration": {
45
+ "name": "RCChipRemoveDetail",
46
+ "module": "./rc-chip.js"
47
+ }
48
+ },
49
+ {
50
+ "kind": "js",
51
+ "name": "RCChipVariant",
52
+ "declaration": {
53
+ "name": "RCChipVariant",
54
+ "module": "./rc-chip.js"
55
+ }
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ "kind": "javascript-module",
61
+ "path": "src/rc-chip.ts",
62
+ "declarations": [
63
+ {
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.",
66
+ "name": "RCChip",
67
+ "cssProperties": [
68
+ {
69
+ "description": "Gap between the slotted button/anchor/label's content.",
70
+ "name": "--rc-chip-gap",
71
+ "default": "0px"
72
+ },
73
+ {
74
+ "description": "Minimum chip block size (defers to native button/anchor sizing when unset).",
75
+ "name": "--rc-chip-block-size"
76
+ },
77
+ {
78
+ "description": "Block-axis padding of the slotted button, anchor, or label (defers to native padding when unset).",
79
+ "name": "--rc-chip-padding-block"
80
+ },
81
+ {
82
+ "description": "Inline-axis padding of the slotted button, anchor, or label (defers to native padding when unset).",
83
+ "name": "--rc-chip-padding-inline"
84
+ },
85
+ {
86
+ "description": "Border of the slotted button, anchor, or label (defers to native border when unset).",
87
+ "name": "--rc-chip-border"
88
+ },
89
+ {
90
+ "description": "Border radius of the slotted button/anchor/label and the state-layer overlay (defers to native border-radius when unset; the state-layer overlay falls back to 0).",
91
+ "name": "--rc-chip-radius"
92
+ },
93
+ {
94
+ "description": "Background of the slotted button, anchor, or label (defers to native background when unset).",
95
+ "name": "--rc-chip-bg"
96
+ },
97
+ {
98
+ "description": "Text color of the slotted button, anchor, or label (defers to native color when unset).",
99
+ "name": "--rc-chip-color"
100
+ },
101
+ {
102
+ "description": "Font shorthand for the slotted button, anchor, or label (defers to native font when unset).",
103
+ "name": "--rc-chip-font"
104
+ },
105
+ {
106
+ "description": "Text decoration for the slotted anchor (defers to native text-decoration when unset).",
107
+ "name": "--rc-chip-text-decoration"
108
+ },
109
+ {
110
+ "description": "Border color when `selected` (defers to native styling when unset).",
111
+ "name": "--rc-chip-selected-border-color"
112
+ },
113
+ {
114
+ "description": "Background when `selected` (defers to native styling when unset).",
115
+ "name": "--rc-chip-selected-bg"
116
+ },
117
+ {
118
+ "description": "Text color when `selected` (defers to native styling when unset).",
119
+ "name": "--rc-chip-selected-color"
120
+ },
121
+ {
122
+ "description": "Opacity of the slotted button when `disabled` (defers to native disabled styling when unset).",
123
+ "name": "--rc-chip-disabled-opacity"
124
+ },
125
+ {
126
+ "description": "Outline shown while focus-within (defers to native focus styling when unset).",
127
+ "name": "--rc-chip-focus-ring"
128
+ },
129
+ {
130
+ "description": "Outline offset while focus-within (defers to native focus styling when unset).",
131
+ "name": "--rc-chip-focus-ring-offset"
132
+ },
133
+ {
134
+ "description": "Hover/focus/pressed state-layer color.",
135
+ "name": "--rc-chip-state-layer-color",
136
+ "default": "currentColor"
137
+ },
138
+ {
139
+ "description": "Selected chip state-layer color.",
140
+ "name": "--rc-chip-selected-state-layer-color",
141
+ "default": "var(--rc-chip-state-layer-color, currentColor)"
142
+ },
143
+ {
144
+ "description": "Hover state-layer opacity.",
145
+ "name": "--rc-chip-hover-state-layer-opacity",
146
+ "default": "0.08"
147
+ },
148
+ {
149
+ "description": "Focus state-layer opacity.",
150
+ "name": "--rc-chip-focus-state-layer-opacity",
151
+ "default": "0.12"
152
+ },
153
+ {
154
+ "description": "Pressed state-layer opacity.",
155
+ "name": "--rc-chip-pressed-state-layer-opacity",
156
+ "default": "0.12"
157
+ },
158
+ {
159
+ "description": "State-layer effects duration.",
160
+ "name": "--rc-chip-state-layer-transition-duration",
161
+ "default": "var(--rc-motion-effects-duration-fast,80ms)"
162
+ },
163
+ {
164
+ "description": "State-layer effects easing.",
165
+ "name": "--rc-chip-state-layer-transition-easing",
166
+ "default": "var(--rc-motion-effects-easing-fast,ease-out)"
167
+ },
168
+ {
169
+ "description": "Inline offset of the remove indicator from the chip edge.",
170
+ "name": "--rc-chip-remove-offset-inline",
171
+ "default": "0.125rem"
172
+ },
173
+ {
174
+ "description": "Minimum inline and block size of the remove indicator's hit target.",
175
+ "name": "--rc-chip-remove-target-size",
176
+ "default": "1.5rem"
177
+ },
178
+ {
179
+ "description": "Border radius of the remove indicator.",
180
+ "name": "--rc-chip-remove-radius",
181
+ "default": "9999px"
182
+ },
183
+ {
184
+ "description": "Font size for a slotted remove icon.",
185
+ "name": "--rc-chip-remove-icon-size",
186
+ "default": "smaller"
187
+ },
188
+ {
189
+ "description": "Override for removable chip content end padding.",
190
+ "name": "--rc-chip-removable-padding-inline-end",
191
+ "default": "calc(var(--rc-chip-remove-target-size, 1.5rem) - var(--rc-chip-gap, 0px))"
192
+ }
193
+ ],
194
+ "cssParts": [
195
+ {
196
+ "description": "Overlay layer for hover, focus, pressed, ripple, or design-system effects.",
197
+ "name": "state-layer"
198
+ },
199
+ {
200
+ "description": "Presentational trailing remove indicator.",
201
+ "name": "remove"
202
+ }
203
+ ],
204
+ "slots": [
205
+ {
206
+ "description": "A direct native `<button>` child, or `[data-rc-chip-label]` when `readonly`.",
207
+ "name": ""
208
+ },
209
+ {
210
+ "description": "Optional presentational remove icon.",
211
+ "name": "remove-icon"
212
+ }
213
+ ],
214
+ "members": [
215
+ {
216
+ "kind": "field",
217
+ "name": "_selected",
218
+ "type": {
219
+ "text": "boolean | undefined"
220
+ },
221
+ "privacy": "private"
222
+ },
223
+ {
224
+ "kind": "field",
225
+ "name": "_defaultSelected",
226
+ "type": {
227
+ "text": "boolean"
228
+ },
229
+ "privacy": "private",
230
+ "default": "false"
231
+ },
232
+ {
233
+ "kind": "field",
234
+ "name": "_selectedInitialized",
235
+ "type": {
236
+ "text": "boolean"
237
+ },
238
+ "privacy": "private",
239
+ "default": "false"
240
+ },
241
+ {
242
+ "kind": "field",
243
+ "name": "_$button",
244
+ "type": {
245
+ "text": "HTMLButtonElement | null"
246
+ },
247
+ "privacy": "private",
248
+ "default": "null"
249
+ },
250
+ {
251
+ "kind": "field",
252
+ "name": "_buttonObserver",
253
+ "type": {
254
+ "text": "MutationObserver | null"
255
+ },
256
+ "privacy": "private",
257
+ "default": "null"
258
+ },
259
+ {
260
+ "kind": "field",
261
+ "name": "_disabledOwned",
262
+ "type": {
263
+ "text": "boolean"
264
+ },
265
+ "privacy": "private",
266
+ "default": "false"
267
+ },
268
+ {
269
+ "kind": "field",
270
+ "name": "_pressedOwned",
271
+ "type": {
272
+ "text": "boolean"
273
+ },
274
+ "privacy": "private",
275
+ "default": "false"
276
+ },
277
+ {
278
+ "kind": "field",
279
+ "name": "_slotMicrotaskQueued",
280
+ "type": {
281
+ "text": "boolean"
282
+ },
283
+ "privacy": "private",
284
+ "default": "false"
285
+ },
286
+ {
287
+ "kind": "field",
288
+ "name": "variant",
289
+ "type": {
290
+ "text": "RCChipVariant"
291
+ },
292
+ "default": "'assist'",
293
+ "description": "Chip variant.",
294
+ "attribute": "variant",
295
+ "reflects": true
296
+ },
297
+ {
298
+ "kind": "field",
299
+ "name": "selected",
300
+ "type": {
301
+ "text": "boolean"
302
+ },
303
+ "description": "Current selected state. Host writes are silent.",
304
+ "attribute": "selected",
305
+ "reflects": true
306
+ },
307
+ {
308
+ "kind": "field",
309
+ "name": "defaultSelected",
310
+ "type": {
311
+ "text": "boolean"
312
+ },
313
+ "description": "Initial selected state for uncontrolled usage.",
314
+ "attribute": "default-selected"
315
+ },
316
+ {
317
+ "kind": "field",
318
+ "name": "disabled",
319
+ "type": {
320
+ "text": "boolean"
321
+ },
322
+ "default": "false",
323
+ "description": "Mirror disabled state to the native child button.",
324
+ "attribute": "disabled",
325
+ "reflects": true
326
+ },
327
+ {
328
+ "kind": "field",
329
+ "name": "readonly",
330
+ "type": {
331
+ "text": "boolean"
332
+ },
333
+ "default": "false",
334
+ "description": "Mark this chip as non-interactive display content.",
335
+ "attribute": "readonly",
336
+ "reflects": true
337
+ },
338
+ {
339
+ "kind": "field",
340
+ "name": "removable",
341
+ "type": {
342
+ "text": "boolean"
343
+ },
344
+ "default": "false",
345
+ "description": "Show a trailing remove affordance.",
346
+ "attribute": "removable",
347
+ "reflects": true
348
+ },
349
+ {
350
+ "kind": "method",
351
+ "name": "_handleSlotChange",
352
+ "privacy": "private",
353
+ "return": {
354
+ "type": {
355
+ "text": "void"
356
+ }
357
+ }
358
+ },
359
+ {
360
+ "kind": "method",
361
+ "name": "_syncSlottedButton",
362
+ "privacy": "private",
363
+ "return": {
364
+ "type": {
365
+ "text": "void"
366
+ }
367
+ }
368
+ },
369
+ {
370
+ "kind": "field",
371
+ "name": "_handleButtonClick",
372
+ "privacy": "private",
373
+ "readonly": true
374
+ },
375
+ {
376
+ "kind": "method",
377
+ "name": "_dispatchRemove",
378
+ "privacy": "private",
379
+ "return": {
380
+ "type": {
381
+ "text": "void"
382
+ }
383
+ }
384
+ },
385
+ {
386
+ "kind": "method",
387
+ "name": "_syncDisabled",
388
+ "privacy": "private",
389
+ "return": {
390
+ "type": {
391
+ "text": "void"
392
+ }
393
+ }
394
+ },
395
+ {
396
+ "kind": "method",
397
+ "name": "_syncPressedState",
398
+ "privacy": "private",
399
+ "return": {
400
+ "type": {
401
+ "text": "void"
402
+ }
403
+ }
404
+ }
405
+ ],
406
+ "events": [
407
+ {
408
+ "name": "rc-chip-remove",
409
+ "type": {
410
+ "text": "CustomEvent"
411
+ },
412
+ "description": "Fired when a user activates a removable chip's native button."
413
+ },
414
+ {
415
+ "description": "Fired when a user toggles a filter chip.",
416
+ "name": "rc-chip-change"
417
+ }
418
+ ],
419
+ "attributes": [
420
+ {
421
+ "description": "Chip variant.",
422
+ "name": "variant",
423
+ "type": {
424
+ "text": "RCChipVariant"
425
+ },
426
+ "default": "'assist'",
427
+ "fieldName": "variant"
428
+ },
429
+ {
430
+ "description": "Current selected state. Host writes are silent.",
431
+ "name": "selected",
432
+ "type": {
433
+ "text": "boolean"
434
+ },
435
+ "fieldName": "selected"
436
+ },
437
+ {
438
+ "description": "Initial selected state for uncontrolled usage.",
439
+ "name": "default-selected",
440
+ "type": {
441
+ "text": "boolean"
442
+ },
443
+ "fieldName": "defaultSelected"
444
+ },
445
+ {
446
+ "description": "Mirror disabled state to the native child button.",
447
+ "name": "disabled",
448
+ "type": {
449
+ "text": "boolean"
450
+ },
451
+ "default": "false",
452
+ "fieldName": "disabled"
453
+ },
454
+ {
455
+ "description": "Mark this chip as non-interactive display content.",
456
+ "name": "readonly",
457
+ "type": {
458
+ "text": "boolean"
459
+ },
460
+ "default": "false",
461
+ "fieldName": "readonly"
462
+ },
463
+ {
464
+ "description": "Show a trailing remove affordance.",
465
+ "name": "removable",
466
+ "type": {
467
+ "text": "boolean"
468
+ },
469
+ "default": "false",
470
+ "fieldName": "removable"
471
+ }
472
+ ],
473
+ "superclass": {
474
+ "name": "LitElement",
475
+ "package": "lit"
476
+ },
477
+ "tagName": "rc-chip",
478
+ "customElement": true
479
+ }
480
+ ],
481
+ "exports": [
482
+ {
483
+ "kind": "js",
484
+ "name": "RCChip",
485
+ "declaration": {
486
+ "name": "RCChip",
487
+ "module": "src/rc-chip.ts"
488
+ }
489
+ },
490
+ {
491
+ "kind": "js",
492
+ "name": "default",
493
+ "declaration": {
494
+ "name": "RCChip",
495
+ "module": "src/rc-chip.ts"
496
+ }
497
+ }
498
+ ]
499
+ }
500
+ ]
501
+ }
@@ -0,0 +1,267 @@
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
@@ -0,0 +1 @@
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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"}
@@ -0,0 +1,3 @@
1
+ import { R as e } from "./rc-chip-Do50B5yx.js";
2
+ customElements.get("rc-chip") || customElements.define("rc-chip", e);
3
+ //# sourceMappingURL=rc-chip-define.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-chip-define.js","sources":["../src/define.ts"],"sourcesContent":["import RCChip from './rc-chip.js';\n\ncustomElements.get('rc-chip') || customElements.define('rc-chip', RCChip);\n"],"names":["RCChip"],"mappings":";AAEA,eAAe,IAAI,SAAS,KAAK,eAAe,OAAO,WAAWA,CAAM;"}
@@ -0,0 +1,5 @@
1
+ import { R as r } from "./rc-chip-Do50B5yx.js";
2
+ export {
3
+ r as RCChip
4
+ };
5
+ //# sourceMappingURL=rc-chip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-chip.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { default as RCChip } from './rc-chip.js';
2
+ export type { RCChipChangeDetail, RCChipRemoveDetail, RCChipVariant } from './rc-chip.js';
@@ -0,0 +1,128 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ 'rc-chip': RCChip;
5
+ }
6
+ interface HTMLElementEventMap {
7
+ 'rc-chip-change': CustomEvent<RCChipChangeDetail>;
8
+ 'rc-chip-remove': CustomEvent<RCChipRemoveDetail>;
9
+ }
10
+ }
11
+ /** Supported chip variants. */
12
+ export type RCChipVariant = 'assist' | 'filter' | 'input' | 'suggestion';
13
+ /** Detail payload for `rc-chip-change`. */
14
+ export interface RCChipChangeDetail {
15
+ /** Selected state after user interaction. */
16
+ selected: boolean;
17
+ }
18
+ /** Detail payload for `rc-chip-remove`. */
19
+ export interface RCChipRemoveDetail {
20
+ /** The host chip requesting removal. */
21
+ chip: RCChip;
22
+ }
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.
26
+ *
27
+ * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-chip rc-chip docs}
28
+ * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/button/ WAI-ARIA button pattern}
29
+ *
30
+ * @slot - A direct native `<button>` child, or `[data-rc-chip-label]` when `readonly`.
31
+ * @slot remove-icon - Optional presentational remove icon.
32
+ *
33
+ * @fires rc-chip-change - Fired when a user toggles a filter chip.
34
+ * @fires rc-chip-remove - Fired when a user activates a removable chip's native button.
35
+ *
36
+ * @csspart state-layer - Overlay layer for hover, focus, pressed, ripple, or design-system effects.
37
+ * @csspart remove - Presentational trailing remove indicator.
38
+ *
39
+ * @cssprop [--rc-chip-gap=0px] - Gap between the slotted button/anchor/label's content.
40
+ * @cssprop [--rc-chip-block-size] - Minimum chip block size (defers to native button/anchor
41
+ * sizing when unset).
42
+ * @cssprop [--rc-chip-padding-block] - Block-axis padding of the slotted button, anchor, or
43
+ * label (defers to native padding when unset).
44
+ * @cssprop [--rc-chip-padding-inline] - Inline-axis padding of the slotted button, anchor, or
45
+ * label (defers to native padding when unset).
46
+ * @cssprop [--rc-chip-border] - Border of the slotted button, anchor, or label (defers to
47
+ * native border when unset).
48
+ * @cssprop [--rc-chip-radius] - Border radius of the slotted button/anchor/label and the
49
+ * state-layer overlay (defers to native border-radius when unset; the state-layer overlay
50
+ * falls back to 0).
51
+ * @cssprop [--rc-chip-bg] - Background of the slotted button, anchor, or label (defers to
52
+ * native background when unset).
53
+ * @cssprop [--rc-chip-color] - Text color of the slotted button, anchor, or label (defers to
54
+ * native color when unset).
55
+ * @cssprop [--rc-chip-font] - Font shorthand for the slotted button, anchor, or label (defers
56
+ * to native font when unset).
57
+ * @cssprop [--rc-chip-text-decoration] - Text decoration for the slotted anchor (defers to
58
+ * native text-decoration when unset).
59
+ * @cssprop [--rc-chip-selected-border-color] - Border color when `selected` (defers to native
60
+ * styling when unset).
61
+ * @cssprop [--rc-chip-selected-bg] - Background when `selected` (defers to native styling when
62
+ * unset).
63
+ * @cssprop [--rc-chip-selected-color] - Text color when `selected` (defers to native styling
64
+ * when unset).
65
+ * @cssprop [--rc-chip-disabled-opacity] - Opacity of the slotted button when `disabled` (defers
66
+ * to native disabled styling when unset).
67
+ * @cssprop [--rc-chip-focus-ring] - Outline shown while focus-within (defers to native focus
68
+ * styling when unset).
69
+ * @cssprop [--rc-chip-focus-ring-offset] - Outline offset while focus-within (defers to native
70
+ * focus styling when unset).
71
+ * @cssprop [--rc-chip-state-layer-color=currentColor] - Hover/focus/pressed state-layer color.
72
+ * @cssprop [--rc-chip-selected-state-layer-color=var(--rc-chip-state-layer-color, currentColor)] - Selected chip state-layer color.
73
+ * @cssprop [--rc-chip-hover-state-layer-opacity=0.08] - Hover state-layer opacity.
74
+ * @cssprop [--rc-chip-focus-state-layer-opacity=0.12] - Focus state-layer opacity.
75
+ * @cssprop [--rc-chip-pressed-state-layer-opacity=0.12] - Pressed state-layer opacity.
76
+ * @cssprop [--rc-chip-state-layer-transition-duration=var(--rc-motion-effects-duration-fast,80ms)] - State-layer effects duration.
77
+ * @cssprop [--rc-chip-state-layer-transition-easing=var(--rc-motion-effects-easing-fast,ease-out)] - State-layer effects easing.
78
+ * @cssprop [--rc-chip-remove-offset-inline=0.125rem] - Inline offset of the remove indicator
79
+ * from the chip edge.
80
+ * @cssprop [--rc-chip-remove-target-size=1.5rem] - Minimum inline and block size of the remove
81
+ * indicator's hit target.
82
+ * @cssprop [--rc-chip-remove-radius=9999px] - Border radius of the remove indicator.
83
+ * @cssprop [--rc-chip-remove-icon-size=smaller] - Font size for a slotted remove icon.
84
+ * @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.
85
+ *
86
+ * @attr variant - Chip variant: `assist`, `filter`, `input`, or `suggestion`.
87
+ * @attr selected - Declarative selected state for filter/input chips.
88
+ * @attr default-selected - Initial selected state for uncontrolled usage.
89
+ * @attr disabled - Mirrors disabled state to the native child button.
90
+ * @attr readonly - Marks the chip as non-interactive display content.
91
+ * @attr removable - Shows a trailing remove affordance.
92
+ */
93
+ export declare class RCChip extends LitElement {
94
+ static styles: import('lit').CSSResult;
95
+ private _selected;
96
+ private _defaultSelected;
97
+ private _selectedInitialized;
98
+ private _$button;
99
+ private _buttonObserver;
100
+ private _disabledOwned;
101
+ private _pressedOwned;
102
+ private _slotMicrotaskQueued;
103
+ /** Chip variant. */
104
+ variant: RCChipVariant;
105
+ /** Current selected state. Host writes are silent. */
106
+ get selected(): boolean;
107
+ set selected(value: boolean | undefined);
108
+ /** Initial selected state for uncontrolled usage. */
109
+ get defaultSelected(): boolean;
110
+ set defaultSelected(value: boolean);
111
+ /** Mirror disabled state to the native child button. */
112
+ disabled: boolean;
113
+ /** Mark this chip as non-interactive display content. */
114
+ readonly: boolean;
115
+ /** Show a trailing remove affordance. */
116
+ removable: boolean;
117
+ disconnectedCallback(): void;
118
+ protected firstUpdated(): void;
119
+ protected updated(changed: PropertyValues<this>): void;
120
+ protected render(): import('lit').TemplateResult<1>;
121
+ private _handleSlotChange;
122
+ private _syncSlottedButton;
123
+ private readonly _handleButtonClick;
124
+ private _dispatchRemove;
125
+ private _syncDisabled;
126
+ private _syncPressedState;
127
+ }
128
+ export default RCChip;
@@ -0,0 +1,2 @@
1
+ export declare const chipStyles: import('lit').CSSResult;
2
+ export default chipStyles;
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@rcarls/rc-chip",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "0.4.0",
7
+ "description": "Chip wrapper for native button-based actions, filters, and inputs.",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/richardcarls/rc-webcomponents.git",
11
+ "directory": "packages/rc-chip"
12
+ },
13
+ "homepage": "https://richardcarls.github.io/rc-webcomponents/components/rc-chip",
14
+ "license": "MIT",
15
+ "type": "module",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "module": "./dist/rc-chip.js",
20
+ "exports": {
21
+ ".": {
22
+ "import": {
23
+ "types": "./dist/types/packages/rc-chip/src/index.d.ts",
24
+ "default": "./dist/rc-chip.js"
25
+ }
26
+ },
27
+ "./define": {
28
+ "import": {
29
+ "types": "./dist/types/packages/rc-chip/src/define.d.ts",
30
+ "default": "./dist/rc-chip-define.js"
31
+ }
32
+ }
33
+ },
34
+ "types": "./dist/types/packages/rc-chip/src/index.d.ts",
35
+ "sideEffects": [
36
+ "./dist/rc-chip-define.js"
37
+ ],
38
+ "customElements": "dist/custom-elements.json",
39
+ "scripts": {
40
+ "build": "tsc && vite build && cem analyze",
41
+ "cem:analyze": "cem analyze",
42
+ "preview": "vite preview",
43
+ "test:browser": "vitest --run",
44
+ "test:browser:chrome": "vitest --run --project=chromium",
45
+ "test:browser:firefox": "vitest --run --project=firefox"
46
+ },
47
+ "devDependencies": {
48
+ "@custom-elements-manifest/analyzer": "0.11.0",
49
+ "@vitest/browser-playwright": "4.1.5",
50
+ "lit": "^3.0.0",
51
+ "playwright": "^1.56.0",
52
+ "rollup": "^4.60.2",
53
+ "typescript": "~5.9.3",
54
+ "vite": "^7.1.7",
55
+ "vite-plugin-dts": "^4.5.4",
56
+ "vitest": "^4.0.6",
57
+ "vitest-browser-lit": "^1.0.1"
58
+ },
59
+ "peerDependencies": {
60
+ "lit": "^3.0.0"
61
+ }
62
+ }