beez-ui 0.8.1 → 0.9.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +11 -9
  3. package/dist/components/animated-collapse.js +9 -3
  4. package/dist/components/animated-list-item.js +37 -34
  5. package/dist/components/filter-presets-bar.d.ts +71 -0
  6. package/dist/components/filter-presets-bar.js +508 -0
  7. package/dist/components/presence-swap.js +38 -51
  8. package/dist/components/reaction-button.d.ts +7 -2
  9. package/dist/components/reaction-button.js +59 -48
  10. package/dist/hooks.d.ts +10 -0
  11. package/dist/hooks.js +10 -0
  12. package/dist/index.d.ts +1 -23
  13. package/dist/index.js +1 -23
  14. package/dist/styles.css +1 -1
  15. package/package.json +11 -126
  16. package/dist/components/bouncing-dots-loader.d.ts +0 -19
  17. package/dist/components/bouncing-dots-loader.js +0 -47
  18. package/dist/components/confirm-delete-button.d.ts +0 -29
  19. package/dist/components/confirm-delete-button.js +0 -254
  20. package/dist/components/empty-state.d.ts +0 -24
  21. package/dist/components/empty-state.js +0 -37
  22. package/dist/components/error-state.d.ts +0 -20
  23. package/dist/components/error-state.js +0 -145
  24. package/dist/components/external-browser-handoff.d.ts +0 -27
  25. package/dist/components/external-browser-handoff.js +0 -306
  26. package/dist/components/info-popover.d.ts +0 -23
  27. package/dist/components/info-popover.js +0 -158
  28. package/dist/components/month-calendar-header.d.ts +0 -65
  29. package/dist/components/month-calendar-header.js +0 -337
  30. package/dist/components/month-grid.d.ts +0 -59
  31. package/dist/components/month-grid.js +0 -301
  32. package/dist/components/notification-bell.d.ts +0 -50
  33. package/dist/components/notification-bell.js +0 -338
  34. package/dist/components/notification-panel.d.ts +0 -56
  35. package/dist/components/notification-panel.js +0 -281
  36. package/dist/components/open-in-browser-cta.d.ts +0 -22
  37. package/dist/components/open-in-browser-cta.js +0 -61
  38. package/dist/components/pwa-update-control.d.ts +0 -18
  39. package/dist/components/pwa-update-control.js +0 -119
  40. package/dist/emoji-picker.d.ts +0 -27
  41. package/dist/emoji-picker.js +0 -283
  42. package/dist/hooks/use-minute-clock.d.ts +0 -23
  43. package/dist/hooks/use-minute-clock.js +0 -147
  44. package/dist/hooks/use-month-transition-direction.d.ts +0 -21
  45. package/dist/hooks/use-month-transition-direction.js +0 -110
  46. package/dist/lib/browser-navigation.d.ts +0 -21
  47. package/dist/lib/browser-navigation.js +0 -42
  48. package/dist/lib/in-app-browser.d.ts +0 -35
  49. package/dist/lib/in-app-browser.js +0 -80
  50. package/dist/lib/month-grid.d.ts +0 -42
  51. package/dist/lib/month-grid.js +0 -74
@@ -0,0 +1,508 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Saved queries for `FilterQueryBar`: a button that stores the current query under a name and a
5
+ * row of chips to apply, edit or delete them. Persistence stays with the application.
6
+ */
7
+ import { useId, useState } from "react";
8
+ import { Bookmark, Pencil, X } from "lucide-react";
9
+ import { cn } from "../lib/utils.js";
10
+ import { Button } from "./button.js";
11
+ import { FilterQueryBar } from "./filter-query-bar.js";
12
+ import { Input } from "./input.js";
13
+ import { Label } from "./label.js";
14
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
15
+ import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
16
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
+ const ENTER_KEY = "Enter";
18
+ /** Suggestions of the query editor render in their own popover, outside the edit popover. */
19
+ const NESTED_POPOVER_SELECTOR = "[data-slot=\"popover-content\"]";
20
+ /**
21
+ * Tells whether a value is a non-null object.
22
+ * @param value - Untrusted value.
23
+ * @returns Whether its properties can be read.
24
+ */
25
+ function isRecord(value) {
26
+ return typeof value === "object" && value !== null;
27
+ }
28
+ /**
29
+ * Validates presets restored from untrusted storage, trimming names and queries and dropping
30
+ * malformed or empty entries.
31
+ * @param value - Parsed stored value, such as the result of `JSON.parse`.
32
+ * @returns The valid presets, or an empty list when the value is not a list.
33
+ */
34
+ export function parseFilterPresets(value) {
35
+ if (!Array.isArray(value)) return [];
36
+ return value.flatMap((entry) => {
37
+ if (!isRecord(entry) || typeof entry.name !== "string" || typeof entry.query !== "string") return [];
38
+ const name = entry.name.trim();
39
+ const query = entry.query.trim();
40
+ return name && query ? [{
41
+ name,
42
+ query
43
+ }] : [];
44
+ });
45
+ }
46
+ export const FILTER_PRESET_DEFAULT_LABELS = {
47
+ saveAction: "Guardar filtro",
48
+ saveConfirm: "Guardar",
49
+ saveConfirmAriaLabel: "Guardar filtro con nombre",
50
+ presetName: "Nombre del filtro",
51
+ presetNamePlaceholder: "Mi filtro",
52
+ presetQuery: "Búsqueda del filtro",
53
+ presetQueryPlaceholder: "",
54
+ savedPresets: "Filtros guardados:",
55
+ editConfirmAriaLabel: "Guardar cambios del filtro",
56
+ cancel: "Cancelar",
57
+ delete: "Eliminar",
58
+ emptyNameError: "Ingresá un nombre para el filtro.",
59
+ emptyCurrentQueryError: "Escribí una búsqueda en la barra antes de guardarla.",
60
+ emptyPresetQueryError: "Ingresá una búsqueda para el filtro.",
61
+ duplicateNameError: "Ya existe un filtro con ese nombre.",
62
+ applyPresetAriaLabel: (presetName) => `Aplicar filtro guardado ${presetName}`,
63
+ editPresetAriaLabel: (presetName) => `Editar filtro guardado ${presetName}`,
64
+ deletePresetAriaLabel: (presetName) => `Eliminar filtro guardado ${presetName}`,
65
+ deleteConfirmation: (presetName) => `¿Querés eliminar el filtro guardado "${presetName}"?`
66
+ };
67
+ const FORM_POPOVER_CLASS_NAME = "grid w-64 gap-2";
68
+ const ERROR_CLASS_NAME = "m-0 text-xs text-destructive";
69
+ const CHIP_ICON_BUTTON_CLASS_NAME = "inline-flex cursor-pointer items-center border-0 bg-transparent py-[0.35rem] text-muted-foreground [&_svg]:size-3";
70
+ /**
71
+ * Compact icon button that saves the current query as a named preset. Fits the action slot of
72
+ * the filter bar input.
73
+ * @param props - Save availability, save callback and optional labels.
74
+ * @returns The button and its naming popover.
75
+ */
76
+ export function FilterPresetSaveButton(t0) {
77
+ const $ = _c(45);
78
+ const { canSaveCurrentQuery, onSaveCurrentQuery, labels } = t0;
79
+ let t1;
80
+ if ($[0] !== labels) {
81
+ t1 = {
82
+ ...FILTER_PRESET_DEFAULT_LABELS,
83
+ ...labels
84
+ };
85
+ $[0] = labels;
86
+ $[1] = t1;
87
+ } else {
88
+ t1 = $[1];
89
+ }
90
+ const resolvedLabels = t1;
91
+ const nameInputId = useId();
92
+ const [isOpen, setIsOpen] = useState(false);
93
+ const [nameDraft, setNameDraft] = useState("");
94
+ const [error, setError] = useState(null);
95
+ let t2;
96
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
97
+ t2 = (nextOpen) => {
98
+ setIsOpen(nextOpen);
99
+ if (!nextOpen) {
100
+ setNameDraft("");
101
+ setError(null);
102
+ }
103
+ };
104
+ $[2] = t2;
105
+ } else {
106
+ t2 = $[2];
107
+ }
108
+ const handleOpenChange = t2;
109
+ let t3;
110
+ if ($[3] !== nameDraft || $[4] !== onSaveCurrentQuery || $[5] !== resolvedLabels.emptyCurrentQueryError || $[6] !== resolvedLabels.emptyNameError) {
111
+ t3 = () => {
112
+ const presetName = nameDraft.trim();
113
+ if (!presetName) {
114
+ setError(resolvedLabels.emptyNameError);
115
+ return;
116
+ }
117
+ if (!onSaveCurrentQuery(presetName)) {
118
+ setError(resolvedLabels.emptyCurrentQueryError);
119
+ return;
120
+ }
121
+ handleOpenChange(false);
122
+ };
123
+ $[3] = nameDraft;
124
+ $[4] = onSaveCurrentQuery;
125
+ $[5] = resolvedLabels.emptyCurrentQueryError;
126
+ $[6] = resolvedLabels.emptyNameError;
127
+ $[7] = t3;
128
+ } else {
129
+ t3 = $[7];
130
+ }
131
+ const handleConfirmSave = t3;
132
+ const t4 = !canSaveCurrentQuery;
133
+ let t5;
134
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
135
+ t5 = /* @__PURE__ */ _jsx(Bookmark, { "aria-hidden": "true" });
136
+ $[8] = t5;
137
+ } else {
138
+ t5 = $[8];
139
+ }
140
+ let t6;
141
+ if ($[9] !== resolvedLabels.saveAction || $[10] !== t4) {
142
+ t6 = /* @__PURE__ */ _jsx(TooltipTrigger, {
143
+ asChild: true,
144
+ children: /* @__PURE__ */ _jsx(PopoverTrigger, {
145
+ asChild: true,
146
+ children: /* @__PURE__ */ _jsx(Button, {
147
+ "data-slot": "filter-preset-save-button",
148
+ "aria-label": resolvedLabels.saveAction,
149
+ disabled: t4,
150
+ size: "icon-xs",
151
+ type: "button",
152
+ variant: "ghost",
153
+ children: t5
154
+ })
155
+ })
156
+ });
157
+ $[9] = resolvedLabels.saveAction;
158
+ $[10] = t4;
159
+ $[11] = t6;
160
+ } else {
161
+ t6 = $[11];
162
+ }
163
+ let t7;
164
+ if ($[12] !== resolvedLabels.saveAction) {
165
+ t7 = /* @__PURE__ */ _jsx(TooltipContent, { children: resolvedLabels.saveAction });
166
+ $[12] = resolvedLabels.saveAction;
167
+ $[13] = t7;
168
+ } else {
169
+ t7 = $[13];
170
+ }
171
+ let t8;
172
+ if ($[14] !== t6 || $[15] !== t7) {
173
+ t8 = /* @__PURE__ */ _jsxs(Tooltip, { children: [t6, t7] });
174
+ $[14] = t6;
175
+ $[15] = t7;
176
+ $[16] = t8;
177
+ } else {
178
+ t8 = $[16];
179
+ }
180
+ let t9;
181
+ if ($[17] !== nameInputId || $[18] !== resolvedLabels.presetName) {
182
+ t9 = /* @__PURE__ */ _jsx(Label, {
183
+ htmlFor: nameInputId,
184
+ children: resolvedLabels.presetName
185
+ });
186
+ $[17] = nameInputId;
187
+ $[18] = resolvedLabels.presetName;
188
+ $[19] = t9;
189
+ } else {
190
+ t9 = $[19];
191
+ }
192
+ let t10;
193
+ if ($[20] !== error) {
194
+ t10 = (event) => {
195
+ setNameDraft(event.target.value);
196
+ if (error) {
197
+ setError(null);
198
+ }
199
+ };
200
+ $[20] = error;
201
+ $[21] = t10;
202
+ } else {
203
+ t10 = $[21];
204
+ }
205
+ let t11;
206
+ if ($[22] !== handleConfirmSave) {
207
+ t11 = (event_0) => {
208
+ if (event_0.key !== ENTER_KEY) {
209
+ return;
210
+ }
211
+ event_0.preventDefault();
212
+ handleConfirmSave();
213
+ };
214
+ $[22] = handleConfirmSave;
215
+ $[23] = t11;
216
+ } else {
217
+ t11 = $[23];
218
+ }
219
+ let t12;
220
+ if ($[24] !== nameDraft || $[25] !== nameInputId || $[26] !== resolvedLabels.presetNamePlaceholder || $[27] !== t10 || $[28] !== t11) {
221
+ t12 = /* @__PURE__ */ _jsx(Input, {
222
+ id: nameInputId,
223
+ onChange: t10,
224
+ onKeyDown: t11,
225
+ placeholder: resolvedLabels.presetNamePlaceholder,
226
+ type: "text",
227
+ value: nameDraft
228
+ });
229
+ $[24] = nameDraft;
230
+ $[25] = nameInputId;
231
+ $[26] = resolvedLabels.presetNamePlaceholder;
232
+ $[27] = t10;
233
+ $[28] = t11;
234
+ $[29] = t12;
235
+ } else {
236
+ t12 = $[29];
237
+ }
238
+ let t13;
239
+ if ($[30] !== error) {
240
+ t13 = error ? /* @__PURE__ */ _jsx("p", {
241
+ className: ERROR_CLASS_NAME,
242
+ role: "alert",
243
+ children: error
244
+ }) : null;
245
+ $[30] = error;
246
+ $[31] = t13;
247
+ } else {
248
+ t13 = $[31];
249
+ }
250
+ let t14;
251
+ if ($[32] !== handleConfirmSave || $[33] !== resolvedLabels.saveConfirm || $[34] !== resolvedLabels.saveConfirmAriaLabel) {
252
+ t14 = /* @__PURE__ */ _jsx(Button, {
253
+ "aria-label": resolvedLabels.saveConfirmAriaLabel,
254
+ onClick: handleConfirmSave,
255
+ size: "sm",
256
+ type: "button",
257
+ children: resolvedLabels.saveConfirm
258
+ });
259
+ $[32] = handleConfirmSave;
260
+ $[33] = resolvedLabels.saveConfirm;
261
+ $[34] = resolvedLabels.saveConfirmAriaLabel;
262
+ $[35] = t14;
263
+ } else {
264
+ t14 = $[35];
265
+ }
266
+ let t15;
267
+ if ($[36] !== t12 || $[37] !== t13 || $[38] !== t14 || $[39] !== t9) {
268
+ t15 = /* @__PURE__ */ _jsxs(PopoverContent, {
269
+ align: "end",
270
+ className: FORM_POPOVER_CLASS_NAME,
271
+ children: [
272
+ t9,
273
+ t12,
274
+ t13,
275
+ t14
276
+ ]
277
+ });
278
+ $[36] = t12;
279
+ $[37] = t13;
280
+ $[38] = t14;
281
+ $[39] = t9;
282
+ $[40] = t15;
283
+ } else {
284
+ t15 = $[40];
285
+ }
286
+ let t16;
287
+ if ($[41] !== isOpen || $[42] !== t15 || $[43] !== t8) {
288
+ t16 = /* @__PURE__ */ _jsxs(Popover, {
289
+ onOpenChange: handleOpenChange,
290
+ open: isOpen,
291
+ children: [t8, t15]
292
+ });
293
+ $[41] = isOpen;
294
+ $[42] = t15;
295
+ $[43] = t8;
296
+ $[44] = t16;
297
+ } else {
298
+ t16 = $[44];
299
+ }
300
+ return t16;
301
+ }
302
+ /**
303
+ * Renders one chip per saved preset: its name applies it, the pencil edits its name and query,
304
+ * and the cross deletes it after a confirmation. Renders nothing without presets.
305
+ * @param props - Presets, filter configs, callbacks and optional labels.
306
+ * @returns The presets row, or nothing.
307
+ */
308
+ export function FilterPresetsBar(t0) {
309
+ const $ = _c(4);
310
+ const { presets, queryFilterConfigs, onApplyPreset, onDeletePreset, onUpdatePreset, labels, className } = t0;
311
+ const resolvedLabels = {
312
+ ...FILTER_PRESET_DEFAULT_LABELS,
313
+ ...labels
314
+ };
315
+ const nameInputId = useId();
316
+ const [editingPresetName, setEditingPresetName] = useState(null);
317
+ const [nameDraft, setNameDraft] = useState("");
318
+ const [queryDraft, setQueryDraft] = useState("");
319
+ const [editError, setEditError] = useState(null);
320
+ const [deletingPresetName, setDeletingPresetName] = useState(null);
321
+ let t1;
322
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
323
+ t1 = (preset, nextOpen) => {
324
+ setEditError(null);
325
+ if (!nextOpen) {
326
+ setEditingPresetName(null);
327
+ return;
328
+ }
329
+ setEditingPresetName(preset.name);
330
+ setNameDraft(preset.name);
331
+ setQueryDraft(preset.query);
332
+ };
333
+ $[0] = t1;
334
+ } else {
335
+ t1 = $[0];
336
+ }
337
+ const handleEditOpenChange = t1;
338
+ const handleConfirmEdit = () => {
339
+ if (editingPresetName === null) {
340
+ return;
341
+ }
342
+ const name = nameDraft.trim();
343
+ const query = queryDraft.trim();
344
+ if (!name) {
345
+ setEditError(resolvedLabels.emptyNameError);
346
+ return;
347
+ }
348
+ if (!query) {
349
+ setEditError(resolvedLabels.emptyPresetQueryError);
350
+ return;
351
+ }
352
+ if (presets.some((preset_0) => preset_0.name === name && preset_0.name !== editingPresetName)) {
353
+ setEditError(resolvedLabels.duplicateNameError);
354
+ return;
355
+ }
356
+ onUpdatePreset({
357
+ name,
358
+ originalName: editingPresetName,
359
+ query
360
+ });
361
+ setEditingPresetName(null);
362
+ };
363
+ if (presets.length === 0) {
364
+ return null;
365
+ }
366
+ let t2;
367
+ if ($[1] !== className) {
368
+ t2 = cn("flex flex-wrap items-center gap-[0.4rem]", className);
369
+ $[1] = className;
370
+ $[2] = t2;
371
+ } else {
372
+ t2 = $[2];
373
+ }
374
+ let t3;
375
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
376
+ t3 = /* @__PURE__ */ _jsx(Bookmark, { "aria-hidden": "true" });
377
+ $[3] = t3;
378
+ } else {
379
+ t3 = $[3];
380
+ }
381
+ return /* @__PURE__ */ _jsxs("div", {
382
+ "data-slot": "filter-presets-bar",
383
+ className: t2,
384
+ children: [/* @__PURE__ */ _jsxs("span", {
385
+ className: "inline-flex items-center gap-[0.3rem] text-xs font-medium text-muted-foreground [&_svg]:size-[0.8rem]",
386
+ children: [t3, resolvedLabels.savedPresets]
387
+ }), presets.map((preset_1) => /* @__PURE__ */ _jsxs("span", {
388
+ "data-slot": "filter-preset-chip",
389
+ className: "inline-flex items-center overflow-hidden rounded-full border border-border bg-muted text-xs leading-none",
390
+ children: [
391
+ /* @__PURE__ */ _jsx("button", {
392
+ "aria-label": resolvedLabels.applyPresetAriaLabel(preset_1.name),
393
+ className: "max-w-48 cursor-pointer truncate border-0 bg-transparent py-[0.35rem] pr-1 pl-[0.65rem] text-inherit hover:text-primary focus-visible:text-primary",
394
+ onClick: () => onApplyPreset(preset_1),
395
+ title: preset_1.query,
396
+ type: "button",
397
+ children: preset_1.name
398
+ }),
399
+ /* @__PURE__ */ _jsxs(Popover, {
400
+ onOpenChange: (nextOpen_0) => handleEditOpenChange(preset_1, nextOpen_0),
401
+ open: editingPresetName === preset_1.name,
402
+ children: [/* @__PURE__ */ _jsx(PopoverTrigger, {
403
+ asChild: true,
404
+ children: /* @__PURE__ */ _jsx("button", {
405
+ "aria-label": resolvedLabels.editPresetAriaLabel(preset_1.name),
406
+ className: cn(CHIP_ICON_BUTTON_CLASS_NAME, "px-[0.15rem] hover:text-primary focus-visible:text-primary"),
407
+ type: "button",
408
+ children: /* @__PURE__ */ _jsx(Pencil, { "aria-hidden": "true" })
409
+ })
410
+ }), /* @__PURE__ */ _jsxs(PopoverContent, {
411
+ align: "start",
412
+ className: FORM_POPOVER_CLASS_NAME,
413
+ onInteractOutside: _temp,
414
+ children: [
415
+ /* @__PURE__ */ _jsx(Label, {
416
+ htmlFor: nameInputId,
417
+ children: resolvedLabels.presetName
418
+ }),
419
+ /* @__PURE__ */ _jsx(Input, {
420
+ id: nameInputId,
421
+ onChange: (event_0) => {
422
+ setNameDraft(event_0.target.value);
423
+ if (editError) {
424
+ setEditError(null);
425
+ }
426
+ },
427
+ type: "text",
428
+ value: nameDraft
429
+ }),
430
+ /* @__PURE__ */ _jsx("span", {
431
+ className: "text-sm leading-none font-medium",
432
+ children: resolvedLabels.presetQuery
433
+ }),
434
+ /* @__PURE__ */ _jsx(FilterQueryBar, {
435
+ ariaLabel: resolvedLabels.presetQuery,
436
+ configs: queryFilterConfigs,
437
+ onValueChange: (nextQuery) => {
438
+ setQueryDraft(nextQuery);
439
+ if (editError) {
440
+ setEditError(null);
441
+ }
442
+ },
443
+ placeholder: resolvedLabels.presetQueryPlaceholder,
444
+ value: queryDraft
445
+ }),
446
+ editError ? /* @__PURE__ */ _jsx("p", {
447
+ className: ERROR_CLASS_NAME,
448
+ role: "alert",
449
+ children: editError
450
+ }) : null,
451
+ /* @__PURE__ */ _jsx(Button, {
452
+ "aria-label": resolvedLabels.editConfirmAriaLabel,
453
+ onClick: handleConfirmEdit,
454
+ size: "sm",
455
+ type: "button",
456
+ children: resolvedLabels.saveConfirm
457
+ })
458
+ ]
459
+ })]
460
+ }),
461
+ /* @__PURE__ */ _jsxs(Popover, {
462
+ onOpenChange: (nextOpen_1) => setDeletingPresetName(nextOpen_1 ? preset_1.name : null),
463
+ open: deletingPresetName === preset_1.name,
464
+ children: [/* @__PURE__ */ _jsx(PopoverTrigger, {
465
+ asChild: true,
466
+ children: /* @__PURE__ */ _jsx("button", {
467
+ "aria-label": resolvedLabels.deletePresetAriaLabel(preset_1.name),
468
+ className: cn(CHIP_ICON_BUTTON_CLASS_NAME, "pr-2 pl-[0.15rem] hover:text-destructive focus-visible:text-destructive"),
469
+ type: "button",
470
+ children: /* @__PURE__ */ _jsx(X, { "aria-hidden": "true" })
471
+ })
472
+ }), /* @__PURE__ */ _jsxs(PopoverContent, {
473
+ align: "start",
474
+ className: "grid w-68 gap-3",
475
+ children: [/* @__PURE__ */ _jsx("p", {
476
+ className: "m-0 text-sm",
477
+ children: resolvedLabels.deleteConfirmation(preset_1.name)
478
+ }), /* @__PURE__ */ _jsxs("div", {
479
+ className: "flex justify-end gap-2",
480
+ children: [/* @__PURE__ */ _jsx(Button, {
481
+ onClick: () => setDeletingPresetName(null),
482
+ size: "sm",
483
+ type: "button",
484
+ variant: "outline",
485
+ children: resolvedLabels.cancel
486
+ }), /* @__PURE__ */ _jsx(Button, {
487
+ onClick: () => {
488
+ setDeletingPresetName(null);
489
+ onDeletePreset(preset_1.name);
490
+ },
491
+ size: "sm",
492
+ type: "button",
493
+ variant: "destructive",
494
+ children: resolvedLabels.delete
495
+ })]
496
+ })]
497
+ })]
498
+ })
499
+ ]
500
+ }, preset_1.name))]
501
+ });
502
+ }
503
+ function _temp(event) {
504
+ const interactionTarget = event.target;
505
+ if (interactionTarget instanceof Element && interactionTarget.closest(NESTED_POPOVER_SELECTOR)) {
506
+ event.preventDefault();
507
+ }
508
+ }
@@ -9,7 +9,6 @@ const PRESENCE_SWAP_ELEMENTS = {
9
9
  div: motion.div,
10
10
  span: motion.span
11
11
  };
12
- const INSTANT_TRANSITION = { duration: 0 };
13
12
  /**
14
13
  * One keyed state of the swap. While it animates out it turns inert and hidden
15
14
  * from assistive technology, so stale controls cannot be clicked or announced.
@@ -17,7 +16,7 @@ const INSTANT_TRANSITION = { duration: 0 };
17
16
  * @returns The animated state.
18
17
  */
19
18
  function PresenceSwapItem(t0) {
20
- const $ = _c(20);
19
+ const $ = _c(14);
21
20
  const { as, className, children } = t0;
22
21
  const MotionElement = PRESENCE_SWAP_ELEMENTS[as];
23
22
  const isPresent = useIsPresent();
@@ -37,78 +36,66 @@ function PresenceSwapItem(t0) {
37
36
  t3 = $[1];
38
37
  }
39
38
  let t4;
40
- if ($[2] !== shouldReduceMotion) {
41
- t4 = shouldReduceMotion ? INSTANT_TRANSITION : {
42
- duration: MOTION_TIMING.enter,
43
- ease: MOTION_EASE
44
- };
45
- $[2] = shouldReduceMotion;
46
- $[3] = t4;
47
- } else {
48
- t4 = $[3];
49
- }
50
- let t5;
51
- if ($[4] !== t4) {
52
- t5 = {
39
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
40
+ t4 = {
53
41
  opacity: 1,
54
42
  y: 0,
55
- transition: t4
43
+ transition: {
44
+ duration: MOTION_TIMING.enter,
45
+ ease: MOTION_EASE
46
+ }
56
47
  };
57
- $[4] = t4;
58
- $[5] = t5;
48
+ $[2] = t4;
59
49
  } else {
60
- t5 = $[5];
50
+ t4 = $[2];
61
51
  }
62
- const t6 = -distance;
63
- let t7;
64
- if ($[6] !== shouldReduceMotion) {
65
- t7 = shouldReduceMotion ? INSTANT_TRANSITION : {
52
+ const t5 = -distance;
53
+ let t6;
54
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
55
+ t6 = {
66
56
  duration: MOTION_TIMING.exit,
67
57
  ease: MOTION_EASE
68
58
  };
69
- $[6] = shouldReduceMotion;
70
- $[7] = t7;
59
+ $[3] = t6;
71
60
  } else {
72
- t7 = $[7];
61
+ t6 = $[3];
73
62
  }
74
- let t8;
75
- if ($[8] !== t6 || $[9] !== t7) {
76
- t8 = {
63
+ let t7;
64
+ if ($[4] !== t5) {
65
+ t7 = {
77
66
  opacity: 0,
78
- y: t6,
79
- transition: t7
67
+ y: t5,
68
+ transition: t6
80
69
  };
81
- $[8] = t6;
82
- $[9] = t7;
83
- $[10] = t8;
70
+ $[4] = t5;
71
+ $[5] = t7;
84
72
  } else {
85
- t8 = $[10];
73
+ t7 = $[5];
86
74
  }
87
- let t9;
88
- if ($[11] !== MotionElement || $[12] !== children || $[13] !== className || $[14] !== t1 || $[15] !== t2 || $[16] !== t3 || $[17] !== t5 || $[18] !== t8) {
89
- t9 = /* @__PURE__ */ _jsx(MotionElement, {
75
+ let t8;
76
+ if ($[6] !== MotionElement || $[7] !== children || $[8] !== className || $[9] !== t1 || $[10] !== t2 || $[11] !== t3 || $[12] !== t7) {
77
+ t8 = /* @__PURE__ */ _jsx(MotionElement, {
90
78
  "data-slot": "presence-swap",
91
79
  "aria-hidden": t1,
92
80
  inert: t2,
93
81
  className,
94
82
  initial: t3,
95
- animate: t5,
96
- exit: t8,
83
+ animate: t4,
84
+ exit: t7,
97
85
  children
98
86
  });
99
- $[11] = MotionElement;
100
- $[12] = children;
101
- $[13] = className;
102
- $[14] = t1;
103
- $[15] = t2;
104
- $[16] = t3;
105
- $[17] = t5;
106
- $[18] = t8;
107
- $[19] = t9;
87
+ $[6] = MotionElement;
88
+ $[7] = children;
89
+ $[8] = className;
90
+ $[9] = t1;
91
+ $[10] = t2;
92
+ $[11] = t3;
93
+ $[12] = t7;
94
+ $[13] = t8;
108
95
  } else {
109
- t9 = $[19];
96
+ t8 = $[13];
110
97
  }
111
- return t9;
98
+ return t8;
112
99
  }
113
100
  /**
114
101
  * Swaps keyed content with a short lift-and-fade; the first render is not animated.
@@ -10,8 +10,13 @@ export interface ReactionButtonProps {
10
10
  count: number;
11
11
  onClick: (event: MouseEvent<HTMLButtonElement>) => void;
12
12
  isDisabled?: boolean;
13
- /** Icon of the reaction. While active it is filled with the destructive color; override it with `[&_svg]:` classes. */
13
+ /** Icon of the reaction; it is filled with `activeColor` while active. */
14
14
  icon?: ComponentType<SVGProps<SVGSVGElement>>;
15
+ /**
16
+ * CSS color of the active icon, such as `var(--primary)` or `currentColor` to follow the
17
+ * button text. Defaults to the destructive color, the usual tone of a like.
18
+ */
19
+ activeColor?: string;
15
20
  /** Formats the visible count, for example with a locale-aware compact format. */
16
21
  formatCount?: (count: number) => string;
17
22
  className?: string;
@@ -23,4 +28,4 @@ export interface ReactionButtonProps {
23
28
  * @param props - Accessible name, state, count, click handler and optional icon.
24
29
  * @returns The reaction button.
25
30
  */
26
- export declare function ReactionButton({ ariaLabel, isActive, count, onClick, isDisabled, icon: Icon, formatCount, className, }: ReactionButtonProps): import("react").JSX.Element;
31
+ export declare function ReactionButton({ ariaLabel, isActive, count, onClick, isDisabled, icon: Icon, formatCount, activeColor, className, }: ReactionButtonProps): import("react").JSX.Element;