@prolibu-suite/cobalt-core 0.9.2 → 0.9.4

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.
Files changed (245) hide show
  1. package/custom-elements.json +375 -25
  2. package/dist/cjs/co-audio-player.cjs.entry.js +107 -18
  3. package/dist/cjs/co-avatar_2.cjs.entry.js +7 -31
  4. package/dist/cjs/co-button.cjs.entry.js +6 -4
  5. package/dist/cjs/co-calendar-month_2.cjs.entry.js +59 -2
  6. package/dist/cjs/co-checkbox.cjs.entry.js +10 -4
  7. package/dist/cjs/co-chip_2.cjs.entry.js +388 -18
  8. package/dist/cjs/co-color-picker.cjs.entry.js +36 -3
  9. package/dist/cjs/co-combobox.cjs.entry.js +44 -4
  10. package/dist/cjs/co-event-popover.cjs.entry.js +5 -2
  11. package/dist/cjs/co-file-field.cjs.entry.js +12 -6
  12. package/dist/cjs/co-icon-button.cjs.entry.js +5 -2
  13. package/dist/cjs/co-icon.cjs.entry.js +17 -1
  14. package/dist/cjs/co-input.cjs.entry.js +21 -1
  15. package/dist/cjs/co-loader.cjs.entry.js +1 -1
  16. package/dist/cjs/co-number-field.cjs.entry.js +22 -2
  17. package/dist/cjs/co-ref-field.cjs.entry.js +87 -13
  18. package/dist/cjs/co-select.cjs.entry.js +273 -8
  19. package/dist/cjs/co-tags-field.cjs.entry.js +1 -1
  20. package/dist/cjs/cobalt.cjs.js +1 -1
  21. package/dist/cjs/color-YhUkm10t.js +32 -0
  22. package/dist/cjs/fieldChip-BLzo9MEV.js +7 -0
  23. package/dist/cjs/index-DK-2Lzmf.js +4 -4
  24. package/dist/cjs/loader.cjs.js +1 -1
  25. package/dist/cobalt/cobalt.esm.js +1 -1
  26. package/dist/cobalt/p-0c463d9a.entry.js +1 -0
  27. package/dist/cobalt/p-0caa059c.entry.js +1 -0
  28. package/dist/cobalt/{p-3ced4269.entry.js → p-2828ecf6.entry.js} +1 -1
  29. package/dist/cobalt/p-2f88d151.entry.js +1 -0
  30. package/dist/cobalt/p-409f28bb.entry.js +1 -0
  31. package/dist/cobalt/{p-18af9e44.entry.js → p-568cfe8d.entry.js} +1 -1
  32. package/dist/cobalt/p-6bf814f9.entry.js +1 -0
  33. package/dist/cobalt/p-7ea87b75.entry.js +1 -0
  34. package/dist/cobalt/p-8b4b3589.entry.js +1 -0
  35. package/dist/cobalt/p-93c68029.entry.js +1 -0
  36. package/dist/cobalt/p-BG4WRR22.js +1 -0
  37. package/dist/cobalt/p-a2d31248.entry.js +1 -0
  38. package/dist/cobalt/p-bcedbd73.entry.js +1 -0
  39. package/dist/cobalt/p-dfd25f1d.entry.js +1 -0
  40. package/dist/cobalt/p-e364b8a5.entry.js +1 -0
  41. package/dist/cobalt/p-f00be11f.entry.js +1 -0
  42. package/dist/cobalt/p-f25967fb.entry.js +1 -0
  43. package/dist/cobalt/p-f5f1b463.entry.js +1 -0
  44. package/dist/cobalt/p-fef5db54.entry.js +1 -0
  45. package/dist/cobalt/p-mAGnZXRn.js +1 -0
  46. package/dist/collection/components/co-audio-player/co-audio-player.js +81 -17
  47. package/dist/collection/components/co-audio-player/co-audio-player.utils.js +27 -2
  48. package/dist/collection/components/co-autocomplete/co-autocomplete.js +1 -1
  49. package/dist/collection/components/co-avatar/co-avatar.js +5 -1
  50. package/dist/collection/components/co-avatar-group/co-avatar-group.js +1 -1
  51. package/dist/collection/components/co-button/co-button.css +7 -0
  52. package/dist/collection/components/co-button/co-button.js +7 -5
  53. package/dist/collection/components/co-calendar-month/co-calendar-month.js +59 -2
  54. package/dist/collection/components/co-checkbox/co-checkbox.css +22 -0
  55. package/dist/collection/components/co-checkbox/co-checkbox.js +9 -3
  56. package/dist/collection/components/co-checkbox-group/co-checkbox-group.js +1 -1
  57. package/dist/collection/components/co-color-picker/co-color-picker.css +7 -0
  58. package/dist/collection/components/co-color-picker/co-color-picker.js +35 -2
  59. package/dist/collection/components/co-combobox/co-combobox.css +7 -0
  60. package/dist/collection/components/co-combobox/co-combobox.js +44 -4
  61. package/dist/collection/components/co-command-search/co-command-search.js +1 -1
  62. package/dist/collection/components/co-data-table/co-data-table.js +1 -1
  63. package/dist/collection/components/co-date-range-picker/co-date-range-picker.js +2 -2
  64. package/dist/collection/components/co-event-popover/co-event-popover.js +5 -2
  65. package/dist/collection/components/co-file-field/co-file-field.css +7 -4
  66. package/dist/collection/components/co-file-field/co-file-field.js +8 -5
  67. package/dist/collection/components/co-icon/iconLoader.js +17 -1
  68. package/dist/collection/components/co-icon-button/co-icon-button.css +7 -0
  69. package/dist/collection/components/co-icon-button/co-icon-button.js +6 -3
  70. package/dist/collection/components/co-input/co-input.css +13 -0
  71. package/dist/collection/components/co-input/co-input.js +21 -0
  72. package/dist/collection/components/co-loader/co-loader.css +5 -3
  73. package/dist/collection/components/co-number-field/co-number-field.js +23 -2
  74. package/dist/collection/components/co-option-list/co-option-list.css +45 -2
  75. package/dist/collection/components/co-option-list/co-option-list.js +468 -18
  76. package/dist/collection/components/co-option-list/optionListLogic.js +25 -0
  77. package/dist/collection/components/co-popover/co-popover.js +1 -1
  78. package/dist/collection/components/co-radio-group/co-radio-group.js +1 -1
  79. package/dist/collection/components/co-ref-field/co-ref-field.css +49 -0
  80. package/dist/collection/components/co-ref-field/co-ref-field.js +240 -12
  81. package/dist/collection/components/co-segmented-bar/co-segmented-bar.js +1 -1
  82. package/dist/collection/components/co-select/co-select.css +19 -0
  83. package/dist/collection/components/co-select/co-select.js +275 -9
  84. package/dist/collection/components/co-sidebar-nav/co-sidebar-nav.js +1 -1
  85. package/dist/collection/components/co-toast/co-toast.js +2 -2
  86. package/dist/collection/components/co-transfer-list/co-transfer-list.js +1 -1
  87. package/dist/collection/utils/fieldChip.js +1 -1
  88. package/dist/collection/utils/fileI18n.js +3 -0
  89. package/dist/components/co-accordion.js +1 -1
  90. package/dist/components/co-action-bar.js +1 -1
  91. package/dist/components/co-audio-player.js +1 -1
  92. package/dist/components/co-autocomplete.js +1 -1
  93. package/dist/components/co-avatar-group.js +1 -1
  94. package/dist/components/co-avatar.js +1 -1
  95. package/dist/components/co-breadcrumb-item.js +1 -1
  96. package/dist/components/co-breadcrumb.js +1 -1
  97. package/dist/components/co-button.js +1 -1
  98. package/dist/components/co-calendar-month.js +1 -1
  99. package/dist/components/co-calendar-timegrid.js +1 -1
  100. package/dist/components/co-calendar.js +1 -1
  101. package/dist/components/co-carousel.js +1 -1
  102. package/dist/components/co-checkbox-group.js +1 -1
  103. package/dist/components/co-checkbox.js +1 -1
  104. package/dist/components/co-chip.js +1 -1
  105. package/dist/components/co-color-picker.js +1 -1
  106. package/dist/components/co-column-picker.js +1 -1
  107. package/dist/components/co-combobox.js +1 -1
  108. package/dist/components/co-command-search.js +1 -1
  109. package/dist/components/co-data-table-pagination.js +1 -1
  110. package/dist/components/co-data-table.js +1 -1
  111. package/dist/components/co-date-field.js +1 -1
  112. package/dist/components/co-date-picker.js +1 -1
  113. package/dist/components/co-date-range-picker.js +1 -1
  114. package/dist/components/co-date-range.js +1 -1
  115. package/dist/components/co-date-time-picker.js +1 -1
  116. package/dist/components/co-drawer.js +1 -1
  117. package/dist/components/co-drive-card.js +1 -1
  118. package/dist/components/co-drop-zone.js +1 -1
  119. package/dist/components/co-emoji-picker.js +1 -1
  120. package/dist/components/co-empty-state.js +1 -1
  121. package/dist/components/co-event-calendar.js +1 -1
  122. package/dist/components/co-event-popover.js +1 -1
  123. package/dist/components/co-fab.js +1 -1
  124. package/dist/components/co-file-field.js +1 -1
  125. package/dist/components/co-file-type-tile.js +1 -1
  126. package/dist/components/co-helper-text.js +1 -1
  127. package/dist/components/co-icon-button.js +1 -1
  128. package/dist/components/co-icon.js +1 -1
  129. package/dist/components/co-input.js +1 -1
  130. package/dist/components/co-json-field.js +1 -1
  131. package/dist/components/co-lightbox.js +1 -1
  132. package/dist/components/co-list-footer.js +1 -1
  133. package/dist/components/co-list-item.js +1 -1
  134. package/dist/components/co-loader.js +1 -1
  135. package/dist/components/co-menu-item.js +1 -1
  136. package/dist/components/co-modal.js +1 -1
  137. package/dist/components/co-number-field.js +1 -1
  138. package/dist/components/co-option-list.js +1 -1
  139. package/dist/components/co-page-header.js +1 -1
  140. package/dist/components/co-phone-field.js +1 -1
  141. package/dist/components/co-radio-group.js +1 -1
  142. package/dist/components/co-rating.js +1 -1
  143. package/dist/components/co-ref-field.js +1 -1
  144. package/dist/components/co-rich-text-editor.js +1 -1
  145. package/dist/components/co-rich-text-toolbar.js +1 -1
  146. package/dist/components/co-select.js +1 -1
  147. package/dist/components/co-sidebar-nav.js +1 -1
  148. package/dist/components/co-slider.js +1 -1
  149. package/dist/components/co-switch.js +1 -1
  150. package/dist/components/co-tab.js +1 -1
  151. package/dist/components/co-tags-field.js +1 -1
  152. package/dist/components/co-textarea.js +1 -1
  153. package/dist/components/co-toast.js +1 -1
  154. package/dist/components/co-toggle-button.js +1 -1
  155. package/dist/components/co-transfer-list.js +1 -1
  156. package/dist/components/co-video.js +1 -1
  157. package/dist/components/{p-CklsvHeL.js → p-B0Dc-I_C.js} +1 -1
  158. package/dist/components/{p-DzoNGEDU.js → p-BH184F0X.js} +1 -1
  159. package/dist/components/{p-BGD3oQ73.js → p-BHYtxTzM.js} +1 -1
  160. package/dist/components/{p-mom5kiBa.js → p-BTQEg3UO.js} +1 -1
  161. package/dist/components/p-BZIB4JDs.js +1 -0
  162. package/dist/components/p-Bbny3WUc.js +1 -0
  163. package/dist/components/{p-D5QJpmqf.js → p-Bxk96Zgc.js} +1 -1
  164. package/dist/components/p-C1Kv3zYZ.js +1 -0
  165. package/dist/components/p-C4U2tbRp.js +1 -0
  166. package/dist/components/{p-CyMaOb1j.js → p-CA_JAK9s.js} +1 -1
  167. package/dist/components/{p-AvSaw4Ua.js → p-CR0izsJC.js} +1 -1
  168. package/dist/components/p-CuZXTvDM.js +1 -0
  169. package/dist/components/{p-_131DL6m.js → p-D4qzGifz.js} +1 -1
  170. package/dist/components/{p-BsQQ7Mki.js → p-D5EdMieb.js} +1 -1
  171. package/dist/components/p-Dabi98BI.js +1 -0
  172. package/dist/components/p-DbipMAyT.js +1 -0
  173. package/dist/components/p-DgUBcJIS.js +1 -0
  174. package/dist/components/p-Dj1EZ5qD.js +1 -0
  175. package/dist/components/{p-DkmKOF60.js → p-P8wvwhM2.js} +1 -1
  176. package/dist/components/{p-nwy6X1QT.js → p-hfGFsvaD.js} +1 -1
  177. package/dist/esm/co-audio-player.entry.js +107 -18
  178. package/dist/esm/co-avatar_2.entry.js +6 -30
  179. package/dist/esm/co-button.entry.js +6 -4
  180. package/dist/esm/co-calendar-month_2.entry.js +59 -2
  181. package/dist/esm/co-checkbox.entry.js +10 -4
  182. package/dist/esm/co-chip_2.entry.js +388 -18
  183. package/dist/esm/co-color-picker.entry.js +36 -3
  184. package/dist/esm/co-combobox.entry.js +44 -4
  185. package/dist/esm/co-event-popover.entry.js +5 -2
  186. package/dist/esm/co-file-field.entry.js +12 -6
  187. package/dist/esm/co-icon-button.entry.js +5 -2
  188. package/dist/esm/co-icon.entry.js +17 -1
  189. package/dist/esm/co-input.entry.js +21 -1
  190. package/dist/esm/co-loader.entry.js +1 -1
  191. package/dist/esm/co-number-field.entry.js +22 -2
  192. package/dist/esm/co-ref-field.entry.js +87 -13
  193. package/dist/esm/co-select.entry.js +273 -8
  194. package/dist/esm/co-tags-field.entry.js +1 -1
  195. package/dist/esm/cobalt.js +1 -1
  196. package/dist/esm/color-BG4WRR22.js +30 -0
  197. package/dist/esm/fieldChip-DsAfq1e0.js +5 -0
  198. package/dist/esm/index-CrtiywTB.js +4 -4
  199. package/dist/esm/loader.js +1 -1
  200. package/dist/types/components/co-audio-player/co-audio-player.d.ts +13 -0
  201. package/dist/types/components/co-audio-player/co-audio-player.utils.d.ts +18 -1
  202. package/dist/types/components/co-button/co-button.d.ts +3 -1
  203. package/dist/types/components/co-calendar-month/co-calendar-month.d.ts +7 -0
  204. package/dist/types/components/co-checkbox/co-checkbox.d.ts +1 -0
  205. package/dist/types/components/co-color-picker/co-color-picker.d.ts +15 -0
  206. package/dist/types/components/co-combobox/co-combobox.d.ts +17 -0
  207. package/dist/types/components/co-icon-button/co-icon-button.d.ts +3 -0
  208. package/dist/types/components/co-input/co-input.d.ts +9 -0
  209. package/dist/types/components/co-number-field/co-number-field.d.ts +9 -0
  210. package/dist/types/components/co-option-list/co-option-list.d.ts +79 -0
  211. package/dist/types/components/co-option-list/optionListLogic.d.ts +23 -1
  212. package/dist/types/components/co-ref-field/co-ref-field.d.ts +46 -0
  213. package/dist/types/components/co-select/co-select.d.ts +67 -0
  214. package/dist/types/components.d.ts +110 -4
  215. package/dist/types/utils/fieldChip.d.ts +5 -0
  216. package/dist/types/utils/fileI18n.d.ts +1 -0
  217. package/package.json +4 -4
  218. package/dist/cjs/fieldChip-xNJPEFcS.js +0 -7
  219. package/dist/cobalt/p-02ac492f.entry.js +0 -1
  220. package/dist/cobalt/p-0ccb672b.entry.js +0 -1
  221. package/dist/cobalt/p-2d81b292.entry.js +0 -1
  222. package/dist/cobalt/p-4a503187.entry.js +0 -1
  223. package/dist/cobalt/p-55566b37.entry.js +0 -1
  224. package/dist/cobalt/p-7457aa89.entry.js +0 -1
  225. package/dist/cobalt/p-77719335.entry.js +0 -1
  226. package/dist/cobalt/p-8f600512.entry.js +0 -1
  227. package/dist/cobalt/p-CQAYgqA6.js +0 -1
  228. package/dist/cobalt/p-a02db338.entry.js +0 -1
  229. package/dist/cobalt/p-a51d8775.entry.js +0 -1
  230. package/dist/cobalt/p-a9096b5c.entry.js +0 -1
  231. package/dist/cobalt/p-aafb9d11.entry.js +0 -1
  232. package/dist/cobalt/p-b28dc0fe.entry.js +0 -1
  233. package/dist/cobalt/p-c6b9b9d6.entry.js +0 -1
  234. package/dist/cobalt/p-d4debd6f.entry.js +0 -1
  235. package/dist/cobalt/p-d629fb4e.entry.js +0 -1
  236. package/dist/components/p-B3TkpLNh.js +0 -1
  237. package/dist/components/p-B7hvddnu.js +0 -1
  238. package/dist/components/p-BT5tSgZa.js +0 -1
  239. package/dist/components/p-CXLX8DpD.js +0 -1
  240. package/dist/components/p-DTvb412h.js +0 -1
  241. package/dist/components/p-DvhR3H61.js +0 -1
  242. package/dist/components/p-KWTokD0C.js +0 -1
  243. package/dist/components/p-Q6caHt79.js +0 -1
  244. package/dist/components/p-WWlZiln1.js +0 -1
  245. package/dist/esm/fieldChip-BZDUy9Z-.js +0 -5
@@ -1,12 +1,37 @@
1
1
  import { r as registerInstance, c as createEvent, h } from './index-CrtiywTB.js';
2
2
 
3
- /** Seconds → "m:ss" (floors; 0 for NaN/negative). */
3
+ /** Rendered in place of `m:ss` while a time is not known.
4
+ *
5
+ * Not an error state: `<audio>.duration` is `Infinity` for any container whose
6
+ * header carries no duration — every blob `MediaRecorder` produces, i.e. every
7
+ * freshly recorded voice note — and Chrome keeps it that way until the clip has
8
+ * been played end to end. `0:00` there would read as a zero-length recording;
9
+ * `--:--` reads as "not known yet", which is the truth. */
10
+ const UNKNOWN_TIME = '--:--';
11
+ /** Seconds → "m:ss" (floors). Anything that is not a finite, non-negative number
12
+ * (`Infinity`, `NaN`, negatives) → `UNKNOWN_TIME` — never `"Infinity:NaN"`. */
4
13
  function formatTime(seconds) {
5
- const s = Math.max(0, Math.floor(seconds || 0));
14
+ if (!Number.isFinite(seconds) || seconds < 0)
15
+ return UNKNOWN_TIME;
16
+ const s = Math.floor(seconds);
6
17
  const m = Math.floor(s / 60);
7
18
  const sec = s % 60;
8
19
  return `${m}:${sec.toString().padStart(2, '0')}`;
9
20
  }
21
+ /** Picks the duration to trust (seconds), or `NaN` when neither source knows it.
22
+ *
23
+ * `<audio>.duration` is authoritative *when it is a real number*. It is not for
24
+ * a duration-less container (see `UNKNOWN_TIME`), where it reports `Infinity`.
25
+ * The WebAudio decode the player already runs to draw the waveform does know the
26
+ * real length (`AudioBuffer.duration`), so it is the fallback. `0` from either
27
+ * source means "empty/unknown" too, so it never wins. */
28
+ function resolveDuration(fromAudio, fromDecode) {
29
+ if (Number.isFinite(fromAudio) && fromAudio > 0)
30
+ return fromAudio;
31
+ if (Number.isFinite(fromDecode) && fromDecode > 0)
32
+ return fromDecode;
33
+ return NaN;
34
+ }
10
35
  /** Downsample raw PCM to `bars` peak heights, each normalized to a 0..1 fraction. */
11
36
  function resamplePeaks(channelData, bars) {
12
37
  const len = channelData.length;
@@ -73,7 +98,10 @@ const CoAudioPlayer = class {
73
98
  this.isLoading = false;
74
99
  this.hasError = false;
75
100
  this.currentTime = 0;
76
- this.duration = 0;
101
+ /** Playback length in seconds, or `NaN` while it is not known — which is the
102
+ * normal state for a `MediaRecorder` blob until the decode lands. Everything
103
+ * that does arithmetic with it goes through `knownDuration`. */
104
+ this.duration = NaN;
77
105
  this.peaks = [];
78
106
  /** Measured wave width (px); 0 until the ResizeObserver reports it. */
79
107
  this.containerWidth = 0;
@@ -81,7 +109,13 @@ const CoAudioPlayer = class {
81
109
  this.playbackRate = 1;
82
110
  // Decoded mono PCM, kept so bars can be re-resampled on resize without re-fetching.
83
111
  this.rawChannelData = null;
84
- this.onMeta = () => { var _a; this.duration = ((_a = this.audio) === null || _a === void 0 ? void 0 : _a.duration) || 0; };
112
+ // Length reported by the WebAudio decode; NaN when nothing has decoded (yet).
113
+ // It is the only trustworthy duration for a container without a duration header.
114
+ this.decodedDuration = NaN;
115
+ // Bumped by every init(); an in-flight extractPeaks whose token no longer matches
116
+ // belongs to a superseded `src` and must not write peaks/duration.
117
+ this.loadToken = 0;
118
+ this.onMeta = () => { this.syncDuration(); };
85
119
  this.onCanPlay = () => { this.isLoading = false; };
86
120
  this.onWaiting = () => { this.isLoading = true; };
87
121
  this.onTime = () => { var _a; this.currentTime = ((_a = this.audio) === null || _a === void 0 ? void 0 : _a.currentTime) || 0; };
@@ -108,11 +142,15 @@ const CoAudioPlayer = class {
108
142
  if (this.audio)
109
143
  this.audio.playbackRate = this.playbackRate;
110
144
  };
145
+ // Scrubbing needs a real total to map the click fraction onto: with an unknown
146
+ // duration `frac * duration` is Infinity (or NaN at frac 0), and assigning that
147
+ // to `currentTime` throws. No total → no scrub.
111
148
  this.seekAt = (clientX) => {
112
- if (!this.audio || !this.waveEl || !this.duration)
149
+ const total = this.knownDuration;
150
+ if (!this.audio || !this.waveEl || !total)
113
151
  return;
114
152
  const frac = scrubFraction(clientX, this.waveEl.getBoundingClientRect());
115
- this.audio.currentTime = frac * this.duration;
153
+ this.audio.currentTime = frac * total;
116
154
  this.currentTime = this.audio.currentTime;
117
155
  };
118
156
  this.onWaveKey = (e) => {
@@ -121,17 +159,29 @@ const CoAudioPlayer = class {
121
159
  this.toggle();
122
160
  return;
123
161
  }
124
- if (!this.audio || !this.duration)
162
+ if (!this.audio)
125
163
  return;
164
+ // Relative nudges stay available even with an unknown duration (the media
165
+ // element clamps a forward seek to its own seekable end); only the upper
166
+ // clamp needs a total, and both operands stay finite either way.
167
+ const total = this.knownDuration;
168
+ const at = this.audio.currentTime;
126
169
  if (e.key === 'ArrowRight')
127
- this.audio.currentTime = Math.min(this.duration, this.audio.currentTime + 5);
170
+ this.audio.currentTime = total ? Math.min(total, at + 5) : at + 5;
128
171
  else if (e.key === 'ArrowLeft')
129
- this.audio.currentTime = Math.max(0, this.audio.currentTime - 5);
172
+ this.audio.currentTime = Math.max(0, at - 5);
130
173
  else
131
174
  return;
132
175
  this.currentTime = this.audio.currentTime;
133
176
  };
134
177
  }
178
+ /** Duration usable for arithmetic (seek target, progress %, ARIA): `0` when it
179
+ * is not known, so every caller can bail on a plain falsy check instead of
180
+ * letting `Infinity`/`NaN` reach `audio.currentTime` — that setter takes a
181
+ * restricted `double` and THROWS a TypeError on a non-finite value. */
182
+ get knownDuration() {
183
+ return Number.isFinite(this.duration) && this.duration > 0 ? this.duration : 0;
184
+ }
135
185
  /** Bar count: derived from the measured width (V1-style density) once known,
136
186
  * else the `bars` fallback. Floored at 24 so a narrow player still reads as a wave. */
137
187
  get effectiveBars() {
@@ -169,6 +219,7 @@ const CoAudioPlayer = class {
169
219
  }
170
220
  disconnectedCallback() {
171
221
  var _a;
222
+ this.loadToken++; // orphan any in-flight decode so it can't write to a dead instance
172
223
  this.teardown();
173
224
  (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
174
225
  this.resizeObserver = undefined;
@@ -183,16 +234,18 @@ const CoAudioPlayer = class {
183
234
  }
184
235
  init() {
185
236
  this.teardown();
237
+ const token = ++this.loadToken;
186
238
  this.rawChannelData = null;
239
+ this.decodedDuration = NaN;
187
240
  this.peaks = fallbackPeaks(this.effectiveBars); // draw immediately; refine with real peaks
188
241
  this.currentTime = 0;
189
- this.duration = 0;
242
+ this.duration = NaN; // unknown until `loadedmetadata` or the decode says otherwise
190
243
  this.playbackRate = 1; // a fresh source starts at 1x (new <audio> defaults to 1)
191
244
  this.hasError = false;
192
245
  if (!this.src)
193
246
  return;
194
247
  this.isLoading = true;
195
- this.extractPeaks(this.src);
248
+ this.extractPeaks(this.src, token);
196
249
  if (typeof Audio === 'undefined')
197
250
  return; // test/SSR guard
198
251
  const el = new Audio();
@@ -221,22 +274,52 @@ const CoAudioPlayer = class {
221
274
  }
222
275
  this.isPlaying = false;
223
276
  }
224
- async extractPeaks(url) {
277
+ async extractPeaks(url, token) {
278
+ let ctx;
225
279
  try {
226
280
  const Ctx = window.AudioContext || window.webkitAudioContext;
227
281
  if (!Ctx || typeof fetch === 'undefined')
228
282
  return; // keep fallback
229
- const ctx = new Ctx();
283
+ ctx = new Ctx();
230
284
  const buf = await (await fetch(url)).arrayBuffer();
231
285
  const audioBuf = await ctx.decodeAudioData(buf);
286
+ if (token !== this.loadToken)
287
+ return; // a newer src superseded this decode
232
288
  this.rawChannelData = audioBuf.getChannelData(0);
289
+ this.decodedDuration = audioBuf.duration;
233
290
  this.peaks = resamplePeaks(this.rawChannelData, this.effectiveBars);
234
- ctx.close();
235
291
  }
236
292
  catch (_a) {
293
+ if (token !== this.loadToken)
294
+ return;
295
+ // Undecodable (codec WebAudio can't handle, CORS, network): keep the
296
+ // deterministic fallback wave and let <audio> own the duration — playback,
297
+ // seek and the time readout all still work, or degrade to `--:--`.
237
298
  this.rawChannelData = null;
299
+ this.decodedDuration = NaN;
238
300
  this.peaks = fallbackPeaks(this.effectiveBars); // stays functional
239
301
  }
302
+ finally {
303
+ // Always release the context. Chrome caps concurrent AudioContexts per
304
+ // document, so leaking one per failed decode would eventually stop every
305
+ // later player on the page from decoding at all.
306
+ try {
307
+ await (ctx === null || ctx === void 0 ? void 0 : ctx.close());
308
+ }
309
+ catch ( /* already closed */_b) { /* already closed */ }
310
+ }
311
+ if (token === this.loadToken)
312
+ this.syncDuration();
313
+ }
314
+ /** Re-derive the shown duration from whichever source knows it. Called from both
315
+ * `loadedmetadata` and the end of the decode, because either can land first. */
316
+ syncDuration() {
317
+ var _a, _b;
318
+ const next = resolveDuration((_b = (_a = this.audio) === null || _a === void 0 ? void 0 : _a.duration) !== null && _b !== void 0 ? _b : NaN, this.decodedDuration);
319
+ // Object.is, not !==: Stencil's @State setter re-renders on any `oldVal !== newVal`,
320
+ // and NaN !== NaN — so a plain assignment would re-render on every no-op sync.
321
+ if (!Object.is(next, this.duration))
322
+ this.duration = next;
240
323
  }
241
324
  async download() {
242
325
  if (!this.src || typeof fetch === 'undefined')
@@ -257,14 +340,20 @@ const CoAudioPlayer = class {
257
340
  render() {
258
341
  const H = 40, UNIT = 3, W = 1.8, R = 0.6;
259
342
  const vbW = Math.max(1, this.peaks.length * UNIT);
260
- const pct = this.duration ? (this.currentTime / this.duration) * 100 : 0;
261
- const bar = (hFrac, i, played = false) => (h("rect", { key: 'ffe5ce97626e52c12e60b953b62d237f14acb582', x: i * UNIT, y: H / 2 - (hFrac * H) / 2, width: W, height: Math.max(hFrac * H, 2), rx: R, class: { 'co-audio-player__bar': true, 'co-audio-player__bar--played': played } }));
262
- return (h("div", { key: '012710aded6ca183e80d7fde087cb0fdf413249b', class: {
343
+ const total = this.knownDuration; // 0 while unknown → no progress fill, no ARIA max
344
+ const pct = total ? (this.currentTime / total) * 100 : 0;
345
+ // Undefined drops the attribute (Stencil removes null/undefined attrs). An
346
+ // `aria-valuemax="Infinity"`/`"NaN"` is invalid, and a stand-in `"0"` would sit
347
+ // below `aria-valuenow` the moment playback advances. ARIA 1.2 makes valuemax
348
+ // optional for `slider`, so leaving it off while unknown is well-formed.
349
+ const ariaMax = total ? Math.floor(total) : undefined;
350
+ const bar = (hFrac, i, played = false) => (h("rect", { key: '997dcefc32f5188c41afa0a7b5135c70cceeed1d', x: i * UNIT, y: H / 2 - (hFrac * H) / 2, width: W, height: Math.max(hFrac * H, 2), rx: R, class: { 'co-audio-player__bar': true, 'co-audio-player__bar--played': played } }));
351
+ return (h("div", { key: '8ac91ab3f8eb417df5e7cf4d1e016d6ca7eb45a3', class: {
263
352
  'co-audio-player': true,
264
353
  'co-audio-player--compact': this.compact,
265
354
  'co-audio-player--error': this.hasError,
266
355
  'co-audio-player--playing': this.isPlaying,
267
- }, part: "player" }, h("button", { key: '2505b88e97e73fd39aa31e3dad5e7fe0c1b94c80', type: "button", class: "co-audio-player__play", part: "play", "aria-label": this.hasError ? 'Audio no disponible' : this.isPlaying ? 'Pausar' : 'Reproducir', "aria-busy": this.isLoading ? 'true' : 'false', disabled: this.hasError || !this.src, onClick: this.toggle }, h("co-icon", { key: 'e0e0d2dd5f6e0578ba80a3c235e5c221a6e8fe21', name: this.hasError ? 'warning-circle' : this.isPlaying ? 'pause' : 'play', weight: "fill", size: this.compact ? 12 : 14 })), h("div", { key: 'd2b32119c69c64d2f68d469fe4ae056780446322', class: "co-audio-player__wave", part: "wave", role: "slider", tabindex: "0", "aria-label": "Progreso de reproducci\u00F3n", "aria-valuemin": 0, "aria-valuemax": Math.floor(this.duration), "aria-valuenow": Math.floor(this.currentTime), ref: (el) => (this.waveEl = el), onClick: (e) => this.seekAt(e.clientX), onKeyDown: this.onWaveKey }, h("svg", { key: 'fb9643df152d2d0b119580954f639cb3a9c2cd66', class: "co-audio-player__svg", viewBox: `0 0 ${vbW} ${H}`, preserveAspectRatio: "none", "aria-hidden": "true" }, this.peaks.map((hFrac, i) => bar(hFrac, i)), h("clipPath", { key: 'c2901cfe7c7e910bd53c8c92894b2d2395cde270', id: "co-ap-clip" }, h("rect", { key: '8129a85201e09ba6646b08ed0075798b0a0b0dfc', x: "0", y: "0", width: (pct / 100) * vbW, height: H })), h("g", { key: '69bc1780122d48f1a545d1c59bf7ed6536285ed2', "clip-path": "url(#co-ap-clip)" }, this.peaks.map((hFrac, i) => bar(hFrac, i, true))))), h("span", { key: '3747622619bd81545f85e7eb2f9c19b1aca6e7c2', class: "co-audio-player__time", part: "time" }, formatTime(this.currentTime), " / ", formatTime(this.duration)), !this.compact && (h("button", { key: '84341856fb2e0b6a094c673a727370b148190e30', type: "button", class: "co-audio-player__speed", part: "speed", "aria-label": `Velocidad de reproducción ${this.playbackRate}x`, onClick: this.cycleSpeed }, this.playbackRate, "x")), !this.compact && !this.noDownload && (h("button", { key: 'd6767d185317f20299b40c4050a806d88165682f', type: "button", class: "co-audio-player__dl", part: "download", "aria-label": "Descargar", onClick: () => this.download() }, h("co-icon", { key: 'a0f0a09cdf705ecf15e0156cf93011f89f41ffa5', name: "download-simple", size: 14 })))));
356
+ }, part: "player" }, h("button", { key: '0e5897dc64c91ee67432f17d7b0d57a27f44cd0e', type: "button", class: "co-audio-player__play", part: "play", "aria-label": this.hasError ? 'Audio no disponible' : this.isPlaying ? 'Pausar' : 'Reproducir', "aria-busy": this.isLoading ? 'true' : 'false', disabled: this.hasError || !this.src, onClick: this.toggle }, h("co-icon", { key: '4843751a2a3709942a49ae03ff9ba0eb08ab7d97', name: this.hasError ? 'warning-circle' : this.isPlaying ? 'pause' : 'play', weight: "fill", size: this.compact ? 12 : 14 })), h("div", { key: 'b7aebd0e0c5197b0dec6257bbec7c9dd8dd55d6f', class: "co-audio-player__wave", part: "wave", role: "slider", tabindex: "0", "aria-label": "Progreso de reproducci\u00F3n", "aria-valuemin": 0, "aria-valuemax": ariaMax, "aria-valuenow": Math.floor(this.currentTime), ref: (el) => (this.waveEl = el), onClick: (e) => this.seekAt(e.clientX), onKeyDown: this.onWaveKey }, h("svg", { key: 'a504d058a27bb33dd57733ec32db306eb0ed87e9', class: "co-audio-player__svg", viewBox: `0 0 ${vbW} ${H}`, preserveAspectRatio: "none", "aria-hidden": "true" }, this.peaks.map((hFrac, i) => bar(hFrac, i)), h("clipPath", { key: '9cfa69ba28801893baf62c8f66b18a31319fdebe', id: "co-ap-clip" }, h("rect", { key: '6e5cb34baeb2b7dddd6ef7e94f8585ef912e0315', x: "0", y: "0", width: (pct / 100) * vbW, height: H })), h("g", { key: '4b78a29dde762cabc85d7921aacbcd261d8fa6b5', "clip-path": "url(#co-ap-clip)" }, this.peaks.map((hFrac, i) => bar(hFrac, i, true))))), h("span", { key: '9067d22b0e2994e46ef49c60356292ec59f61a21', class: "co-audio-player__time", part: "time" }, formatTime(this.currentTime), " / ", formatTime(this.duration)), !this.compact && (h("button", { key: 'f6149a9996e6ce15230221c2f6fcec95fec5f485', type: "button", class: "co-audio-player__speed", part: "speed", "aria-label": `Velocidad de reproducción ${this.playbackRate}x`, onClick: this.cycleSpeed }, this.playbackRate, "x")), !this.compact && !this.noDownload && (h("button", { key: '73d291d31d92bcb0e18e230fe0ac35d3ab4077b2', type: "button", class: "co-audio-player__dl", part: "download", "aria-label": "Descargar", onClick: () => this.download() }, h("co-icon", { key: '9ab09f5d6b975f4f5544019f70bd2ca1ee521068', name: "download-simple", size: 14 })))));
268
357
  }
269
358
  static get watchers() { return {
270
359
  "src": [{
@@ -1,35 +1,7 @@
1
1
  import { r as registerInstance, h, a as getElement } from './index-CrtiywTB.js';
2
+ import { i as isLightColor } from './color-BG4WRR22.js';
2
3
  import { c as computePosition, g as getOffsetAncestor, f as findNearestScrollParent } from './positioning-BMdapAL8.js';
3
4
 
4
- /**
5
- * Shared color utilities for Cobalt components.
6
- * WCAG sRGB relative luminance for contrast detection.
7
- */
8
- function parseHex(hex) {
9
- if (!hex || typeof hex !== 'string')
10
- return null;
11
- const h = hex.replace('#', '');
12
- if (h.length === 3) {
13
- return { r: parseInt(h[0] + h[0], 16), g: parseInt(h[1] + h[1], 16), b: parseInt(h[2] + h[2], 16) };
14
- }
15
- if (h.length === 6) {
16
- return { r: parseInt(h.slice(0, 2), 16), g: parseInt(h.slice(2, 4), 16), b: parseInt(h.slice(4, 6), 16) };
17
- }
18
- return null;
19
- }
20
- /** WCAG sRGB relative luminance (0–1). */
21
- function luminance(hex) {
22
- const c = parseHex(hex);
23
- if (!c)
24
- return 0;
25
- const [rs, gs, bs] = [c.r / 255, c.g / 255, c.b / 255].map((v) => v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4));
26
- return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
27
- }
28
- /** Returns true when the color is perceptually light (needs dark foreground). */
29
- function isLightColor(hex) {
30
- return luminance(hex) > 0.4;
31
- }
32
-
33
5
  const coAvatarCss = () => `:host{display:inline-flex;--co-avatar-squircle:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'><path d='M100 50L99.94 68.06L99.75 73.81L99.44 77.94L99.01 81.26L98.44 84.05L97.74 86.46L96.91 88.57L95.94 90.43L94.81 92.07L93.53 93.53L92.07 94.81L90.43 95.94L88.57 96.91L86.46 97.74L84.05 98.44L81.26 99.01L77.94 99.44L73.81 99.75L68.06 99.94L50 100L31.94 99.94L26.19 99.75L22.06 99.44L18.74 99.01L15.95 98.44L13.54 97.74L11.43 96.91L9.57 95.94L7.93 94.81L6.47 93.53L5.19 92.07L4.06 90.43L3.09 88.57L2.26 86.46L1.56 84.05L0.99 81.26L0.56 77.94L0.25 73.81L0.06 68.06L0 50L0.06 31.94L0.25 26.19L0.56 22.06L0.99 18.74L1.56 15.95L2.26 13.54L3.09 11.43L4.06 9.57L5.19 7.93L6.47 6.47L7.93 5.19L9.57 4.06L11.43 3.09L13.54 2.26L15.95 1.56L18.74 0.99L22.06 0.56L26.19 0.25L31.94 0.06L50 0L68.06 0.06L73.81 0.25L77.94 0.56L81.26 0.99L84.05 1.56L86.46 2.26L88.57 3.09L90.43 4.06L92.07 5.19L93.53 6.47L94.81 7.93L95.94 9.57L96.91 11.43L97.74 13.54L98.44 15.95L99.01 18.74L99.44 22.06L99.75 26.19L99.94 31.94Z' fill='%23fff'/></svg>")}.co-avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--co-border-radius-full);background:var(--co-semantic-surface-primary);color:var(--co-semantic-on-primary);font-family:var(--co-font-family-primary);font-weight:600;line-height:1;letter-spacing:var(--co-font-letter-spacing-body);overflow:hidden;flex-shrink:0;user-select:none;-webkit-font-smoothing:antialiased}.co-avatar::after{content:'';position:absolute;inset:0;pointer-events:none;border-radius:inherit;box-shadow:inset 0 0 0 var(--co-avatar-border-width, 1px) var(--co-avatar-border-color, transparent)}.co-avatar__text{text-transform:uppercase}.co-avatar__img{width:100%;height:100%;object-fit:cover;display:block}.co-avatar--square{border-radius:0;-webkit-mask:var(--co-avatar-squircle) center / 100% 100% no-repeat;mask:var(--co-avatar-squircle) center / 100% 100% no-repeat}.co-avatar--square::after{--co-avatar-bw:var(--co-avatar-border-width, 1px);box-shadow:none;background:var(--co-avatar-border-color, transparent);-webkit-mask:var(--co-avatar-squircle) center / 100% 100% no-repeat, var(--co-avatar-squircle) center / calc(100% - 2 * var(--co-avatar-bw)) calc(100% - 2 * var(--co-avatar-bw)) no-repeat;-webkit-mask-composite:xor;mask:var(--co-avatar-squircle) center / 100% 100% no-repeat, var(--co-avatar-squircle) center / calc(100% - 2 * var(--co-avatar-bw)) calc(100% - 2 * var(--co-avatar-bw)) no-repeat;mask-composite:exclude}.co-avatar--light{color:rgba(0, 0, 0, 0.87)}co-tooltip{display:inline-flex;align-items:center;line-height:0}`;
34
6
 
35
7
  const SIZE_MAP = {
@@ -70,6 +42,10 @@ const CoAvatar = class {
70
42
  const iconSize = (_b = ICON_SIZE_MAP[this.size]) !== null && _b !== void 0 ? _b : 24;
71
43
  const fontSize = (_c = FONT_SIZE_MAP[this.size]) !== null && _c !== void 0 ? _c : 'var(--co-font-size-18)';
72
44
  const showImage = this.type === 'image' && this.src && !this.imgFailed;
45
+ // Broken/missing image without initials falls back to the ICON (default
46
+ // "user") — never an empty disc. With `text` present, initials win (they
47
+ // identify the record better than a generic glyph).
48
+ const showIcon = this.type === 'icon' || (this.type === 'image' && !showImage && !this.text);
73
49
  const ariaLabel = this.type === 'text'
74
50
  ? this.text
75
51
  : this.type === 'image'
@@ -83,7 +59,7 @@ const CoAvatar = class {
83
59
  'co-avatar--light': !!this.color && isLightColor(this.color),
84
60
  }, style: Object.assign(Object.assign({ width: `var(--co-avatar-size, ${dim}px)`, height: `var(--co-avatar-size, ${dim}px)`, fontSize }, (this.color ? { background: this.color } : {})), (this.ringColor
85
61
  ? { '--co-avatar-border-color': this.ringColor, '--co-avatar-border-width': '2px' }
86
- : {})), part: "avatar", role: "img", "aria-label": ariaLabel }, showImage ? (h("img", { class: "co-avatar__img", src: this.src, alt: (_g = (_f = this.alt) !== null && _f !== void 0 ? _f : this.text) !== null && _g !== void 0 ? _g : '', onError: this.handleImgError })) : this.type === 'icon' ? (h("co-icon", { name: this.icon, weight: this.iconWeight, size: iconSize })) : (h("span", { class: "co-avatar__text" }, this.text))));
62
+ : {})), part: "avatar", role: "img", "aria-label": ariaLabel }, showImage ? (h("img", { class: "co-avatar__img", src: this.src, alt: (_g = (_f = this.alt) !== null && _f !== void 0 ? _f : this.text) !== null && _g !== void 0 ? _g : '', onError: this.handleImgError })) : showIcon ? (h("co-icon", { name: this.icon, weight: this.iconWeight, size: iconSize })) : (h("span", { class: "co-avatar__text" }, this.text))));
87
63
  // No tooltip when `name` is unset/empty — renders exactly as before, no wrapper.
88
64
  if (!this.name)
89
65
  return disc;
@@ -1,6 +1,6 @@
1
1
  import { r as registerInstance, h, a as getElement } from './index-CrtiywTB.js';
2
2
 
3
- const coButtonCss = () => `:host{display:inline-flex}.co-button{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:1px solid transparent;outline:none;font-family:var(--co-font-family-primary);font-weight:400;line-height:1;letter-spacing:var(--co-font-letter-spacing-body);white-space:nowrap;-webkit-font-smoothing:antialiased;transition:opacity var(--co-motion-duration-fast) var(--co-motion-ease-out), background var(--co-motion-duration-fast) var(--co-motion-ease-out), transform var(--co-motion-duration-fast) var(--co-motion-ease-out);box-sizing:border-box;-webkit-backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate))}.co-button--primary{background:var(--co-semantic-surface-primary);color:var(--co-semantic-on-primary);border-color:color-mix(in srgb, var(--co-semantic-on-primary) 28%, transparent)}.co-button--secondary{background:color-mix(in srgb, var(--co-semantic-surface-secondary) 55%, transparent);color:var(--co-semantic-on-secondary);border-color:var(--co-semantic-border-subtle)}.co-button--stroke{background:color-mix(in srgb, var(--co-semantic-surface-secondary) 25%, transparent);color:var(--co-semantic-text-default);border-color:var(--co-semantic-border-default)}.co-button--ghost{background:transparent;color:var(--co-semantic-text-default);border-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.co-button--danger{background:var(--co-semantic-status-error);color:var(--co-color-base-blanco);border-color:transparent}.co-button--success{background:var(--co-semantic-status-success);color:var(--co-color-base-blanco);border-color:transparent}.co-button--rounded.co-button--l{padding:var(--co-spacing-xl) var(--co-spacing-2xl);gap:var(--co-spacing-md);font-size:var(--co-font-size-18);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--rounded.co-button--m{padding:var(--co-spacing-lg) var(--co-spacing-xl);gap:var(--co-spacing-md);font-size:var(--co-font-size-16);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--rounded.co-button--s{padding:var(--co-spacing-md) var(--co-spacing-lg);gap:var(--co-spacing-sm2);font-size:var(--co-font-size-14);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--rounded.co-button--xs{padding:var(--co-spacing-md) var(--co-spacing-lg);gap:var(--co-spacing-sm2);font-size:var(--co-font-size-12);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--square.co-button--l{padding:var(--co-spacing-lg) var(--co-spacing-xl);gap:var(--co-spacing-md);font-size:var(--co-font-size-18);border-radius:var(--co-border-radius-lg)}.co-button--square.co-button--m{padding:var(--co-spacing-md) var(--co-spacing-lg);gap:var(--co-spacing-sm2);font-size:var(--co-font-size-16);border-radius:var(--co-border-radius-sm)}.co-button--square.co-button--s{padding:var(--co-spacing-sm2) var(--co-spacing-md);gap:var(--co-spacing-sm);font-size:var(--co-font-size-14);border-radius:var(--co-border-radius-xs)}.co-button--square.co-button--xs{padding:var(--co-spacing-sm) var(--co-spacing-sm2);gap:var(--co-spacing-xs);font-size:var(--co-font-size-12);border-radius:var(--co-spacing-sm)}.co-button--disabled,.co-button:disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}.co-button--primary:hover:not(:disabled){opacity:0.88}.co-button--secondary:hover:not(:disabled),.co-button--stroke:hover:not(:disabled){background:var(--co-semantic-surface-hover)}.co-button--ghost:hover:not(:disabled){background:color-mix(in srgb, var(--co-semantic-surface-hover) 60%, transparent);-webkit-backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate))}.co-button--danger:hover:not(:disabled),.co-button--success:hover:not(:disabled){opacity:0.88}.co-button:active:not(:disabled){transform:scale(0.97);transition-duration:var(--co-motion-duration-instant)}.co-button--primary{transition:opacity var(--co-motion-duration-fast) var(--co-motion-ease-out), background var(--co-motion-duration-fast) var(--co-motion-ease-out), transform var(--co-motion-duration-slow) var(--co-motion-ease-spring)}.co-button--secondary.co-button--elevated{box-shadow:var(--co-shadow-sm, 0 1px 2px 0 rgba(26, 26, 26, 0.04)), inset 0 0 0 1px var(--co-color-opacity-negro-8)}.co-button--ghost.co-button--surface-dark,.co-button--stroke.co-button--surface-dark{color:var(--co-color-base-blanco, #fff)}.co-button--ghost.co-button--surface-dark:hover:not(:disabled),.co-button--stroke.co-button--surface-dark:hover:not(:disabled){background:var(--co-color-opacity-blanco-16);-webkit-backdrop-filter:none;backdrop-filter:none}.co-button--danger.co-button--surface-dark:hover:not(:disabled){opacity:1;background:color-mix(in srgb, var(--co-semantic-status-error) 84%, var(--co-color-base-blanco, #fff))}.co-button--danger.co-button--surface-dark:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--co-color-base-blanco, #fff) 45%, transparent)}::slotted([slot="icon-left"]),::slotted([slot="icon-right"]){display:inline-flex;flex-shrink:0}@supports not (background: color-mix(in srgb, red, transparent)){.co-button--primary{background:var(--co-semantic-surface-primary)}.co-button--secondary{background:var(--co-semantic-surface-secondary)}.co-button--stroke{background:transparent}}`;
3
+ const coButtonCss = () => `:host{display:inline-flex}:host([disabled]){pointer-events:none}.co-button{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:1px solid transparent;outline:none;font-family:var(--co-font-family-primary);font-weight:400;line-height:1;letter-spacing:var(--co-font-letter-spacing-body);white-space:nowrap;-webkit-font-smoothing:antialiased;transition:opacity var(--co-motion-duration-fast) var(--co-motion-ease-out), background var(--co-motion-duration-fast) var(--co-motion-ease-out), transform var(--co-motion-duration-fast) var(--co-motion-ease-out);box-sizing:border-box;-webkit-backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate))}.co-button--primary{background:var(--co-semantic-surface-primary);color:var(--co-semantic-on-primary);border-color:color-mix(in srgb, var(--co-semantic-on-primary) 28%, transparent)}.co-button--secondary{background:color-mix(in srgb, var(--co-semantic-surface-secondary) 55%, transparent);color:var(--co-semantic-on-secondary);border-color:var(--co-semantic-border-subtle)}.co-button--stroke{background:color-mix(in srgb, var(--co-semantic-surface-secondary) 25%, transparent);color:var(--co-semantic-text-default);border-color:var(--co-semantic-border-default)}.co-button--ghost{background:transparent;color:var(--co-semantic-text-default);border-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.co-button--danger{background:var(--co-semantic-status-error);color:var(--co-color-base-blanco);border-color:transparent}.co-button--success{background:var(--co-semantic-status-success);color:var(--co-color-base-blanco);border-color:transparent}.co-button--rounded.co-button--l{padding:var(--co-spacing-xl) var(--co-spacing-2xl);gap:var(--co-spacing-md);font-size:var(--co-font-size-18);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--rounded.co-button--m{padding:var(--co-spacing-lg) var(--co-spacing-xl);gap:var(--co-spacing-md);font-size:var(--co-font-size-16);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--rounded.co-button--s{padding:var(--co-spacing-md) var(--co-spacing-lg);gap:var(--co-spacing-sm2);font-size:var(--co-font-size-14);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--rounded.co-button--xs{padding:var(--co-spacing-md) var(--co-spacing-lg);gap:var(--co-spacing-sm2);font-size:var(--co-font-size-12);border-radius:var(--co-button-radius, var(--co-border-radius-full))}.co-button--square.co-button--l{padding:var(--co-spacing-lg) var(--co-spacing-xl);gap:var(--co-spacing-md);font-size:var(--co-font-size-18);border-radius:var(--co-border-radius-lg)}.co-button--square.co-button--m{padding:var(--co-spacing-md) var(--co-spacing-lg);gap:var(--co-spacing-sm2);font-size:var(--co-font-size-16);border-radius:var(--co-border-radius-sm)}.co-button--square.co-button--s{padding:var(--co-spacing-sm2) var(--co-spacing-md);gap:var(--co-spacing-sm);font-size:var(--co-font-size-14);border-radius:var(--co-border-radius-xs)}.co-button--square.co-button--xs{padding:var(--co-spacing-sm) var(--co-spacing-sm2);gap:var(--co-spacing-xs);font-size:var(--co-font-size-12);border-radius:var(--co-spacing-sm)}.co-button--disabled,.co-button:disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}.co-button--primary:hover:not(:disabled){opacity:0.88}.co-button--secondary:hover:not(:disabled),.co-button--stroke:hover:not(:disabled){background:var(--co-semantic-surface-hover)}.co-button--ghost:hover:not(:disabled){background:color-mix(in srgb, var(--co-semantic-surface-hover) 60%, transparent);-webkit-backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate))}.co-button--danger:hover:not(:disabled),.co-button--success:hover:not(:disabled){opacity:0.88}.co-button:active:not(:disabled){transform:scale(0.97);transition-duration:var(--co-motion-duration-instant)}.co-button--primary{transition:opacity var(--co-motion-duration-fast) var(--co-motion-ease-out), background var(--co-motion-duration-fast) var(--co-motion-ease-out), transform var(--co-motion-duration-slow) var(--co-motion-ease-spring)}.co-button--secondary.co-button--elevated{box-shadow:var(--co-shadow-sm, 0 1px 2px 0 rgba(26, 26, 26, 0.04)), inset 0 0 0 1px var(--co-color-opacity-negro-8)}.co-button--ghost.co-button--surface-dark,.co-button--stroke.co-button--surface-dark{color:var(--co-color-base-blanco, #fff)}.co-button--ghost.co-button--surface-dark:hover:not(:disabled),.co-button--stroke.co-button--surface-dark:hover:not(:disabled){background:var(--co-color-opacity-blanco-16);-webkit-backdrop-filter:none;backdrop-filter:none}.co-button--danger.co-button--surface-dark:hover:not(:disabled){opacity:1;background:color-mix(in srgb, var(--co-semantic-status-error) 84%, var(--co-color-base-blanco, #fff))}.co-button--danger.co-button--surface-dark:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--co-color-base-blanco, #fff) 45%, transparent)}::slotted([slot="icon-left"]),::slotted([slot="icon-right"]){display:inline-flex;flex-shrink:0}@supports not (background: color-mix(in srgb, red, transparent)){.co-button--primary{background:var(--co-semantic-surface-primary)}.co-button--secondary{background:var(--co-semantic-surface-secondary)}.co-button--stroke{background:transparent}}`;
4
4
 
5
5
  const ICON_SIZE = { l: 20, m: 18, s: 16, xs: 14 };
6
6
  const CoButton = class {
@@ -23,7 +23,9 @@ const CoButton = class {
23
23
  * `variant="danger" surface="dark"`.
24
24
  */
25
25
  this.surface = 'light';
26
- /** Disabled state */
26
+ /** Disabled state. Reflected so :host([disabled]) can kill pointer-events —
27
+ * the inner button's own pointer-events:none re-targets clicks to the host,
28
+ * where consumers' click listeners live. */
27
29
  this.disabled = false;
28
30
  /** Icon weight applied to both iconLeft and iconRight */
29
31
  this.iconWeight = 'regular';
@@ -54,7 +56,7 @@ const CoButton = class {
54
56
  customStyle.background = this.color;
55
57
  if (this.textColor)
56
58
  customStyle.color = this.textColor;
57
- return (h("button", { key: 'e765a1fcb3b4efcc7c43e155015b3c178a536d3c', class: {
59
+ return (h("button", { key: '651f8d079c09cf21d076aa20564a462a15ca8c4a', class: {
58
60
  'co-button': true,
59
61
  [`co-button--${this.variant}`]: true,
60
62
  [`co-button--${this.shape}`]: true,
@@ -64,7 +66,7 @@ const CoButton = class {
64
66
  'co-button--disabled': this.disabled,
65
67
  }, style: Object.keys(customStyle).length ? customStyle : undefined, type: this.type, disabled: this.disabled, "aria-label": this.ariaLabelText || undefined, onClick: this.handleClick, part: "button" }, this.iconLeft
66
68
  ? h("co-icon", { name: this.iconLeft, weight: this.iconWeight, size: iconSize })
67
- : null, h("slot", { key: '8dd3e816276a67ba6072eeed1ad34a982b60389e' }, this.label), this.iconRight
69
+ : null, h("slot", { key: 'b8c5b230a473fe4a57aa087533186e410db64bed' }, this.label), this.iconRight
68
70
  ? h("co-icon", { name: this.iconRight, weight: this.iconWeight, size: iconSize })
69
71
  : null));
70
72
  }
@@ -365,6 +365,11 @@ function readableTextToken(host, bg) {
365
365
 
366
366
  const coCalendarMonthCss = () => `:host{display:block;font-family:var(--co-font-family-primary);--co-cal-daynum-h:24px;--co-cal-lane-h:22px;--co-cal-min-week-h:92px;--co-cal-gap:2px;--co-cal-surface:var(--co-semantic-surface-page);--co-cal-border:var(--co-semantic-border-default);--co-cal-text:var(--co-semantic-text-default);--co-cal-text-muted:var(--co-semantic-text-muted);--co-cal-hover:var(--co-semantic-surface-hover);--co-cal-today-ring:var(--co-color-primary-azul);--co-cal-event-radius:6px;--co-cal-elevation-hover:var(--co-shadow-lg);--co-cal-event-bg:var(--co-color-primary-azul);--co-cal-event-border:transparent;--co-cal-event-text:var(--co-color-base-blanco, #fff);--co-cal-event-text-light:var(--co-color-base-blanco, #fff);--co-cal-event-text-dark:var(--co-semantic-text-default)}.cal-month{display:flex;flex-direction:column;height:100%;border-radius:var(--co-border-radius-xs);overflow:hidden;background:var(--co-cal-surface)}.cal-month__dow{display:grid;grid-template-columns:repeat(7, 1fr);border-bottom:1px solid var(--co-cal-border)}.cal-month__dow-cell{padding:var(--co-spacing-xs) var(--co-spacing-sm);font-size:var(--co-font-size-10, 10px);font-weight:600;text-transform:uppercase;letter-spacing:0.04em;color:var(--co-cal-text-muted);text-align:right}.cal-month__week{position:relative;min-height:var(--co-cal-min-week-h);flex:1 0 auto}.cal-month__week:not(:last-child){border-bottom:1px solid var(--co-cal-border)}.cal-month__days{display:grid;grid-template-columns:repeat(7, 1fr);height:100%;position:absolute;inset:0}.cal-month__day{border-right:1px solid var(--co-cal-border);padding:var(--co-spacing-xxs);cursor:pointer;transition:background var(--co-motion-duration-fast) var(--co-motion-ease-out)}.cal-month__day:last-child{border-right:0}.cal-month__day:hover{background:var(--co-cal-hover)}.cal-month__day:focus-visible{outline:2px solid var(--co-semantic-border-focus);outline-offset:-2px}.cal-month__day--outside .cal-month__daynum{color:var(--co-cal-text-muted)}.cal-month__day--disabled{cursor:not-allowed;background:color-mix(in srgb, var(--co-cal-border) 20%, transparent)}.cal-month__day--drag-over{background:color-mix(in srgb, var(--co-cal-today-ring) 14%, transparent);box-shadow:inset 0 0 0 2px var(--co-cal-today-ring)}.cal-month__day--selected{background:color-mix(in srgb, var(--co-cal-today-ring) 10%, transparent)}.cal-month__daynum{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;margin-left:auto;float:right;font-size:var(--co-font-size-12, 12px);color:var(--co-cal-text);border-radius:var(--co-border-radius-full)}.cal-month__day--today .cal-month__daynum{background:var(--co-cal-today-ring);color:var(--co-color-base-blanco, #fff);font-weight:600}.cal-month__events{position:absolute;inset:0;pointer-events:none;}.cal-chip,.cal-month__more{position:absolute;height:calc(var(--co-cal-lane-h) - 3px);box-sizing:border-box;pointer-events:auto;display:flex;align-items:center;gap:var(--co-spacing-xxs);margin:0 3px;padding:0 var(--co-spacing-xs);border:1px solid var(--co-cal-event-border);border-radius:var(--co-cal-event-radius);font-family:inherit;font-size:var(--co-font-size-12, 12px);line-height:1;text-align:left;cursor:pointer;overflow:hidden;white-space:nowrap}.cal-chip{background:var(--co-cal-event-bg);color:var(--co-cal-event-text);user-select:none;-webkit-user-select:none;touch-action:none}.cal-month__chip-skeleton{position:absolute;height:calc(var(--co-cal-lane-h) - 3px);box-sizing:border-box;margin:0 3px;border-radius:var(--co-cal-event-radius);overflow:hidden;pointer-events:none}.cal-month__chip-skeleton co-skeleton{display:block;block-size:100%}.cal-chip--all-day:hover{filter:brightness(0.95);box-shadow:var(--co-cal-elevation-hover)}.cal-chip:focus-visible{outline:2px solid var(--co-semantic-border-focus);outline-offset:1px}.cal-chip--all-day{font-weight:500}.cal-chip__dot{flex:0 0 auto;width:7px;height:7px;border-radius:var(--co-border-radius-full);background:var(--co-cal-event-bg)}.cal-chip:not(.cal-chip--all-day){background:transparent;color:var(--co-cal-text);border-color:transparent}.cal-chip:not(.cal-chip--all-day):hover{background:var(--co-cal-hover);filter:none}.cal-chip__time{flex:0 0 auto;color:var(--co-cal-text-muted);font-variant-numeric:tabular-nums}.cal-chip__title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}.cal-chip__ext{flex:0 0 auto;margin-inline-start:auto;opacity:0.8}.cal-chip--past{opacity:0.55}.cal-chip--locked{cursor:default}.cal-chip--external{border-style:dashed}.cal-chip--dragging{opacity:0.4}.cal-month--interacting .cal-chip{pointer-events:none}.cal-chip--all-day.cal-chip--tentative{background-image:repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.5) 0 4px, transparent 4px 8px)}.cal-chip--cancelled{opacity:0.6}.cal-chip--cancelled .cal-chip__title{text-decoration:line-through}.cal-chip--continues-before{border-top-left-radius:0;border-bottom-left-radius:0;margin-left:0}.cal-chip--continues-after{border-top-right-radius:0;border-bottom-right-radius:0;margin-right:0}.cal-month__more{background:transparent;color:var(--co-cal-text-muted);border-color:transparent;font-weight:600;font-size:var(--co-font-size-11, 11px)}.cal-month__more:hover{background:var(--co-cal-hover);color:var(--co-cal-text)}`;
367
367
 
368
+ // Distancia (px) que el puntero debe recorrer tras el pointerdown para que un drag
369
+ // de evento se comprometa. Por debajo de esto el gesto es un CLICK: el drag no
370
+ // arranca, el chip conserva sus pointer-events y su click abre el popover. Mismo
371
+ // literal/mecanismo que co-calendar-timegrid.tsx (DRAG_THRESHOLD_PX ahí, línea ~28).
372
+ const DRAG_THRESHOLD_PX$1 = 5;
368
373
  const CoCalendarMonth = class {
369
374
  constructor(hostRef) {
370
375
  registerInstance(this, hostRef);
@@ -395,6 +400,21 @@ const CoCalendarMonth = class {
395
400
  /** Epoch ms of "now", refreshed on a 60s timer so `past` styling stays live. */
396
401
  this.nowMs = 0;
397
402
  this.onPointerUp = () => this.finishDrag();
403
+ this.onPointerMove = (e) => this.trackDrag(e);
404
+ // Drag ARMADO pero aún no comprometido: `startDrag` guarda el id y el punto de
405
+ // agarre acá; el drag pasa a activo (`dragId`) recién cuando el puntero cruza
406
+ // DRAG_THRESHOLD_PX en `trackDrag` (mismo patrón que co-calendar-timegrid.tsx,
407
+ // `dragArmedId`/`startMove`). Así un click simple en un evento arrastrable no
408
+ // arranca drag (que pone `pointer-events:none` en los chips vía
409
+ // `cal-month--interacting`) y su popover abre normal.
410
+ this.dragArmedId = null;
411
+ this.dragStartPointer = null;
412
+ // Set right before coEventDrop so the trailing click no-ops (mismo patrón que
413
+ // co-calendar-timegrid.tsx#suppressNextClick): un drag COMPROMETIDO deja el
414
+ // chip con pointer-events restaurados (`setInteracting(false)`) ANTES de que
415
+ // el navegador dispare el `click` sintético que sigue al `pointerup` — sin
416
+ // este flag ese click reabriría el popover justo después de soltar.
417
+ this.suppressNextClick = false;
398
418
  // ── Selection / activation ──────────────────────────────────────────────
399
419
  /** Día seleccionado que PERSISTE resaltado mientras el host tiene abierto su
400
420
  * form/bubble de creación (referencia visual, paridad Google). */
@@ -439,9 +459,11 @@ const CoCalendarMonth = class {
439
459
  }
440
460
  connectedCallback() {
441
461
  window.addEventListener('pointerup', this.onPointerUp);
462
+ window.addEventListener('pointermove', this.onPointerMove);
442
463
  }
443
464
  disconnectedCallback() {
444
465
  window.removeEventListener('pointerup', this.onPointerUp);
466
+ window.removeEventListener('pointermove', this.onPointerMove);
445
467
  if (this.nowTimer)
446
468
  window.clearInterval(this.nowTimer);
447
469
  }
@@ -498,16 +520,43 @@ const CoCalendarMonth = class {
498
520
  return;
499
521
  // Ver la nota en co-calendar-timegrid#startMove: preventDefault en
500
522
  // pointerdown mata el click y el chip arrastrable no podía activarse.
523
+ // Tampoco se toca dragId/interacting acá: eso arrancaba
524
+ // `cal-month--interacting` (pointer-events:none en los chips, css:249) en el
525
+ // pointerdown mismo y se comía el click de todo evento FUTURO arrastrable —
526
+ // el chip nunca veía el click nativo. Se arma un candidato nada más; el
527
+ // commit real ocurre en `trackDrag` al cruzar DRAG_THRESHOLD_PX.
501
528
  e.stopPropagation();
502
- this.dragId = id;
529
+ this.dragArmedId = id;
530
+ this.dragStartPointer = { x: e.clientX, y: e.clientY };
531
+ }
532
+ /** Arma → activa el drag al cruzar el umbral (ver DRAG_THRESHOLD_PX). Antes de
533
+ * eso no toca dragId/interacting, así el click nativo del chip sigue vivo. */
534
+ trackDrag(e) {
535
+ if (!this.dragArmedId || this.dragId)
536
+ return;
537
+ const sp = this.dragStartPointer;
538
+ if (!sp)
539
+ return;
540
+ if (Math.hypot(e.clientX - sp.x, e.clientY - sp.y) < DRAG_THRESHOLD_PX$1)
541
+ return;
542
+ this.dragId = this.dragArmedId;
543
+ this.dragArmedId = null;
503
544
  this.dragOverDate = null;
504
545
  this.setInteracting(true);
505
546
  }
506
547
  finishDrag() {
548
+ // pointerup habiendo solo ARMADO (sin cruzar el umbral) = fue un click, no un
549
+ // drag: desarmar en silencio y dejar pasar el click nativo → abre el popover.
550
+ if (this.dragArmedId && !this.dragId) {
551
+ this.dragArmedId = null;
552
+ this.dragStartPointer = null;
553
+ return;
554
+ }
507
555
  const id = this.dragId;
508
556
  const target = this.dragOverDate;
509
557
  this.dragId = null;
510
558
  this.dragOverDate = null;
559
+ this.dragStartPointer = null;
511
560
  this.setInteracting(false);
512
561
  if (!id || !target)
513
562
  return;
@@ -522,6 +571,10 @@ const CoCalendarMonth = class {
522
571
  return;
523
572
  if (!this.isDayInteractable(target))
524
573
  return;
574
+ this.suppressNextClick = true;
575
+ // Clear on the next macrotask: a same-target synthetic click fires before this
576
+ // (and is suppressed); a later unrelated click is not.
577
+ setTimeout(() => { this.suppressNextClick = false; }, 0);
525
578
  const shifted = shiftEventByDays(ev, deltaDays, this.timeZone);
526
579
  this.coEventDrop.emit({
527
580
  id,
@@ -613,6 +666,10 @@ const CoCalendarMonth = class {
613
666
  'cal-chip--cancelled': ev.responseState === 'cancelled' || ev.responseState === 'declined',
614
667
  }, style: style, title: ev.title, "aria-label": ev.title, onClick: (e) => {
615
668
  e.stopPropagation();
669
+ if (this.suppressNextClick) {
670
+ this.suppressNextClick = false;
671
+ return;
672
+ }
616
673
  this.activateEvent(ev.id, e.currentTarget.getBoundingClientRect());
617
674
  }, onDblClick: (e) => {
618
675
  e.stopPropagation();
@@ -626,7 +683,7 @@ const CoCalendarMonth = class {
626
683
  const short = getWeekdayLabels(this.locale, this.firstDayOfWeek, 'short');
627
684
  const long = getWeekdayLabels(this.locale, this.firstDayOfWeek, 'long');
628
685
  const today = todayYMD();
629
- return (h("div", { key: 'f8bcb53b7ef7c47a1ff59caee0305dfc1a3f1fc2', class: "cal-month", part: "grid", role: "grid", onKeyDown: this.handleKeyDown, ref: (el) => (this.rootEl = el) }, h("div", { key: '11acf9973a13ad661590a04dd934c86ceaa10f5d', class: "cal-month__dow", role: "row" }, short.map((lbl, i) => (h("span", { class: "cal-month__dow-cell", role: "columnheader", "aria-label": long[i] }, lbl)))), matrix.map((week, wi) => {
686
+ return (h("div", { key: '7cb63a84f7005ee7b5552a5d9b88c598f579b7be', class: "cal-month", part: "grid", role: "grid", onKeyDown: this.handleKeyDown, ref: (el) => (this.rootEl = el) }, h("div", { key: '70281a5799b9b95957d152e15a374001a2ec8fa2', class: "cal-month__dow", role: "row" }, short.map((lbl, i) => (h("span", { class: "cal-month__dow-cell", role: "columnheader", "aria-label": long[i] }, lbl)))), matrix.map((week, wi) => {
630
687
  var _a;
631
688
  return (h("div", { class: "cal-month__week", role: "row" }, h("div", { class: "cal-month__days" }, week.map((date) => {
632
689
  const ymd = parseISO(date);
@@ -1,6 +1,6 @@
1
1
  import { r as registerInstance, c as createEvent, h } from './index-CrtiywTB.js';
2
2
 
3
- const coCheckboxCss = () => `:host{display:inline-flex;font-family:var(--co-font-family-primary);font-size:var(--co-font-size-14);letter-spacing:var(--co-font-letter-spacing-body);line-height:1}.co-checkbox-row{display:flex;align-items:center;gap:var(--co-spacing-sm2);cursor:pointer}.co-checkbox-row--disabled{cursor:not-allowed}.co-checkbox__label{color:var(--co-semantic-text-secondary);font-size:var(--co-font-size-14);font-weight:400;line-height:1;white-space:nowrap;user-select:none}.co-checkbox-row--disabled .co-checkbox__label{color:var(--co-semantic-text-disabled)}.co-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:none;outline:none;padding:0;overflow:hidden;flex-shrink:0;box-sizing:border-box;transition:background var(--co-motion-duration-fast) var(--co-motion-ease-out), border-color var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-checkbox--small{width:16px;height:16px;border-radius:var(--co-border-radius-xxs);}.co-checkbox--medium{width:20px;height:20px;border-radius:var(--co-spacing-sm);}.co-checkbox--large{width:24px;height:24px;border-radius:var(--co-spacing-sm);}.co-checkbox:not(.co-checkbox--checked){background:color-mix(in srgb, var(--co-semantic-surface-secondary) 35%, transparent);-webkit-backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));border:1px solid color-mix(in srgb, var(--co-semantic-border-default) 75%, transparent)}.co-checkbox--checked{background:var(--co-semantic-surface-primary);border:none}.co-checkbox--indeterminate{background:var(--co-semantic-surface-primary);border:none}.co-checkbox--disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}.co-checkbox--overlay{border-radius:6px}.co-checkbox--overlay.co-checkbox--small{width:20px;height:20px;border-radius:6px}.co-checkbox--overlay.co-checkbox--medium,.co-checkbox--overlay.co-checkbox--large{width:22px;height:22px;border-radius:6px}.co-checkbox--overlay:not(.co-checkbox--checked):not(.co-checkbox--indeterminate){background:rgba(255, 255, 255, 0.9);box-shadow:inset 0 0 0 1px var(--co-color-opacity-negro-16, rgba(31, 28, 27, 0.16));border:none}.co-checkbox--overlay.co-checkbox--checked,.co-checkbox--overlay.co-checkbox--indeterminate{background:var(--co-color-primary-azul, #2563eb);border:none;box-shadow:none}.co-checkbox__glyph{display:block;pointer-events:none}.co-checkbox__glyph path{stroke:var(--co-semantic-on-primary);stroke-dasharray:1;stroke-dashoffset:1;opacity:0}.co-checkbox--checked .co-checkbox__check,.co-checkbox--indeterminate .co-checkbox__dash{stroke-dashoffset:0;opacity:1;transition:stroke-dashoffset var(--co-motion-duration-base) var(--co-motion-ease-out)}.co-checkbox--small .co-checkbox__glyph{width:12px;height:12px}.co-checkbox--medium .co-checkbox__glyph{width:14px;height:14px}.co-checkbox--large .co-checkbox__glyph{width:18px;height:18px}.co-checkbox--small .co-checkbox__check{stroke-width:2;}.co-checkbox--medium .co-checkbox__check{stroke-width:1.714;}.co-checkbox--large .co-checkbox__check{stroke-width:1.333;}.co-checkbox--small .co-checkbox__dash{stroke-width:2;}.co-checkbox--medium .co-checkbox__dash{stroke-width:2;}.co-checkbox--large .co-checkbox__dash{stroke-width:1.778;}.co-checkbox--overlay .co-checkbox__glyph{width:100%;height:100%}.co-checkbox--overlay .co-checkbox__glyph path{stroke:#fff;stroke-width:2.2}@supports not (background: color-mix(in srgb, red, transparent)){.co-checkbox:not(.co-checkbox--checked){background:transparent}}`;
3
+ const coCheckboxCss = () => `:host{display:inline-flex;font-family:var(--co-font-family-primary);font-size:var(--co-font-size-14);letter-spacing:var(--co-font-letter-spacing-body);line-height:1}.co-checkbox-row{display:flex;align-items:center;gap:var(--co-spacing-sm2);cursor:pointer}.co-checkbox-row--disabled{cursor:not-allowed}.co-checkbox__label{color:var(--co-semantic-text-secondary);font-size:var(--co-font-size-14);font-weight:400;line-height:1;white-space:nowrap;user-select:none}.co-checkbox-row--disabled .co-checkbox__label{color:var(--co-semantic-text-disabled)}.co-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:none;outline:none;padding:0;overflow:hidden;flex-shrink:0;box-sizing:border-box;transition:background var(--co-motion-duration-fast) var(--co-motion-ease-out), border-color var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-checkbox--small{width:16px;height:16px;border-radius:var(--co-border-radius-xxs);}.co-checkbox--medium{width:20px;height:20px;border-radius:var(--co-spacing-sm);}.co-checkbox--large{width:24px;height:24px;border-radius:var(--co-spacing-sm);}.co-checkbox:not(.co-checkbox--checked){background:color-mix(in srgb, var(--co-semantic-surface-secondary) 35%, transparent);-webkit-backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));backdrop-filter:blur(var(--co-glass-blur)) saturate(var(--co-glass-saturate));border:1px solid color-mix(in srgb, var(--co-semantic-border-default) 75%, transparent)}.co-checkbox--checked{background:var(--co-semantic-surface-primary);border:none}.co-checkbox--indeterminate{background:var(--co-semantic-surface-primary);border:none}.co-checkbox--disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}.co-checkbox--overlay{border-radius:6px}.co-checkbox--overlay.co-checkbox--small{width:20px;height:20px;border-radius:6px}.co-checkbox--overlay.co-checkbox--medium,.co-checkbox--overlay.co-checkbox--large{width:22px;height:22px;border-radius:6px}.co-checkbox--overlay:not(.co-checkbox--checked):not(.co-checkbox--indeterminate){background:rgba(255, 255, 255, 0.9);box-shadow:inset 0 0 0 1px var(--co-color-opacity-negro-16, rgba(31, 28, 27, 0.16));border:none}.co-checkbox--overlay.co-checkbox--checked,.co-checkbox--overlay.co-checkbox--indeterminate{background:var(--co-color-primary-azul, #2563eb);border:none;box-shadow:none}.co-checkbox__glyph{display:block;pointer-events:none}.co-checkbox__glyph path{stroke:var(--co-semantic-on-primary);stroke-dasharray:1;stroke-dashoffset:1;opacity:0}.co-checkbox--checked .co-checkbox__check,.co-checkbox--indeterminate .co-checkbox__dash{stroke-dashoffset:0;opacity:1;transition:stroke-dashoffset var(--co-motion-duration-base) var(--co-motion-ease-out)}.co-checkbox--small .co-checkbox__glyph{width:12px;height:12px}.co-checkbox--medium .co-checkbox__glyph{width:14px;height:14px}.co-checkbox--large .co-checkbox__glyph{width:18px;height:18px}.co-checkbox--small .co-checkbox__check{stroke-width:2;}.co-checkbox--medium .co-checkbox__check{stroke-width:1.714;}.co-checkbox--large .co-checkbox__check{stroke-width:1.333;}.co-checkbox--small .co-checkbox__dash{stroke-width:2;}.co-checkbox--medium .co-checkbox__dash{stroke-width:2;}.co-checkbox--large .co-checkbox__dash{stroke-width:1.778;}.co-checkbox--overlay .co-checkbox__glyph{width:100%;height:100%}.co-checkbox--overlay .co-checkbox__glyph path{stroke:#fff;stroke-width:2.2}@supports not (background: color-mix(in srgb, red, transparent)){.co-checkbox:not(.co-checkbox--checked){background:transparent}}.co-checkbox.co-checkbox:focus-visible{outline:none;border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px var(--co-semantic-border-focus)}`;
4
4
 
5
5
  const CoCheckbox = class {
6
6
  constructor(hostRef) {
@@ -35,6 +35,12 @@ const CoCheckbox = class {
35
35
  }
36
36
  }
37
37
  };
38
+ this.handleKeyDown = (e) => {
39
+ if (e.key === ' ') {
40
+ e.preventDefault(); // Space no debe scrollear la página
41
+ this.handleClick(); // ya guarda disabled y resuelve indeterminate
42
+ }
43
+ };
38
44
  }
39
45
  render() {
40
46
  const isOverlay = this.appearance === 'overlay';
@@ -42,17 +48,17 @@ const CoCheckbox = class {
42
48
  // Only override the fill when a custom color is provided AND the box is "on".
43
49
  // Leaving this undefined keeps the default appearance byte-identical to before.
44
50
  const boxStyle = this.onColor && isOn ? { background: this.onColor } : undefined;
45
- return (h("div", { key: '31690de633689da0b273e3c88cc200cabb4cee75', class: {
51
+ return (h("div", { key: 'caf200e3c53efa2a00d28db0e149da953e4432da', class: {
46
52
  'co-checkbox-row': true,
47
53
  'co-checkbox-row--disabled': this.disabled,
48
- }, onClick: this.handleClick }, h("span", { key: '2b0c4ebbe4c7a7a8046cf726e682a3d42ae3ebbe', role: "checkbox", "aria-checked": this.indeterminate ? 'mixed' : String(this.checked), "aria-label": this.label || '', class: {
54
+ }, onClick: this.handleClick }, h("span", { key: 'a8fe01958d81587129f304ce33f1f5fef882dd9f', role: "checkbox", "aria-checked": this.indeterminate ? 'mixed' : String(this.checked), "aria-label": this.label || '', "aria-disabled": this.disabled ? 'true' : undefined, tabIndex: this.disabled ? -1 : 0, onKeyDown: this.handleKeyDown, class: {
49
55
  'co-checkbox': true,
50
56
  [`co-checkbox--${this.size}`]: true,
51
57
  'co-checkbox--overlay': isOverlay,
52
58
  'co-checkbox--checked': this.checked && !this.indeterminate,
53
59
  'co-checkbox--indeterminate': this.indeterminate,
54
60
  'co-checkbox--disabled': this.disabled,
55
- }, style: boxStyle, part: "box" }, h("svg", { key: 'a127c176e0233460f14c4261d8d2157e657689a9', class: "co-checkbox__glyph", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" }, h("path", { key: 'ad7dc0018cdae31156884cd04326bbcdba132b4f', class: "co-checkbox__check", d: "M3.5 8.5l3 3 6-6.5", pathLength: "1", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { key: 'dd665144b25aa51339cf9f6ce0e0edf65cfbe5a9', class: "co-checkbox__dash", d: "M3 8h10", pathLength: "1", "stroke-linecap": "round" }))), this.label && (h("span", { key: '08d6c695e2cbb8188564dc8bb5aab9b569c24838', class: "co-checkbox__label", part: "label" }, this.label))));
61
+ }, style: boxStyle, part: "box" }, h("svg", { key: 'd9ea60be2c2e58c227aeca8ae3b8e8f459f3522d', class: "co-checkbox__glyph", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" }, h("path", { key: 'd25f835b95a2200d44b5e4afdeb727d758e0650f', class: "co-checkbox__check", d: "M3.5 8.5l3 3 6-6.5", pathLength: "1", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { key: 'b7a043b9910736a8bdd15720fd7857c01250086d', class: "co-checkbox__dash", d: "M3 8h10", pathLength: "1", "stroke-linecap": "round" }))), this.label && (h("span", { key: '2e256fb7fd1515bf9dbe3dc380a0d7d09d5347ac', class: "co-checkbox__label", part: "label" }, this.label))));
56
62
  }
57
63
  };
58
64
  CoCheckbox.style = coCheckboxCss();