@rcarls/rc-button 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.
@@ -0,0 +1,413 @@
1
+ import { css as p, LitElement as h, html as b } from "lit";
2
+ import { property as a, query as u } from "lit/decorators.js";
3
+ const y = p`
4
+ :host {
5
+ position: relative;
6
+ display: inline-grid;
7
+ vertical-align: middle;
8
+ }
9
+
10
+ :host([hidden]) {
11
+ display: none;
12
+ }
13
+
14
+ :host([full-width]) {
15
+ display: grid;
16
+ inline-size: 100%;
17
+ }
18
+
19
+ ::slotted(button) {
20
+ position: relative;
21
+ display: inline-flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ gap: var(--rc-button-gap);
25
+ min-block-size: var(--rc-button-block-size);
26
+ min-inline-size: var(--rc-button-min-inline-size);
27
+ inline-size: var(--rc-button-inline-size);
28
+ padding-block: var(--rc-button-padding-block, revert);
29
+ padding-inline: var(--rc-button-padding-inline, revert);
30
+ border: var(--rc-button-border, revert);
31
+ border-radius: var(--rc-button-radius, revert);
32
+ background: var(--rc-button-bg, revert);
33
+ color: var(--rc-button-color, revert);
34
+ box-shadow: var(--rc-button-shadow, revert);
35
+ font: var(--rc-button-font, revert);
36
+ white-space: nowrap;
37
+ overflow: hidden;
38
+ box-sizing: border-box;
39
+ z-index: 0;
40
+ transition: var(--rc-button-transition, revert);
41
+ }
42
+
43
+ :host([full-width]) ::slotted(button) {
44
+ inline-size: 100%;
45
+ }
46
+
47
+ :host([icon-only]) ::slotted(button) {
48
+ inline-size: var(
49
+ --rc-button-icon-size,
50
+ var(--rc-button-block-size, var(--rc-control-block-size, 2.5rem))
51
+ );
52
+ min-inline-size: var(
53
+ --rc-button-icon-size,
54
+ var(--rc-button-block-size, var(--rc-control-block-size, 2.5rem))
55
+ );
56
+ padding-inline: 0;
57
+ }
58
+
59
+ :host([disabled]) ::slotted(button),
60
+ :host([pending]) ::slotted(button),
61
+ :host([progress]) ::slotted(button) {
62
+ cursor: default;
63
+ }
64
+
65
+ :host([pending]) ::slotted(button),
66
+ :host([progress]) ::slotted(button) {
67
+ color: var(--rc-button-busy-content-color, transparent);
68
+ }
69
+
70
+ :host([disabled]) ::slotted(button) {
71
+ opacity: var(--rc-button-disabled-opacity, revert);
72
+ }
73
+
74
+ [part='state-layer'],
75
+ [part='progress'] {
76
+ position: absolute;
77
+ inset: 0;
78
+ border-radius: var(--rc-button-radius, 0);
79
+ pointer-events: none;
80
+ }
81
+
82
+ [part='state-layer'] {
83
+ overflow: hidden;
84
+ z-index: 1;
85
+ }
86
+
87
+ [part='state-layer']::before {
88
+ content: '';
89
+ position: absolute;
90
+ inset: 0;
91
+ background: var(--rc-button-state-layer-bg, currentColor);
92
+ opacity: 0;
93
+ transition: opacity var(--rc-button-state-layer-duration, 150ms)
94
+ var(--rc-button-state-layer-easing, ease);
95
+ }
96
+
97
+ [part='state-layer']::after {
98
+ content: '';
99
+ position: absolute;
100
+ inset-inline-start: var(--_rc-button-ripple-x, 50%);
101
+ inset-block-start: var(--_rc-button-ripple-y, 50%);
102
+ inline-size: var(--_rc-button-ripple-size, 0);
103
+ block-size: var(--_rc-button-ripple-size, 0);
104
+ border-radius: 50%;
105
+ background: var(--_rc-button-ripple-color, currentColor);
106
+ opacity: 0;
107
+ pointer-events: none;
108
+ translate: -50% -50%;
109
+ scale: 0;
110
+ }
111
+
112
+ [part='state-layer'][data-rippling]::after {
113
+ animation: rc-button-ripple var(--_rc-button-ripple-duration, 0ms)
114
+ var(--_rc-button-ripple-easing, ease-out);
115
+ }
116
+
117
+ :host(:hover:not([disabled]):not([pending]):not([progress])) [part='state-layer']::before {
118
+ opacity: var(--rc-button-hover-state-layer-opacity, 0);
119
+ }
120
+
121
+ :host(:focus-within:not([disabled])) [part='state-layer']::before {
122
+ opacity: var(--rc-button-focus-state-layer-opacity, 0);
123
+ }
124
+
125
+ :host(:active:not([disabled]):not([pending]):not([progress])) [part='state-layer']::before {
126
+ opacity: var(--rc-button-pressed-state-layer-opacity, 0);
127
+ }
128
+
129
+ [part='progress'] {
130
+ display: none;
131
+ place-items: center;
132
+ color: var(--rc-button-progress-color, currentColor);
133
+ font: var(--rc-button-progress-font, 600 0.75rem / 1 sans-serif);
134
+ font-variant-numeric: tabular-nums;
135
+ z-index: 2;
136
+ }
137
+
138
+ :host([pending]) [part='progress'],
139
+ :host([progress]) [part='progress'] {
140
+ display: grid;
141
+ }
142
+
143
+ [part='progress']::before {
144
+ content: '';
145
+ box-sizing: border-box;
146
+ inline-size: var(--rc-button-progress-size, 1.25rem);
147
+ block-size: var(--rc-button-progress-size, 1.25rem);
148
+ border: var(--rc-button-progress-track-width, 2px) solid
149
+ var(--rc-button-progress-track-color, color-mix(in srgb, currentColor 24%, transparent));
150
+ border-block-start-color: var(--rc-button-progress-active-color, currentColor);
151
+ border-radius: 9999px;
152
+ animation: rc-button-progress-spin 900ms linear infinite;
153
+ }
154
+
155
+ [part='progress'][data-determinate]::before {
156
+ display: none;
157
+ }
158
+
159
+ @keyframes rc-button-progress-spin {
160
+ to {
161
+ rotate: 1turn;
162
+ }
163
+ }
164
+
165
+ @keyframes rc-button-ripple {
166
+ from {
167
+ opacity: var(--_rc-button-ripple-opacity, 0);
168
+ scale: 0;
169
+ }
170
+
171
+ 70% {
172
+ opacity: var(--_rc-button-ripple-opacity, 0);
173
+ }
174
+
175
+ to {
176
+ opacity: 0;
177
+ scale: 1;
178
+ }
179
+ }
180
+
181
+ @media (prefers-reduced-motion: reduce) {
182
+ [part='state-layer'][data-rippling]::after {
183
+ animation-duration: 0ms;
184
+ }
185
+
186
+ [part='progress']::before {
187
+ animation-duration: 2s;
188
+ }
189
+ }
190
+
191
+ @media (forced-colors: active) {
192
+ ::slotted(button) {
193
+ border-color: ButtonBorder;
194
+ background: ButtonFace;
195
+ color: ButtonText;
196
+ }
197
+
198
+ [part='state-layer']::before {
199
+ background: Highlight;
200
+ }
201
+ }
202
+ `;
203
+ var f = Object.defineProperty, _ = Object.getOwnPropertyDescriptor, o = (c, t, e, s) => {
204
+ for (var r = s > 1 ? void 0 : s ? _(t, e) : t, l = c.length - 1, d; l >= 0; l--)
205
+ (d = c[l]) && (r = (s ? d(t, e, r) : d(r)) || r);
206
+ return s && r && f(t, e, r), r;
207
+ };
208
+ const g = `
209
+ @layer rc-base {
210
+ /*
211
+ * Icon-font utility classes commonly set display outside cascade layers.
212
+ * Hiding the inactive icon is structural, so it must win that declaration.
213
+ */
214
+ rc-button[selected] > button > [data-rc-button-icon] {
215
+ display: none !important;
216
+ }
217
+
218
+ rc-button:not([selected]) > button > [data-rc-button-selected-icon] {
219
+ display: none !important;
220
+ }
221
+ }
222
+ `, v = /* @__PURE__ */ new Set(["Enter", " "]);
223
+ var n;
224
+ const i = (n = class extends h {
225
+ constructor() {
226
+ super(), this.disabled = !1, this.pending = !1, this.progress = !1, this.toggle = !1, this.iconOnly = !1, this.fullWidth = !1, this._defaultSelected = !1, this._selectedInitialized = !1, this._$button = null, this._buttonObserver = null, this._disabledOwned = !1, this._ariaBusyOwned = !1, this._pressedOwned = !1, this._authorPressed = null, this._iconOnlyOwned = !1, this._slotMicrotaskQueued = !1, this.addEventListener("pointerdown", this._startRipple, { capture: !0 }), this.addEventListener("click", this._blockActivation, { capture: !0 }), this.addEventListener("click", this._handleToggleActivation), this.addEventListener(
227
+ "keydown",
228
+ (t) => {
229
+ v.has(t.key) && this._blockActivation(t);
230
+ },
231
+ { capture: !0 }
232
+ );
233
+ }
234
+ static _ensureBaseStyles(t) {
235
+ if (n._styledRoots.has(t))
236
+ return;
237
+ n._styledRoots.add(t);
238
+ const e = document.createElement("style");
239
+ e.setAttribute("data-rc-light-dom-base", "rc-button"), e.textContent = g, t instanceof Document ? t.head.append(e) : t.append(e);
240
+ }
241
+ get selected() {
242
+ return this._selected ?? this._uncontrolledSelected ?? this._defaultSelected;
243
+ }
244
+ set selected(t) {
245
+ const e = this.selected;
246
+ this._selected = t, this._selectedInitialized = !0, this._syncPressedState(), this.requestUpdate("selected", e);
247
+ }
248
+ get defaultSelected() {
249
+ return this._defaultSelected;
250
+ }
251
+ set defaultSelected(t) {
252
+ const e = this._defaultSelected;
253
+ this._defaultSelected = t, !this._selectedInitialized && this._selected === void 0 && (this._syncPressedState(), this.requestUpdate("selected", e)), this.requestUpdate("defaultSelected", e);
254
+ }
255
+ connectedCallback() {
256
+ super.connectedCallback(), n._ensureBaseStyles(this.getRootNode());
257
+ }
258
+ disconnectedCallback() {
259
+ this._buttonObserver?.disconnect(), this._buttonObserver = null, super.disconnectedCallback();
260
+ }
261
+ firstUpdated() {
262
+ this._syncSlottedButton();
263
+ }
264
+ updated(t) {
265
+ (t.has("disabled") || t.has("pending") || t.has("progress")) && this._syncNativeState(), (t.has("toggle") || t.has("selected")) && this._syncPressedState();
266
+ }
267
+ render() {
268
+ const t = this._progressPercentage;
269
+ return b`
270
+ <slot @slotchange=${this._handleSlotChange}></slot>
271
+ <span
272
+ part="state-layer"
273
+ aria-hidden="true"
274
+ @animationend=${this._handleRippleAnimationEnd}
275
+ ></span>
276
+ <span part="progress" aria-hidden="true" ?data-determinate=${t !== void 0}
277
+ >${t === void 0 ? "" : `${t}%`}</span
278
+ >
279
+ `;
280
+ }
281
+ get _progressPercentage() {
282
+ if (!(!this.progress || !Number.isFinite(this.progressValue)))
283
+ return Math.round(Math.min(100, Math.max(0, this.progressValue)));
284
+ }
285
+ _handleSlotChange() {
286
+ this._slotMicrotaskQueued || (this._slotMicrotaskQueued = !0, queueMicrotask(() => {
287
+ this._slotMicrotaskQueued = !1, this.isConnected && this._syncSlottedButton();
288
+ }));
289
+ }
290
+ _syncSlottedButton() {
291
+ const t = this._$slot?.assignedElements({ flatten: !0 }).find(
292
+ (e) => e instanceof HTMLButtonElement && e.parentElement === this
293
+ ) ?? null;
294
+ if (t === this._$button) {
295
+ this._classifyButton(), this._syncNativeState(), this._syncPressedState();
296
+ return;
297
+ }
298
+ this._restorePressedState(), this._buttonObserver?.disconnect(), this._buttonObserver = null, this._$button = t, this._disabledOwned = !1, this._ariaBusyOwned = !1, this._pressedOwned = !1, this._authorPressed = t?.getAttribute("aria-pressed") ?? null, t && (this._buttonObserver = new MutationObserver(() => {
299
+ this._classifyButton(), this._syncNativeState(), this._syncPressedState();
300
+ }), this._buttonObserver.observe(t, {
301
+ attributes: !0,
302
+ childList: !0,
303
+ subtree: !0,
304
+ characterData: !0
305
+ })), this._classifyButton(), this._syncNativeState(), this._syncPressedState();
306
+ }
307
+ _classifyButton() {
308
+ const t = this._$button, e = !!t?.querySelector(":scope > [data-rc-button-icon]"), s = !!t?.querySelector(":scope > [data-rc-button-selected-icon]"), r = this._hasLabel(t);
309
+ this.toggleAttribute("has-icon", e), this.toggleAttribute("has-selected-icon", s), this.toggleAttribute("has-label", r), t && e && !r ? this.iconOnly || (this._iconOnlyOwned = !0, this.iconOnly = !0) : this._iconOnlyOwned && (this._iconOnlyOwned = !1, this.iconOnly = !1);
310
+ }
311
+ _hasLabel(t) {
312
+ if (!t)
313
+ return !1;
314
+ if (t.querySelector(":scope > [data-rc-button-label]"))
315
+ return !0;
316
+ for (const e of t.childNodes) {
317
+ if (e.nodeType === Node.TEXT_NODE && e.textContent?.trim())
318
+ return !0;
319
+ if (e instanceof HTMLElement && !e.matches(
320
+ '[data-rc-button-icon], [data-rc-button-selected-icon], [data-rc-button-progress], [aria-hidden="true"]'
321
+ ) && e.textContent?.trim())
322
+ return !0;
323
+ }
324
+ return !1;
325
+ }
326
+ _syncNativeState() {
327
+ const t = this._$button;
328
+ if (!t)
329
+ return;
330
+ const e = this.disabled || this.pending || this.progress;
331
+ e && !t.disabled ? (this._disabledOwned = !0, t.disabled = !0) : !e && this._disabledOwned && (t.disabled = !1, this._disabledOwned = !1), this.pending || this.progress ? t.hasAttribute("aria-busy") || (t.setAttribute("aria-busy", "true"), this._ariaBusyOwned = !0) : this._ariaBusyOwned && (t.removeAttribute("aria-busy"), this._ariaBusyOwned = !1);
332
+ }
333
+ _syncPressedState() {
334
+ const t = this._$button;
335
+ if (t)
336
+ if (this.toggle) {
337
+ const e = this.selected ? "true" : "false";
338
+ t.getAttribute("aria-pressed") !== e && t.setAttribute("aria-pressed", e), this._pressedOwned = !0;
339
+ } else this._pressedOwned && this._restorePressedState();
340
+ }
341
+ _restorePressedState() {
342
+ const t = this._$button;
343
+ !t || !this._pressedOwned || (this._authorPressed === null ? t.removeAttribute("aria-pressed") : t.setAttribute("aria-pressed", this._authorPressed), this._pressedOwned = !1);
344
+ }
345
+ _handleToggleActivation(t) {
346
+ if (!this.toggle || this.disabled || this.pending || this.progress || t.defaultPrevented || !this._isChildButtonEvent(t))
347
+ return;
348
+ const e = this.selected, s = !e;
349
+ this._selected === void 0 && (this._uncontrolledSelected = s, this._selectedInitialized = !0, this._syncPressedState(), this.requestUpdate("selected", e)), this.dispatchEvent(
350
+ new CustomEvent("rc-button-toggle", {
351
+ bubbles: !0,
352
+ composed: !0,
353
+ detail: { selected: s }
354
+ })
355
+ );
356
+ }
357
+ _shouldBlockActivation() {
358
+ return this.pending || this.progress;
359
+ }
360
+ _isChildButtonEvent(t) {
361
+ return !!this._$button && t.composedPath().includes(this._$button);
362
+ }
363
+ _blockActivation(t) {
364
+ !this._shouldBlockActivation() || !this._isChildButtonEvent(t) || (t.preventDefault(), t.stopImmediatePropagation());
365
+ }
366
+ _startRipple(t) {
367
+ if (!t.isPrimary || t.button !== 0 || this.disabled || this.pending || this.progress || !this._isChildButtonEvent(t) || !this._$stateLayer || getComputedStyle(this).getPropertyValue("--_rc-button-ripple-enabled").trim() !== "1")
368
+ return;
369
+ const e = this._$button.getBoundingClientRect(), s = t.clientX - e.left, r = t.clientY - e.top, l = Math.hypot(Math.max(s, e.width - s), Math.max(r, e.height - r));
370
+ this._$stateLayer.style.setProperty("--_rc-button-ripple-x", `${s}px`), this._$stateLayer.style.setProperty("--_rc-button-ripple-y", `${r}px`), this._$stateLayer.style.setProperty("--_rc-button-ripple-size", `${l * 2}px`), this._$stateLayer.removeAttribute("data-rippling"), this._$stateLayer.getBoundingClientRect(), this._$stateLayer.setAttribute("data-rippling", "");
371
+ }
372
+ _handleRippleAnimationEnd(t) {
373
+ t.animationName === "rc-button-ripple" && this._$stateLayer.removeAttribute("data-rippling");
374
+ }
375
+ }, n.styles = y, n._styledRoots = /* @__PURE__ */ new Set(), n);
376
+ o([
377
+ a({ type: Boolean, reflect: !0 })
378
+ ], i.prototype, "disabled", 2);
379
+ o([
380
+ a({ type: Boolean, reflect: !0 })
381
+ ], i.prototype, "pending", 2);
382
+ o([
383
+ a({ type: Boolean, reflect: !0 })
384
+ ], i.prototype, "progress", 2);
385
+ o([
386
+ a({ type: Number, attribute: "progress-value", reflect: !0 })
387
+ ], i.prototype, "progressValue", 2);
388
+ o([
389
+ a({ type: Boolean, reflect: !0 })
390
+ ], i.prototype, "toggle", 2);
391
+ o([
392
+ a({ type: Boolean, reflect: !0 })
393
+ ], i.prototype, "selected", 1);
394
+ o([
395
+ a({ type: Boolean, attribute: "default-selected" })
396
+ ], i.prototype, "defaultSelected", 1);
397
+ o([
398
+ a({ type: Boolean, attribute: "icon-only", reflect: !0 })
399
+ ], i.prototype, "iconOnly", 2);
400
+ o([
401
+ a({ type: Boolean, attribute: "full-width", reflect: !0 })
402
+ ], i.prototype, "fullWidth", 2);
403
+ o([
404
+ u("slot")
405
+ ], i.prototype, "_$slot", 2);
406
+ o([
407
+ u('[part="state-layer"]')
408
+ ], i.prototype, "_$stateLayer", 2);
409
+ let O = i;
410
+ export {
411
+ O as R
412
+ };
413
+ //# sourceMappingURL=rc-button-Ct5C14lN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-button-Ct5C14lN.js","sources":["../src/rc-button.styles.ts","../src/rc-button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const buttonStyles = css`\n :host {\n position: relative;\n display: inline-grid;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n :host([full-width]) {\n display: grid;\n inline-size: 100%;\n }\n\n ::slotted(button) {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--rc-button-gap);\n min-block-size: var(--rc-button-block-size);\n min-inline-size: var(--rc-button-min-inline-size);\n inline-size: var(--rc-button-inline-size);\n padding-block: var(--rc-button-padding-block, revert);\n padding-inline: var(--rc-button-padding-inline, revert);\n border: var(--rc-button-border, revert);\n border-radius: var(--rc-button-radius, revert);\n background: var(--rc-button-bg, revert);\n color: var(--rc-button-color, revert);\n box-shadow: var(--rc-button-shadow, revert);\n font: var(--rc-button-font, revert);\n white-space: nowrap;\n overflow: hidden;\n box-sizing: border-box;\n z-index: 0;\n transition: var(--rc-button-transition, revert);\n }\n\n :host([full-width]) ::slotted(button) {\n inline-size: 100%;\n }\n\n :host([icon-only]) ::slotted(button) {\n inline-size: var(\n --rc-button-icon-size,\n var(--rc-button-block-size, var(--rc-control-block-size, 2.5rem))\n );\n min-inline-size: var(\n --rc-button-icon-size,\n var(--rc-button-block-size, var(--rc-control-block-size, 2.5rem))\n );\n padding-inline: 0;\n }\n\n :host([disabled]) ::slotted(button),\n :host([pending]) ::slotted(button),\n :host([progress]) ::slotted(button) {\n cursor: default;\n }\n\n :host([pending]) ::slotted(button),\n :host([progress]) ::slotted(button) {\n color: var(--rc-button-busy-content-color, transparent);\n }\n\n :host([disabled]) ::slotted(button) {\n opacity: var(--rc-button-disabled-opacity, revert);\n }\n\n [part='state-layer'],\n [part='progress'] {\n position: absolute;\n inset: 0;\n border-radius: var(--rc-button-radius, 0);\n pointer-events: none;\n }\n\n [part='state-layer'] {\n overflow: hidden;\n z-index: 1;\n }\n\n [part='state-layer']::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--rc-button-state-layer-bg, currentColor);\n opacity: 0;\n transition: opacity var(--rc-button-state-layer-duration, 150ms)\n var(--rc-button-state-layer-easing, ease);\n }\n\n [part='state-layer']::after {\n content: '';\n position: absolute;\n inset-inline-start: var(--_rc-button-ripple-x, 50%);\n inset-block-start: var(--_rc-button-ripple-y, 50%);\n inline-size: var(--_rc-button-ripple-size, 0);\n block-size: var(--_rc-button-ripple-size, 0);\n border-radius: 50%;\n background: var(--_rc-button-ripple-color, currentColor);\n opacity: 0;\n pointer-events: none;\n translate: -50% -50%;\n scale: 0;\n }\n\n [part='state-layer'][data-rippling]::after {\n animation: rc-button-ripple var(--_rc-button-ripple-duration, 0ms)\n var(--_rc-button-ripple-easing, ease-out);\n }\n\n :host(:hover:not([disabled]):not([pending]):not([progress])) [part='state-layer']::before {\n opacity: var(--rc-button-hover-state-layer-opacity, 0);\n }\n\n :host(:focus-within:not([disabled])) [part='state-layer']::before {\n opacity: var(--rc-button-focus-state-layer-opacity, 0);\n }\n\n :host(:active:not([disabled]):not([pending]):not([progress])) [part='state-layer']::before {\n opacity: var(--rc-button-pressed-state-layer-opacity, 0);\n }\n\n [part='progress'] {\n display: none;\n place-items: center;\n color: var(--rc-button-progress-color, currentColor);\n font: var(--rc-button-progress-font, 600 0.75rem / 1 sans-serif);\n font-variant-numeric: tabular-nums;\n z-index: 2;\n }\n\n :host([pending]) [part='progress'],\n :host([progress]) [part='progress'] {\n display: grid;\n }\n\n [part='progress']::before {\n content: '';\n box-sizing: border-box;\n inline-size: var(--rc-button-progress-size, 1.25rem);\n block-size: var(--rc-button-progress-size, 1.25rem);\n border: var(--rc-button-progress-track-width, 2px) solid\n var(--rc-button-progress-track-color, color-mix(in srgb, currentColor 24%, transparent));\n border-block-start-color: var(--rc-button-progress-active-color, currentColor);\n border-radius: 9999px;\n animation: rc-button-progress-spin 900ms linear infinite;\n }\n\n [part='progress'][data-determinate]::before {\n display: none;\n }\n\n @keyframes rc-button-progress-spin {\n to {\n rotate: 1turn;\n }\n }\n\n @keyframes rc-button-ripple {\n from {\n opacity: var(--_rc-button-ripple-opacity, 0);\n scale: 0;\n }\n\n 70% {\n opacity: var(--_rc-button-ripple-opacity, 0);\n }\n\n to {\n opacity: 0;\n scale: 1;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n [part='state-layer'][data-rippling]::after {\n animation-duration: 0ms;\n }\n\n [part='progress']::before {\n animation-duration: 2s;\n }\n }\n\n @media (forced-colors: active) {\n ::slotted(button) {\n border-color: ButtonBorder;\n background: ButtonFace;\n color: ButtonText;\n }\n\n [part='state-layer']::before {\n background: Highlight;\n }\n }\n`;\n\nexport default buttonStyles;\n","import { LitElement, html } from 'lit';\nimport type { PropertyValues } from 'lit';\nimport { property, query } from 'lit/decorators.js';\n\nimport buttonStyles from './rc-button.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-button': RCButton;\n }\n\n interface HTMLElementEventMap {\n 'rc-button-toggle': CustomEvent<RCButtonToggleDetail>;\n }\n}\n\nconst LIGHT_DOM_CSS = `\n@layer rc-base {\n /*\n * Icon-font utility classes commonly set display outside cascade layers.\n * Hiding the inactive icon is structural, so it must win that declaration.\n */\n rc-button[selected] > button > [data-rc-button-icon] {\n display: none !important;\n }\n\n rc-button:not([selected]) > button > [data-rc-button-selected-icon] {\n display: none !important;\n }\n}\n`;\n\nconst ACTIVATION_KEYS = new Set(['Enter', ' ']);\n\n/** Detail payload for `rc-button-toggle`. */\nexport interface RCButtonToggleDetail {\n /** Requested selected state after user activation. */\n selected: boolean;\n}\n\n/**\n * Structural button wrapper that preserves a direct native `<button>` child for\n * progressive enhancement, forms, labels, and keyboard behavior.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-button rc-button 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.\n *\n * @fires rc-button-toggle - Fired when a user activates a button with `toggle`.\n *\n * @csspart state-layer - Overlay layer for hover, focus, pressed, ripple, or design-system effects.\n * @csspart progress - Non-interactive progress affordance overlay shown for `pending` or `progress`.\n *\n * @attr disabled - Mirrors disabled state to the native child button.\n * @attr pending - Disables the native button and exposes an indeterminate progress affordance.\n * @attr progress - Disables the native button and exposes a progress affordance.\n * @attr progress-value - Optional determinate progress percentage, clamped from 0 through 100.\n * @attr toggle - Opts the native child into APG toggle-button behavior.\n * @attr selected - Controlled selected state for toggle semantics, styling, and icon switching.\n * @attr default-selected - Initial selected state for uncontrolled toggle usage.\n * @attr icon-only - Removes label-oriented inline padding in supporting themes.\n * @attr full-width - Stretches the native child button to the host inline size.\n * @attr [has-icon] - Present when the native button has a direct `[data-rc-button-icon]` child.\n * Use with CSS selectors (e.g. `rc-button[has-icon]`).\n * @attr [has-selected-icon] - Present when the native button has a direct\n * `[data-rc-button-selected-icon]` child.\n * @attr [has-label] - Present when the native button has visible label content, from either a\n * `[data-rc-button-label]` child or bare text.\n *\n * @cssprop [--rc-button-gap] - Gap between icon and label content.\n * @cssprop [--rc-button-block-size] - Minimum button block size.\n * @cssprop [--rc-button-min-inline-size] - Minimum button inline size.\n * @cssprop [--rc-button-inline-size] - Button inline size.\n * @cssprop [--rc-button-padding-block] - Button block-axis padding (defers to native button\n * padding when unset).\n * @cssprop [--rc-button-padding-inline] - Button inline-axis padding (defers to native button\n * padding when unset).\n * @cssprop [--rc-button-border] - Button border (defers to native button border when unset).\n * @cssprop [--rc-button-radius] - Button and overlay border radius (defers to native button\n * radius when unset).\n * @cssprop [--rc-button-bg] - Button background (defers to native button background when unset).\n * @cssprop [--rc-button-color] - Button text color (defers to native button color when unset).\n * @cssprop [--rc-button-shadow] - Button box shadow (defers to native button shadow when unset).\n * @cssprop [--rc-button-font] - Button font shorthand (defers to native button font when unset).\n * @cssprop [--rc-button-transition] - Button transition shorthand (defers to native button\n * transition when unset).\n * @cssprop [--rc-button-icon-size] - Button inline and min-inline size when `icon-only`. Falls\n * back to `--rc-button-block-size`, then `--rc-control-block-size`, then `2.5rem`.\n * @cssprop [--rc-button-disabled-opacity] - Disabled button opacity (defers to native disabled\n * styling when unset).\n * @cssprop [--rc-button-busy-content-color=transparent] - Button text color while `pending` or\n * `progress`.\n * @cssprop [--rc-button-state-layer-bg=currentColor] - State-layer overlay color.\n * @cssprop [--rc-button-state-layer-duration=150ms] - State-layer opacity transition duration.\n * @cssprop [--rc-button-state-layer-easing=ease] - State-layer opacity transition easing.\n * @cssprop [--rc-button-hover-state-layer-opacity=0] - State-layer opacity on hover.\n * @cssprop [--rc-button-focus-state-layer-opacity=0] - State-layer opacity on focus-within.\n * @cssprop [--rc-button-pressed-state-layer-opacity=0] - State-layer opacity on active press.\n * @cssprop [--rc-button-progress-color=currentColor] - Progress affordance color.\n * @cssprop [--rc-button-progress-font=600 0.75rem / 1 sans-serif] - Determinate progress\n * percentage font.\n * @cssprop [--rc-button-progress-size=1.25rem] - Indeterminate progress spinner diameter.\n * @cssprop [--rc-button-progress-track-width=2px] - Indeterminate progress spinner stroke width.\n * @cssprop [--rc-button-progress-track-color=color-mix(in srgb, currentColor 24%, transparent)] -\n * Indeterminate progress spinner track color.\n * @cssprop [--rc-button-progress-active-color=currentColor] - Indeterminate progress spinner\n * active arc color.\n */\nexport class RCButton extends LitElement {\n static override styles = buttonStyles;\n\n protected static readonly _styledRoots = new Set<Document | ShadowRoot>();\n\n protected static _ensureBaseStyles(root: Document | ShadowRoot): void {\n if (RCButton._styledRoots.has(root)) {\n return;\n }\n\n RCButton._styledRoots.add(root);\n\n const style = document.createElement('style');\n\n style.setAttribute('data-rc-light-dom-base', 'rc-button');\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 /** Mirror disabled state to the native child. */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Show an indeterminate progress affordance and disable the native button. */\n @property({ type: Boolean, reflect: true })\n pending = false;\n\n /** Show a progress affordance and disable the native button. */\n @property({ type: Boolean, reflect: true })\n progress = false;\n\n /** Optional determinate progress percentage, clamped from 0 through 100. */\n @property({ type: Number, attribute: 'progress-value', reflect: true })\n progressValue: number | undefined;\n\n /** Opt the native child into APG toggle-button behavior. */\n @property({ type: Boolean, reflect: true })\n toggle = false;\n\n /** Controlled 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._syncPressedState();\n this.requestUpdate('selected', oldValue);\n }\n\n /** Initial selected state for uncontrolled toggle 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 /** Icon-only layout hint. May also be reflected by child classification. */\n @property({ type: Boolean, attribute: 'icon-only', reflect: true })\n iconOnly = false;\n\n /** Stretch the native child button to the host inline size. */\n @property({ type: Boolean, attribute: 'full-width', reflect: true })\n fullWidth = false;\n\n @query('slot') protected _$slot!: HTMLSlotElement;\n\n @query('[part=\"state-layer\"]') protected _$stateLayer!: HTMLElement;\n\n private _selected: boolean | undefined;\n private _defaultSelected = false;\n private _uncontrolledSelected: boolean | undefined;\n private _selectedInitialized = false;\n protected _$button: HTMLButtonElement | null = null;\n protected _buttonObserver: MutationObserver | null = null;\n protected _disabledOwned = false;\n protected _ariaBusyOwned = false;\n protected _pressedOwned = false;\n protected _authorPressed: string | null = null;\n protected _iconOnlyOwned = false;\n protected _slotMicrotaskQueued = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n RCButton._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n }\n\n override disconnectedCallback(): void {\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('pending') || changed.has('progress')) {\n this._syncNativeState();\n }\n\n if (changed.has('toggle') || changed.has('selected')) {\n this._syncPressedState();\n }\n }\n\n protected override render() {\n const progressPercentage = this._progressPercentage;\n\n return html`\n <slot @slotchange=${this._handleSlotChange}></slot>\n <span\n part=\"state-layer\"\n aria-hidden=\"true\"\n @animationend=${this._handleRippleAnimationEnd}\n ></span>\n <span part=\"progress\" aria-hidden=\"true\" ?data-determinate=${progressPercentage !== undefined}\n >${progressPercentage === undefined ? '' : `${progressPercentage}%`}</span\n >\n `;\n }\n\n protected get _progressPercentage(): number | undefined {\n if (!this.progress || !Number.isFinite(this.progressValue)) {\n return undefined;\n }\n\n return Math.round(Math.min(100, Math.max(0, this.progressValue!)));\n }\n\n protected _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 return;\n }\n\n this._syncSlottedButton();\n });\n }\n\n protected _syncSlottedButton(): void {\n const nextButton =\n this._$slot\n ?.assignedElements({ flatten: true })\n .find(\n (element): element is HTMLButtonElement =>\n element instanceof HTMLButtonElement && element.parentElement === this,\n ) ?? null;\n\n if (!nextButton && import.meta.env.DEV) {\n const misplaced = this.querySelector(\n ':scope > [data-rc-button-icon], :scope > [data-rc-button-selected-icon], :scope > [data-rc-button-label]',\n );\n\n console.warn(\n misplaced\n ? '[rc-button] Place icon and label markers inside the direct child <button>; rc-button will not move author nodes.'\n : '[rc-button] No direct child <button> found. Place a native <button> inside <rc-button>.',\n );\n }\n\n if (nextButton === this._$button) {\n this._classifyButton();\n this._syncNativeState();\n this._syncPressedState();\n\n return;\n }\n\n this._restorePressedState();\n this._buttonObserver?.disconnect();\n this._buttonObserver = null;\n this._$button = nextButton;\n this._disabledOwned = false;\n this._ariaBusyOwned = false;\n this._pressedOwned = false;\n this._authorPressed = nextButton?.getAttribute('aria-pressed') ?? null;\n\n if (nextButton) {\n this._buttonObserver = new MutationObserver(() => {\n this._classifyButton();\n this._syncNativeState();\n this._syncPressedState();\n });\n\n this._buttonObserver.observe(nextButton, {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: true,\n });\n }\n\n this._classifyButton();\n this._syncNativeState();\n this._syncPressedState();\n }\n\n protected _classifyButton(): void {\n const button = this._$button;\n const hasIcon = !!button?.querySelector(':scope > [data-rc-button-icon]');\n const hasSelectedIcon = !!button?.querySelector(':scope > [data-rc-button-selected-icon]');\n const hasLabel = this._hasLabel(button);\n\n this.toggleAttribute('has-icon', hasIcon);\n this.toggleAttribute('has-selected-icon', hasSelectedIcon);\n this.toggleAttribute('has-label', hasLabel);\n\n if (button && hasIcon && !hasLabel) {\n if (!this.iconOnly) {\n this._iconOnlyOwned = true;\n this.iconOnly = true;\n }\n } else if (this._iconOnlyOwned) {\n this._iconOnlyOwned = false;\n this.iconOnly = false;\n }\n }\n\n protected _hasLabel(button: HTMLButtonElement | null): boolean {\n if (!button) {\n return false;\n }\n\n if (button.querySelector(':scope > [data-rc-button-label]')) {\n return true;\n }\n\n for (const node of button.childNodes) {\n if (node.nodeType === Node.TEXT_NODE && node.textContent?.trim()) {\n return true;\n }\n\n if (!(node instanceof HTMLElement)) {\n continue;\n }\n\n // data-rc-button-progress marks consumer content that must not count as a label.\n if (\n node.matches(\n '[data-rc-button-icon], [data-rc-button-selected-icon], [data-rc-button-progress], [aria-hidden=\"true\"]',\n )\n ) {\n continue;\n }\n\n if (node.textContent?.trim()) {\n return true;\n }\n }\n\n return false;\n }\n\n protected _syncNativeState(): void {\n const button = this._$button;\n\n if (!button) {\n return;\n }\n\n const shouldDisable = this.disabled || this.pending || this.progress;\n\n if (shouldDisable && !button.disabled) {\n this._disabledOwned = true;\n\n // Idempotent disabled writes queue mutation records and re-enter the button observer.\n button.disabled = true;\n } else if (!shouldDisable && this._disabledOwned) {\n button.disabled = false;\n this._disabledOwned = false;\n }\n\n const busy = this.pending || this.progress;\n\n if (busy) {\n if (!button.hasAttribute('aria-busy')) {\n button.setAttribute('aria-busy', 'true');\n this._ariaBusyOwned = true;\n }\n } else if (this._ariaBusyOwned) {\n button.removeAttribute('aria-busy');\n this._ariaBusyOwned = false;\n }\n }\n\n protected _syncPressedState(): void {\n const button = this._$button;\n\n if (!button) {\n return;\n }\n\n if (this.toggle) {\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 this._restorePressedState();\n }\n }\n\n protected _restorePressedState(): void {\n const button = this._$button;\n\n if (!button || !this._pressedOwned) {\n return;\n }\n\n if (this._authorPressed === null) {\n button.removeAttribute('aria-pressed');\n } else {\n button.setAttribute('aria-pressed', this._authorPressed);\n }\n\n this._pressedOwned = false;\n }\n\n protected _handleToggleActivation(event: MouseEvent): void {\n if (\n !this.toggle ||\n this.disabled ||\n this.pending ||\n this.progress ||\n event.defaultPrevented ||\n !this._isChildButtonEvent(event)\n ) {\n return;\n }\n\n const oldValue = this.selected;\n const nextSelected = !oldValue;\n\n if (this._selected === undefined) {\n this._uncontrolledSelected = nextSelected;\n this._selectedInitialized = true;\n this._syncPressedState();\n this.requestUpdate('selected', oldValue);\n }\n\n this.dispatchEvent(\n new CustomEvent<RCButtonToggleDetail>('rc-button-toggle', {\n bubbles: true,\n composed: true,\n detail: { selected: nextSelected },\n }),\n );\n }\n\n protected _shouldBlockActivation(): boolean {\n return this.pending || this.progress;\n }\n\n protected _isChildButtonEvent(event: Event): boolean {\n return !!this._$button && event.composedPath().includes(this._$button);\n }\n\n protected _blockActivation(event: Event): void {\n if (!this._shouldBlockActivation() || !this._isChildButtonEvent(event)) {\n return;\n }\n\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n\n protected _startRipple(event: PointerEvent): void {\n if (\n !event.isPrimary ||\n event.button !== 0 ||\n this.disabled ||\n this.pending ||\n this.progress ||\n !this._isChildButtonEvent(event) ||\n !this._$stateLayer ||\n getComputedStyle(this).getPropertyValue('--_rc-button-ripple-enabled').trim() !== '1'\n ) {\n return;\n }\n\n const bounds = this._$button!.getBoundingClientRect();\n const x = event.clientX - bounds.left;\n const y = event.clientY - bounds.top;\n const radius = Math.hypot(Math.max(x, bounds.width - x), Math.max(y, bounds.height - y));\n\n this._$stateLayer.style.setProperty('--_rc-button-ripple-x', `${x}px`);\n this._$stateLayer.style.setProperty('--_rc-button-ripple-y', `${y}px`);\n this._$stateLayer.style.setProperty('--_rc-button-ripple-size', `${radius * 2}px`);\n this._$stateLayer.removeAttribute('data-rippling');\n this._$stateLayer.getBoundingClientRect();\n this._$stateLayer.setAttribute('data-rippling', '');\n }\n\n protected _handleRippleAnimationEnd(event: AnimationEvent): void {\n if (event.animationName === 'rc-button-ripple') {\n this._$stateLayer.removeAttribute('data-rippling');\n }\n }\n\n constructor() {\n super();\n\n this.addEventListener('pointerdown', this._startRipple, { capture: true });\n this.addEventListener('click', this._blockActivation, { capture: true });\n this.addEventListener('click', this._handleToggleActivation);\n\n this.addEventListener(\n 'keydown',\n (event) => {\n if (ACTIVATION_KEYS.has(event.key)) {\n this._blockActivation(event);\n }\n },\n { capture: true },\n );\n }\n}\n\nexport default RCButton;\n"],"names":["buttonStyles","css","LIGHT_DOM_CSS","ACTIVATION_KEYS","_RCButton","_a","LitElement","event","root","style","value","oldValue","changed","progressPercentage","html","nextButton","element","button","hasIcon","hasSelectedIcon","hasLabel","node","shouldDisable","pressed","nextSelected","bounds","x","y","radius","__decorateClass","property","query","RCButton"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { R as t } from "./rc-button-Ct5C14lN.js";
2
+ customElements.get("rc-button") || customElements.define("rc-button", t);
3
+ export {
4
+ t as RCButton
5
+ };
6
+ //# sourceMappingURL=rc-button-define.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-button-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCButton } from './index.js';\n\ncustomElements.get('rc-button') || customElements.define('rc-button', RCButton);\n\nexport * from './index.js';\n"],"names":["RCButton"],"mappings":";AAEA,eAAe,IAAI,WAAW,KAAK,eAAe,OAAO,aAAaA,CAAQ;"}
@@ -0,0 +1,5 @@
1
+ import { R as r } from "./rc-button-Ct5C14lN.js";
2
+ export {
3
+ r as RCButton
4
+ };
5
+ //# sourceMappingURL=rc-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-button.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1 @@
1
+ export * from './index.js';
@@ -0,0 +1 @@
1
+ export * from './rc-button.js';
@@ -0,0 +1,143 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ 'rc-button': RCButton;
5
+ }
6
+ interface HTMLElementEventMap {
7
+ 'rc-button-toggle': CustomEvent<RCButtonToggleDetail>;
8
+ }
9
+ }
10
+ /** Detail payload for `rc-button-toggle`. */
11
+ export interface RCButtonToggleDetail {
12
+ /** Requested selected state after user activation. */
13
+ selected: boolean;
14
+ }
15
+ /**
16
+ * Structural button wrapper that preserves a direct native `<button>` child for
17
+ * progressive enhancement, forms, labels, and keyboard behavior.
18
+ *
19
+ * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-button rc-button docs}
20
+ * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/button/ WAI-ARIA button pattern}
21
+ *
22
+ * @slot - A direct native `<button>` child.
23
+ *
24
+ * @fires rc-button-toggle - Fired when a user activates a button with `toggle`.
25
+ *
26
+ * @csspart state-layer - Overlay layer for hover, focus, pressed, ripple, or design-system effects.
27
+ * @csspart progress - Non-interactive progress affordance overlay shown for `pending` or `progress`.
28
+ *
29
+ * @attr disabled - Mirrors disabled state to the native child button.
30
+ * @attr pending - Disables the native button and exposes an indeterminate progress affordance.
31
+ * @attr progress - Disables the native button and exposes a progress affordance.
32
+ * @attr progress-value - Optional determinate progress percentage, clamped from 0 through 100.
33
+ * @attr toggle - Opts the native child into APG toggle-button behavior.
34
+ * @attr selected - Controlled selected state for toggle semantics, styling, and icon switching.
35
+ * @attr default-selected - Initial selected state for uncontrolled toggle usage.
36
+ * @attr icon-only - Removes label-oriented inline padding in supporting themes.
37
+ * @attr full-width - Stretches the native child button to the host inline size.
38
+ * @attr [has-icon] - Present when the native button has a direct `[data-rc-button-icon]` child.
39
+ * Use with CSS selectors (e.g. `rc-button[has-icon]`).
40
+ * @attr [has-selected-icon] - Present when the native button has a direct
41
+ * `[data-rc-button-selected-icon]` child.
42
+ * @attr [has-label] - Present when the native button has visible label content, from either a
43
+ * `[data-rc-button-label]` child or bare text.
44
+ *
45
+ * @cssprop [--rc-button-gap] - Gap between icon and label content.
46
+ * @cssprop [--rc-button-block-size] - Minimum button block size.
47
+ * @cssprop [--rc-button-min-inline-size] - Minimum button inline size.
48
+ * @cssprop [--rc-button-inline-size] - Button inline size.
49
+ * @cssprop [--rc-button-padding-block] - Button block-axis padding (defers to native button
50
+ * padding when unset).
51
+ * @cssprop [--rc-button-padding-inline] - Button inline-axis padding (defers to native button
52
+ * padding when unset).
53
+ * @cssprop [--rc-button-border] - Button border (defers to native button border when unset).
54
+ * @cssprop [--rc-button-radius] - Button and overlay border radius (defers to native button
55
+ * radius when unset).
56
+ * @cssprop [--rc-button-bg] - Button background (defers to native button background when unset).
57
+ * @cssprop [--rc-button-color] - Button text color (defers to native button color when unset).
58
+ * @cssprop [--rc-button-shadow] - Button box shadow (defers to native button shadow when unset).
59
+ * @cssprop [--rc-button-font] - Button font shorthand (defers to native button font when unset).
60
+ * @cssprop [--rc-button-transition] - Button transition shorthand (defers to native button
61
+ * transition when unset).
62
+ * @cssprop [--rc-button-icon-size] - Button inline and min-inline size when `icon-only`. Falls
63
+ * back to `--rc-button-block-size`, then `--rc-control-block-size`, then `2.5rem`.
64
+ * @cssprop [--rc-button-disabled-opacity] - Disabled button opacity (defers to native disabled
65
+ * styling when unset).
66
+ * @cssprop [--rc-button-busy-content-color=transparent] - Button text color while `pending` or
67
+ * `progress`.
68
+ * @cssprop [--rc-button-state-layer-bg=currentColor] - State-layer overlay color.
69
+ * @cssprop [--rc-button-state-layer-duration=150ms] - State-layer opacity transition duration.
70
+ * @cssprop [--rc-button-state-layer-easing=ease] - State-layer opacity transition easing.
71
+ * @cssprop [--rc-button-hover-state-layer-opacity=0] - State-layer opacity on hover.
72
+ * @cssprop [--rc-button-focus-state-layer-opacity=0] - State-layer opacity on focus-within.
73
+ * @cssprop [--rc-button-pressed-state-layer-opacity=0] - State-layer opacity on active press.
74
+ * @cssprop [--rc-button-progress-color=currentColor] - Progress affordance color.
75
+ * @cssprop [--rc-button-progress-font=600 0.75rem / 1 sans-serif] - Determinate progress
76
+ * percentage font.
77
+ * @cssprop [--rc-button-progress-size=1.25rem] - Indeterminate progress spinner diameter.
78
+ * @cssprop [--rc-button-progress-track-width=2px] - Indeterminate progress spinner stroke width.
79
+ * @cssprop [--rc-button-progress-track-color=color-mix(in srgb, currentColor 24%, transparent)] -
80
+ * Indeterminate progress spinner track color.
81
+ * @cssprop [--rc-button-progress-active-color=currentColor] - Indeterminate progress spinner
82
+ * active arc color.
83
+ */
84
+ export declare class RCButton extends LitElement {
85
+ static styles: import('lit').CSSResult;
86
+ protected static readonly _styledRoots: Set<Document | ShadowRoot>;
87
+ protected static _ensureBaseStyles(root: Document | ShadowRoot): void;
88
+ /** Mirror disabled state to the native child. */
89
+ disabled: boolean;
90
+ /** Show an indeterminate progress affordance and disable the native button. */
91
+ pending: boolean;
92
+ /** Show a progress affordance and disable the native button. */
93
+ progress: boolean;
94
+ /** Optional determinate progress percentage, clamped from 0 through 100. */
95
+ progressValue: number | undefined;
96
+ /** Opt the native child into APG toggle-button behavior. */
97
+ toggle: boolean;
98
+ /** Controlled selected state. Host writes are silent. */
99
+ get selected(): boolean;
100
+ set selected(value: boolean | undefined);
101
+ /** Initial selected state for uncontrolled toggle usage. */
102
+ get defaultSelected(): boolean;
103
+ set defaultSelected(value: boolean);
104
+ /** Icon-only layout hint. May also be reflected by child classification. */
105
+ iconOnly: boolean;
106
+ /** Stretch the native child button to the host inline size. */
107
+ fullWidth: boolean;
108
+ protected _$slot: HTMLSlotElement;
109
+ protected _$stateLayer: HTMLElement;
110
+ private _selected;
111
+ private _defaultSelected;
112
+ private _uncontrolledSelected;
113
+ private _selectedInitialized;
114
+ protected _$button: HTMLButtonElement | null;
115
+ protected _buttonObserver: MutationObserver | null;
116
+ protected _disabledOwned: boolean;
117
+ protected _ariaBusyOwned: boolean;
118
+ protected _pressedOwned: boolean;
119
+ protected _authorPressed: string | null;
120
+ protected _iconOnlyOwned: boolean;
121
+ protected _slotMicrotaskQueued: boolean;
122
+ connectedCallback(): void;
123
+ disconnectedCallback(): void;
124
+ protected firstUpdated(): void;
125
+ protected updated(changed: PropertyValues<this>): void;
126
+ protected render(): import('lit').TemplateResult<1>;
127
+ protected get _progressPercentage(): number | undefined;
128
+ protected _handleSlotChange(): void;
129
+ protected _syncSlottedButton(): void;
130
+ protected _classifyButton(): void;
131
+ protected _hasLabel(button: HTMLButtonElement | null): boolean;
132
+ protected _syncNativeState(): void;
133
+ protected _syncPressedState(): void;
134
+ protected _restorePressedState(): void;
135
+ protected _handleToggleActivation(event: MouseEvent): void;
136
+ protected _shouldBlockActivation(): boolean;
137
+ protected _isChildButtonEvent(event: Event): boolean;
138
+ protected _blockActivation(event: Event): void;
139
+ protected _startRipple(event: PointerEvent): void;
140
+ protected _handleRippleAnimationEnd(event: AnimationEvent): void;
141
+ constructor();
142
+ }
143
+ export default RCButton;
@@ -0,0 +1,2 @@
1
+ export declare const buttonStyles: import('lit').CSSResult;
2
+ export default buttonStyles;