beez-ui 2.7.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/README.md +43 -13
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/components/account-menu.d.ts +4 -3
- package/dist/components/account-menu.js +63 -54
- package/dist/components/alert.d.ts +15 -15
- package/dist/components/alert.js +289 -270
- package/dist/components/animated-theme-toggler.js +1 -1
- package/dist/components/avatar.d.ts +56 -31
- package/dist/components/avatar.js +394 -277
- package/dist/components/badge.d.ts +8 -28
- package/dist/components/badge.js +55 -108
- package/dist/components/calendar.d.ts +36 -26
- package/dist/components/calendar.js +132 -1227
- package/dist/components/card.d.ts +36 -25
- package/dist/components/card.js +895 -72
- package/dist/components/carousel.d.ts +63 -47
- package/dist/components/carousel.js +496 -777
- package/dist/components/data-table.d.ts +5 -4
- package/dist/components/data-table.js +7 -6
- package/dist/components/dialog-surface.d.ts +23 -1
- package/dist/components/dialog-surface.js +99 -3
- package/dist/components/dialog.d.ts +80 -45
- package/dist/components/dialog.js +258 -503
- package/dist/components/dropdown-menu.d.ts +56 -73
- package/dist/components/dropdown-menu.js +79 -714
- package/dist/components/field.d.ts +3 -1
- package/dist/components/field.js +49 -39
- package/dist/components/filter-presets-bar.js +2 -2
- package/dist/components/filter-query-bar.js +1 -1
- package/dist/components/hover-card.d.ts +42 -41
- package/dist/components/hover-card.js +57 -483
- package/dist/components/pagination.d.ts +53 -31
- package/dist/components/pagination.js +176 -412
- package/dist/components/popover.d.ts +11 -23
- package/dist/components/popover.js +19 -304
- package/dist/components/{alert-dialog.d.ts → primitives/alert-dialog.d.ts} +17 -5
- package/dist/components/{alert-dialog.js → primitives/alert-dialog.js} +102 -54
- package/dist/components/primitives/avatar.d.ts +46 -0
- package/dist/components/primitives/avatar.js +267 -0
- package/dist/components/primitives/calendar.d.ts +37 -0
- package/dist/components/primitives/calendar.js +1250 -0
- package/dist/components/primitives/carousel.d.ts +106 -0
- package/dist/components/primitives/carousel.js +928 -0
- package/dist/components/primitives/dialog.d.ts +62 -0
- package/dist/components/primitives/dialog.js +490 -0
- package/dist/components/primitives/dropdown-menu-items.d.ts +59 -0
- package/dist/components/primitives/dropdown-menu-items.js +265 -0
- package/dist/components/primitives/dropdown-menu.d.ts +64 -0
- package/dist/components/primitives/dropdown-menu.js +557 -0
- package/dist/components/primitives/hover-card.d.ts +50 -0
- package/dist/components/primitives/hover-card.js +507 -0
- package/dist/components/primitives/pagination.d.ts +65 -0
- package/dist/components/primitives/pagination.js +373 -0
- package/dist/components/primitives/popover.d.ts +22 -0
- package/dist/components/primitives/popover.js +213 -0
- package/dist/components/primitives/select.d.ts +36 -0
- package/dist/components/primitives/select.js +407 -0
- package/dist/components/primitives/tooltip.d.ts +30 -0
- package/dist/components/primitives/tooltip.js +277 -0
- package/dist/components/radio-group.d.ts +30 -17
- package/dist/components/radio-group.js +266 -315
- package/dist/components/rich-link-editor.js +2 -2
- package/dist/components/select.d.ts +51 -42
- package/dist/components/select.js +163 -495
- package/dist/components/skeleton.d.ts +16 -15
- package/dist/components/skeleton.js +99 -205
- package/dist/components/split-button.js +1 -1
- package/dist/components/switch.d.ts +3 -6
- package/dist/components/switch.js +163 -170
- package/dist/components/tabs.d.ts +3 -11
- package/dist/components/tabs.js +61 -75
- package/dist/components/themed-toaster.d.ts +1 -1
- package/dist/components/themed-toaster.js +1 -1
- package/dist/components/toaster.d.ts +1 -1
- package/dist/components/toaster.js +1 -1
- package/dist/components/tooltip.d.ts +36 -31
- package/dist/components/tooltip.js +44 -284
- package/dist/constants/alert.d.ts +5 -1
- package/dist/constants/alert.js +5 -1
- package/dist/constants/avatar.d.ts +24 -1
- package/dist/constants/avatar.js +19 -0
- package/dist/constants/calendar.d.ts +12 -0
- package/dist/constants/calendar.js +12 -0
- package/dist/constants/card.d.ts +23 -0
- package/dist/constants/card.js +20 -0
- package/dist/constants/carousel.d.ts +31 -13
- package/dist/constants/carousel.js +32 -11
- package/dist/constants/dialog.d.ts +6 -1
- package/dist/constants/dialog.js +5 -1
- package/dist/constants/dropdown-menu.d.ts +2 -2
- package/dist/constants/dropdown-menu.js +2 -2
- package/dist/constants/pagination.d.ts +13 -2
- package/dist/constants/pagination.js +13 -2
- package/dist/constants/select.d.ts +4 -2
- package/dist/constants/select.js +4 -2
- package/dist/constants/switch.d.ts +5 -16
- package/dist/constants/switch.js +6 -14
- package/dist/hooks/use-today.d.ts +7 -0
- package/dist/hooks/use-today.js +50 -0
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.js +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/motion/glide-indicator.d.ts +1 -1
- package/dist/motion/glide-indicator.js +1 -1
- package/dist/motion/presence.d.ts +0 -1
- package/dist/motion/presence.js +0 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -6
|
@@ -1,346 +1,463 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { c as _c } from "react/compiler-runtime";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Arc's Avatar and Avatar group (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md). The avatar is a round
|
|
5
|
+
* portrait named once for assistive technology, with the first two initials standing in until the photo loads or when
|
|
6
|
+
* it fails, and a presence dot that pops in and out. The group overlaps several avatars, collapses the rest into a +N
|
|
7
|
+
* chip whose count rolls the way it moved, opens and closes the slot of members who join or leave, and on fine
|
|
8
|
+
* pointers fans apart while the pointed-at person lifts and shows their name.
|
|
9
|
+
*/
|
|
10
|
+
import { useState } from "react";
|
|
11
|
+
import { AnimatePresence, motion, useIsPresent } from "motion/react";
|
|
12
|
+
import { AVATAR_GROUP_COUNT_OFFSET_EM, AVATAR_GROUP_DEFAULT_LABEL, AVATAR_GROUP_DEFAULT_MAX, AVATAR_GROUP_OVERFLOW_SUFFIX, AVATAR_GROUP_SLOT_HIDDEN_SCALE, AVATAR_LABEL_SEPARATOR, AVATAR_SIZE_PX, AVATAR_STATUS_LABEL } from "../constants/avatar.js";
|
|
6
13
|
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
14
|
+
import { getNameInitials } from "../lib/name-initials.js";
|
|
7
15
|
import { cn } from "../lib/utils.js";
|
|
8
|
-
import { ARC_DURATION,
|
|
9
|
-
import {
|
|
10
|
-
import { useBeezUIComponents } from "../providers/beez-ui-provider.js";
|
|
16
|
+
import { ARC_BLUR, ARC_DURATION, ARC_EASE, ARC_SPRING_MORPH } from "../motion/arc-tokens.js";
|
|
17
|
+
import { AvatarBadge, AvatarFallback, AvatarImage, AvatarRoot } from "./primitives/avatar.js";
|
|
11
18
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
-
/** The presence ring: a surface-coloured gap plus a faint hairline, so the dot reads on photos and fills alike. */
|
|
13
|
-
const presenceRingClassName = "shadow-[0_0_0_2px_var(--surface),0_0_0_3px_color-mix(in_oklab,var(--border)_70%,transparent)]";
|
|
14
19
|
/**
|
|
15
|
-
*
|
|
16
|
-
* @param
|
|
17
|
-
* @
|
|
20
|
+
* Builds the avatar's accessible name: the person plus, when shown, their presence.
|
|
21
|
+
* @param name - Text that names the person.
|
|
22
|
+
* @param presence - Presence text, if any.
|
|
23
|
+
* @returns The accessible name.
|
|
24
|
+
*/
|
|
25
|
+
function buildAvatarLabel(name, presence) {
|
|
26
|
+
return presence ? `${name}${AVATAR_LABEL_SEPARATOR}${presence}` : name;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A round portrait for one person, with initials as fallback and an optional presence dot.
|
|
30
|
+
* @param props - Name, photo, size, presence, optional fallback and badge, plus native span attributes for the root.
|
|
31
|
+
* @returns The avatar, announced as one image.
|
|
18
32
|
*/
|
|
19
33
|
function Avatar(t0) {
|
|
20
|
-
const $ = _c(
|
|
21
|
-
let
|
|
22
|
-
let
|
|
34
|
+
const $ = _c(31);
|
|
35
|
+
let alt;
|
|
36
|
+
let badge;
|
|
37
|
+
let fallback;
|
|
38
|
+
let name;
|
|
23
39
|
let props;
|
|
40
|
+
let src;
|
|
24
41
|
let status;
|
|
25
42
|
let statusLabel;
|
|
26
43
|
let t1;
|
|
27
44
|
if ($[0] !== t0) {
|
|
28
|
-
({
|
|
45
|
+
({name, src, size: t1, status, statusLabel, fallback, badge, alt, ...props} = t0);
|
|
29
46
|
$[0] = t0;
|
|
30
|
-
$[1] =
|
|
31
|
-
$[2] =
|
|
32
|
-
$[3] =
|
|
33
|
-
$[4] =
|
|
34
|
-
$[5] =
|
|
35
|
-
$[6] =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
props = $[3];
|
|
40
|
-
status = $[4];
|
|
41
|
-
statusLabel = $[5];
|
|
42
|
-
t1 = $[6];
|
|
43
|
-
}
|
|
44
|
-
const size = t1 === undefined ? "default" : t1;
|
|
45
|
-
const reduceMotion = usePrefersReducedMotion();
|
|
46
|
-
let t2;
|
|
47
|
-
if ($[7] !== className) {
|
|
48
|
-
t2 = cn("group/avatar relative inline-grid size-8 shrink-0 place-items-center rounded-(--radius-pill) border border-border bg-surface-muted text-xs font-medium text-foreground select-none data-[size=lg]:size-10 data-[size=lg]:text-sm data-[size=sm]:size-6 data-[size=sm]:text-[10px] data-[size=xl]:size-22 data-[size=xl]:text-xl", className);
|
|
49
|
-
$[7] = className;
|
|
50
|
-
$[8] = t2;
|
|
47
|
+
$[1] = alt;
|
|
48
|
+
$[2] = badge;
|
|
49
|
+
$[3] = fallback;
|
|
50
|
+
$[4] = name;
|
|
51
|
+
$[5] = props;
|
|
52
|
+
$[6] = src;
|
|
53
|
+
$[7] = status;
|
|
54
|
+
$[8] = statusLabel;
|
|
55
|
+
$[9] = t1;
|
|
51
56
|
} else {
|
|
52
|
-
|
|
57
|
+
alt = $[1];
|
|
58
|
+
badge = $[2];
|
|
59
|
+
fallback = $[3];
|
|
60
|
+
name = $[4];
|
|
61
|
+
props = $[5];
|
|
62
|
+
src = $[6];
|
|
63
|
+
status = $[7];
|
|
64
|
+
statusLabel = $[8];
|
|
65
|
+
t1 = $[9];
|
|
53
66
|
}
|
|
67
|
+
const size = t1 === undefined ? "md" : t1;
|
|
68
|
+
const presence = status ? statusLabel ?? AVATAR_STATUS_LABEL[status] : undefined;
|
|
69
|
+
const t2 = alt ?? name;
|
|
54
70
|
let t3;
|
|
55
|
-
if ($[
|
|
56
|
-
t3 =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
$[9] = status;
|
|
61
|
-
$[10] = statusLabel;
|
|
62
|
-
$[11] = t3;
|
|
71
|
+
if ($[10] !== presence || $[11] !== t2) {
|
|
72
|
+
t3 = buildAvatarLabel(t2, presence);
|
|
73
|
+
$[10] = presence;
|
|
74
|
+
$[11] = t2;
|
|
75
|
+
$[12] = t3;
|
|
63
76
|
} else {
|
|
64
|
-
t3 = $[
|
|
77
|
+
t3 = $[12];
|
|
65
78
|
}
|
|
66
79
|
let t4;
|
|
67
|
-
if ($[
|
|
68
|
-
t4 =
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
opacity: 1,
|
|
79
|
-
scale: 1
|
|
80
|
-
},
|
|
81
|
-
exit: {
|
|
82
|
-
opacity: 0,
|
|
83
|
-
scale: AVATAR_STATUS_HIDDEN_SCALE,
|
|
84
|
-
transition: { duration: reduceMotion ? 0 : ARC_DURATION.fast }
|
|
85
|
-
},
|
|
86
|
-
transition: reduceMotion ? { duration: 0 } : ARC_SPRING_SNAPPY
|
|
87
|
-
}, status) : null;
|
|
88
|
-
$[12] = reduceMotion;
|
|
89
|
-
$[13] = status;
|
|
90
|
-
$[14] = t4;
|
|
80
|
+
if ($[13] !== size || $[14] !== src) {
|
|
81
|
+
t4 = src ? /* @__PURE__ */ _jsx(AvatarImage, {
|
|
82
|
+
src,
|
|
83
|
+
alt: "",
|
|
84
|
+
width: AVATAR_SIZE_PX[size],
|
|
85
|
+
height: AVATAR_SIZE_PX[size],
|
|
86
|
+
sizes: `${AVATAR_SIZE_PX[size]}px`
|
|
87
|
+
}) : null;
|
|
88
|
+
$[13] = size;
|
|
89
|
+
$[14] = src;
|
|
90
|
+
$[15] = t4;
|
|
91
91
|
} else {
|
|
92
|
-
t4 = $[
|
|
92
|
+
t4 = $[15];
|
|
93
93
|
}
|
|
94
94
|
let t5;
|
|
95
|
-
if ($[
|
|
96
|
-
t5 =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
$[15] = t4;
|
|
101
|
-
$[16] = t5;
|
|
95
|
+
if ($[16] !== fallback || $[17] !== name) {
|
|
96
|
+
t5 = fallback ?? getNameInitials(name);
|
|
97
|
+
$[16] = fallback;
|
|
98
|
+
$[17] = name;
|
|
99
|
+
$[18] = t5;
|
|
102
100
|
} else {
|
|
103
|
-
t5 = $[
|
|
101
|
+
t5 = $[18];
|
|
104
102
|
}
|
|
105
103
|
let t6;
|
|
106
|
-
if ($[
|
|
107
|
-
t6 = /* @__PURE__ */ _jsx(
|
|
108
|
-
|
|
109
|
-
children:
|
|
110
|
-
"data-slot": "avatar",
|
|
111
|
-
"data-size": size,
|
|
112
|
-
className: t2,
|
|
113
|
-
...props,
|
|
114
|
-
children: [
|
|
115
|
-
children,
|
|
116
|
-
t3,
|
|
117
|
-
t5
|
|
118
|
-
]
|
|
119
|
-
})
|
|
104
|
+
if ($[19] !== t5) {
|
|
105
|
+
t6 = /* @__PURE__ */ _jsx(AvatarFallback, {
|
|
106
|
+
"aria-hidden": "true",
|
|
107
|
+
children: t5
|
|
120
108
|
});
|
|
121
|
-
$[
|
|
122
|
-
$[
|
|
123
|
-
$[19] = size;
|
|
124
|
-
$[20] = t2;
|
|
125
|
-
$[21] = t3;
|
|
126
|
-
$[22] = t5;
|
|
127
|
-
$[23] = t6;
|
|
109
|
+
$[19] = t5;
|
|
110
|
+
$[20] = t6;
|
|
128
111
|
} else {
|
|
129
|
-
t6 = $[
|
|
112
|
+
t6 = $[20];
|
|
130
113
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
let className;
|
|
137
|
-
let props;
|
|
138
|
-
let src;
|
|
139
|
-
let t1;
|
|
140
|
-
if ($[0] !== t0) {
|
|
141
|
-
({alt: t1, className, src, ...props} = t0);
|
|
142
|
-
$[0] = t0;
|
|
143
|
-
$[1] = className;
|
|
144
|
-
$[2] = props;
|
|
145
|
-
$[3] = src;
|
|
146
|
-
$[4] = t1;
|
|
114
|
+
let t7;
|
|
115
|
+
if ($[21] !== badge) {
|
|
116
|
+
t7 = badge ? /* @__PURE__ */ _jsx(AvatarBadge, { children: badge }) : null;
|
|
117
|
+
$[21] = badge;
|
|
118
|
+
$[22] = t7;
|
|
147
119
|
} else {
|
|
148
|
-
|
|
149
|
-
props = $[2];
|
|
150
|
-
src = $[3];
|
|
151
|
-
t1 = $[4];
|
|
120
|
+
t7 = $[22];
|
|
152
121
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
t4 = cn("pointer-events-none absolute inset-0 aspect-square size-full rounded-full object-cover data-[loading]:opacity-0 data-[error]:hidden", className);
|
|
167
|
-
$[7] = className;
|
|
168
|
-
$[8] = t4;
|
|
169
|
-
} else {
|
|
170
|
-
t4 = $[8];
|
|
171
|
-
}
|
|
172
|
-
const t5 = src ?? undefined;
|
|
173
|
-
let t6;
|
|
174
|
-
if ($[9] !== alt || $[10] !== props || $[11] !== t3 || $[12] !== t4 || $[13] !== t5) {
|
|
175
|
-
t6 = /* @__PURE__ */ _jsx(MotionSlot, {
|
|
176
|
-
kind: "reveal",
|
|
177
|
-
children: /* @__PURE__ */ _jsx(AvatarPrimitive.Image, {
|
|
178
|
-
render: t3,
|
|
179
|
-
keepMounted: true,
|
|
180
|
-
alt,
|
|
181
|
-
"data-slot": "avatar-image",
|
|
182
|
-
className: t4,
|
|
183
|
-
src: t5,
|
|
184
|
-
loading: "lazy",
|
|
185
|
-
decoding: "async",
|
|
186
|
-
...props
|
|
187
|
-
})
|
|
122
|
+
let t8;
|
|
123
|
+
if ($[23] !== props || $[24] !== size || $[25] !== status || $[26] !== t3 || $[27] !== t4 || $[28] !== t6 || $[29] !== t7) {
|
|
124
|
+
t8 = /* @__PURE__ */ _jsxs(AvatarRoot, {
|
|
125
|
+
role: "img",
|
|
126
|
+
"aria-label": t3,
|
|
127
|
+
size,
|
|
128
|
+
status,
|
|
129
|
+
...props,
|
|
130
|
+
children: [
|
|
131
|
+
t4,
|
|
132
|
+
t6,
|
|
133
|
+
t7
|
|
134
|
+
]
|
|
188
135
|
});
|
|
189
|
-
$[
|
|
190
|
-
$[
|
|
191
|
-
$[
|
|
192
|
-
$[
|
|
193
|
-
$[
|
|
194
|
-
$[
|
|
136
|
+
$[23] = props;
|
|
137
|
+
$[24] = size;
|
|
138
|
+
$[25] = status;
|
|
139
|
+
$[26] = t3;
|
|
140
|
+
$[27] = t4;
|
|
141
|
+
$[28] = t6;
|
|
142
|
+
$[29] = t7;
|
|
143
|
+
$[30] = t8;
|
|
195
144
|
} else {
|
|
196
|
-
|
|
145
|
+
t8 = $[30];
|
|
197
146
|
}
|
|
198
|
-
return
|
|
147
|
+
return t8;
|
|
199
148
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
({
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
149
|
+
/** The overflow count rolls the way it moved: more people rise in from below, fewer drop in from above. */
|
|
150
|
+
const countRoll = {
|
|
151
|
+
hidden: (direction) => ({
|
|
152
|
+
opacity: 0,
|
|
153
|
+
y: `${AVATAR_GROUP_COUNT_OFFSET_EM * direction}em`,
|
|
154
|
+
filter: `blur(${ARC_BLUR.subtle}px)`
|
|
155
|
+
}),
|
|
156
|
+
shown: {
|
|
157
|
+
opacity: 1,
|
|
158
|
+
y: 0,
|
|
159
|
+
filter: "blur(0px)",
|
|
160
|
+
transition: {
|
|
161
|
+
duration: ARC_DURATION.standard,
|
|
162
|
+
ease: [...ARC_EASE.enter]
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
gone: (direction) => ({
|
|
166
|
+
opacity: 0,
|
|
167
|
+
y: `${-AVATAR_GROUP_COUNT_OFFSET_EM * direction}em`,
|
|
168
|
+
filter: `blur(${ARC_BLUR.subtle}px)`,
|
|
169
|
+
transition: {
|
|
170
|
+
duration: ARC_DURATION.fast,
|
|
171
|
+
ease: [...ARC_EASE.standard]
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
};
|
|
175
|
+
/** Same keys as `countRoll`, so the settled style is identical whichever branch renders on the server. */
|
|
176
|
+
const countFade = {
|
|
177
|
+
hidden: {
|
|
178
|
+
opacity: 0,
|
|
179
|
+
y: 0,
|
|
180
|
+
filter: "blur(0px)"
|
|
181
|
+
},
|
|
182
|
+
shown: {
|
|
183
|
+
opacity: 1,
|
|
184
|
+
y: 0,
|
|
185
|
+
filter: "blur(0px)",
|
|
186
|
+
transition: { duration: ARC_DURATION.instant }
|
|
187
|
+
},
|
|
188
|
+
gone: {
|
|
189
|
+
opacity: 0,
|
|
190
|
+
y: 0,
|
|
191
|
+
filter: "blur(0px)",
|
|
192
|
+
transition: { duration: ARC_DURATION.instant }
|
|
212
193
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
194
|
+
};
|
|
195
|
+
/** A person joining or leaving opens or closes their slot, so the rest of the stack slides instead of jumping. */
|
|
196
|
+
const slotPresence = {
|
|
197
|
+
initial: {
|
|
198
|
+
width: 0,
|
|
199
|
+
opacity: 0,
|
|
200
|
+
scale: AVATAR_GROUP_SLOT_HIDDEN_SCALE
|
|
201
|
+
},
|
|
202
|
+
animate: {
|
|
203
|
+
width: "auto",
|
|
204
|
+
opacity: 1,
|
|
205
|
+
scale: 1
|
|
206
|
+
},
|
|
207
|
+
exit: {
|
|
208
|
+
width: 0,
|
|
209
|
+
opacity: 0,
|
|
210
|
+
scale: AVATAR_GROUP_SLOT_HIDDEN_SCALE
|
|
220
211
|
}
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* Each slot is the avatar's visible width, so a slot that opens or closes moves the rest of the stack smoothly. On fine
|
|
215
|
+
* pointers it carries the hover moves as custom properties: the whole stack fans out from its center, the pointed-at
|
|
216
|
+
* slot rises above its neighbours and they ease aside.
|
|
217
|
+
*/
|
|
218
|
+
const slotClassName = "group/avatar-group-slot peer/avatar-group-slot relative inline-flex flex-none items-center [--aside:0px] [--fan:0px] [--rise:0px] pointer-fine:group-hover/avatar-group:[--fan:calc((var(--index)-(var(--count)-1)/2)*4px)] hover-fine:z-1 hover-fine:[--rise:-2px] pointer-fine:peer-hover/avatar-group-slot:[--aside:3px] pointer-fine:has-[~[data-slot=avatar-group-slot]:hover]:[--aside:-3px]";
|
|
219
|
+
/** One wrapper per person carries every hover move as a single translate, so the stack never changes size. */
|
|
220
|
+
const liftClassName = "relative -ml-1.5 inline-flex rounded-(--radius-pill) [transform:translate(calc(var(--fan)+var(--aside)),var(--rise))] transition-transform duration-(--duration-standard) ease-(--ease-standard) motion-reduce:transform-none! motion-reduce:transition-none";
|
|
221
|
+
/** The surface ring that separates overlapping avatars, which sharpens on the pointed-at one. */
|
|
222
|
+
const ringClassName = "border-2 border-surface shadow-[0_0_0_1px_var(--border)] transition-shadow duration-(--duration-fast) ease-(--ease-standard) pointer-fine:group-hover/avatar-group-slot:shadow-[0_0_0_1px_var(--border-strong)]";
|
|
223
|
+
/**
|
|
224
|
+
* One slot of the stack. A slot that is closing turns inert and hidden from assistive technology, so a person who left
|
|
225
|
+
* is no longer announced while the exit spring plays.
|
|
226
|
+
* @param props - Motion span props for the slot.
|
|
227
|
+
* @returns The slot.
|
|
228
|
+
*/
|
|
229
|
+
function AvatarGroupSlot(props) {
|
|
230
|
+
const $ = _c(4);
|
|
231
|
+
const isPresent = useIsPresent();
|
|
232
|
+
const t0 = isPresent ? props["aria-hidden"] : true;
|
|
233
|
+
const t1 = !isPresent || undefined;
|
|
221
234
|
let t2;
|
|
222
|
-
if ($[
|
|
223
|
-
t2 = /* @__PURE__ */ _jsx(
|
|
224
|
-
"data-slot": "avatar-
|
|
225
|
-
|
|
226
|
-
|
|
235
|
+
if ($[0] !== props || $[1] !== t0 || $[2] !== t1) {
|
|
236
|
+
t2 = /* @__PURE__ */ _jsx(motion.span, {
|
|
237
|
+
"data-slot": "avatar-group-slot",
|
|
238
|
+
...props,
|
|
239
|
+
"aria-hidden": t0,
|
|
240
|
+
inert: t1
|
|
227
241
|
});
|
|
228
|
-
$[
|
|
229
|
-
$[
|
|
230
|
-
$[
|
|
242
|
+
$[0] = props;
|
|
243
|
+
$[1] = t0;
|
|
244
|
+
$[2] = t1;
|
|
245
|
+
$[3] = t2;
|
|
231
246
|
} else {
|
|
232
|
-
t2 = $[
|
|
247
|
+
t2 = $[3];
|
|
233
248
|
}
|
|
234
249
|
return t2;
|
|
235
250
|
}
|
|
236
|
-
/**
|
|
237
|
-
|
|
238
|
-
|
|
251
|
+
/**
|
|
252
|
+
* Builds the overflow chip's accessible name, as in "2 integrantes más".
|
|
253
|
+
* @param overflow - How many members are hidden.
|
|
254
|
+
* @param label - Accessible name of the group.
|
|
255
|
+
* @returns The chip's accessible name.
|
|
256
|
+
*/
|
|
257
|
+
function buildOverflowLabel(overflow, label) {
|
|
258
|
+
return `${overflow} ${label.toLowerCase()} ${AVATAR_GROUP_OVERFLOW_SUFFIX}`;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* An overlapping stack of avatars with a +N overflow chip.
|
|
262
|
+
* @param props - Members, optional total, how many to show, size, accessible label, classes and native root attributes.
|
|
263
|
+
* @returns The group.
|
|
264
|
+
*/
|
|
265
|
+
function AvatarGroup(t0) {
|
|
266
|
+
const $ = _c(40);
|
|
239
267
|
let className;
|
|
268
|
+
let members;
|
|
240
269
|
let props;
|
|
270
|
+
let style;
|
|
271
|
+
let t1;
|
|
272
|
+
let t2;
|
|
273
|
+
let t3;
|
|
274
|
+
let total;
|
|
241
275
|
if ($[0] !== t0) {
|
|
242
|
-
({className, ...props} = t0);
|
|
276
|
+
({members, total, max: t1, size: t2, label: t3, className, style, ...props} = t0);
|
|
243
277
|
$[0] = t0;
|
|
244
278
|
$[1] = className;
|
|
245
|
-
$[2] =
|
|
279
|
+
$[2] = members;
|
|
280
|
+
$[3] = props;
|
|
281
|
+
$[4] = style;
|
|
282
|
+
$[5] = t1;
|
|
283
|
+
$[6] = t2;
|
|
284
|
+
$[7] = t3;
|
|
285
|
+
$[8] = total;
|
|
246
286
|
} else {
|
|
247
287
|
className = $[1];
|
|
248
|
-
|
|
288
|
+
members = $[2];
|
|
289
|
+
props = $[3];
|
|
290
|
+
style = $[4];
|
|
291
|
+
t1 = $[5];
|
|
292
|
+
t2 = $[6];
|
|
293
|
+
t3 = $[7];
|
|
294
|
+
total = $[8];
|
|
249
295
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
296
|
+
const max = t1 === undefined ? AVATAR_GROUP_DEFAULT_MAX : t1;
|
|
297
|
+
const size = t2 === undefined ? "md" : t2;
|
|
298
|
+
const label = t3 === undefined ? AVATAR_GROUP_DEFAULT_LABEL : t3;
|
|
299
|
+
const reduceMotion = usePrefersReducedMotion();
|
|
300
|
+
const visibleMembers = members.slice(0, Math.max(0, max));
|
|
301
|
+
const memberCount = Math.max(members.length, total ?? 0);
|
|
302
|
+
const overflow = Math.max(0, memberCount - visibleMembers.length);
|
|
303
|
+
let t4;
|
|
304
|
+
if ($[9] !== reduceMotion) {
|
|
305
|
+
t4 = reduceMotion ? { duration: 0 } : ARC_SPRING_MORPH;
|
|
306
|
+
$[9] = reduceMotion;
|
|
307
|
+
$[10] = t4;
|
|
255
308
|
} else {
|
|
256
|
-
|
|
309
|
+
t4 = $[10];
|
|
257
310
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
$[
|
|
266
|
-
$[
|
|
267
|
-
$[7] = t2;
|
|
311
|
+
const slotTransition = t4;
|
|
312
|
+
let t5;
|
|
313
|
+
if ($[11] !== overflow) {
|
|
314
|
+
t5 = {
|
|
315
|
+
overflow,
|
|
316
|
+
direction: 1
|
|
317
|
+
};
|
|
318
|
+
$[11] = overflow;
|
|
319
|
+
$[12] = t5;
|
|
268
320
|
} else {
|
|
269
|
-
|
|
321
|
+
t5 = $[12];
|
|
270
322
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
323
|
+
const [shownCount, setShownCount] = useState(t5);
|
|
324
|
+
if (shownCount.overflow !== overflow) {
|
|
325
|
+
setShownCount({
|
|
326
|
+
overflow,
|
|
327
|
+
direction: overflow < shownCount.overflow ? -1 : 1
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
const t6 = visibleMembers.length + (overflow > 0 ? 1 : 0);
|
|
331
|
+
let t7;
|
|
332
|
+
if ($[13] !== style || $[14] !== t6) {
|
|
333
|
+
t7 = {
|
|
334
|
+
...style,
|
|
335
|
+
"--count": t6
|
|
336
|
+
};
|
|
337
|
+
$[13] = style;
|
|
338
|
+
$[14] = t6;
|
|
339
|
+
$[15] = t7;
|
|
283
340
|
} else {
|
|
284
|
-
|
|
285
|
-
props = $[2];
|
|
341
|
+
t7 = $[15];
|
|
286
342
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
343
|
+
const groupStyle = t7;
|
|
344
|
+
const t8 = "group";
|
|
345
|
+
const t9 = "avatar-group";
|
|
346
|
+
let t10;
|
|
347
|
+
if ($[16] !== className) {
|
|
348
|
+
t10 = cn("group/avatar-group inline-flex items-center pl-1.5", className);
|
|
349
|
+
$[16] = className;
|
|
350
|
+
$[17] = t10;
|
|
292
351
|
} else {
|
|
293
|
-
|
|
352
|
+
t10 = $[17];
|
|
294
353
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
354
|
+
const T0 = AnimatePresence;
|
|
355
|
+
const t11 = false;
|
|
356
|
+
let t12;
|
|
357
|
+
if ($[18] !== size || $[19] !== slotTransition) {
|
|
358
|
+
t12 = (member, index) => /* @__PURE__ */ _jsx(AvatarGroupSlot, {
|
|
359
|
+
className: slotClassName,
|
|
360
|
+
style: { "--index": index },
|
|
361
|
+
...slotPresence,
|
|
362
|
+
transition: slotTransition,
|
|
363
|
+
children: /* @__PURE__ */ _jsxs("span", {
|
|
364
|
+
className: liftClassName,
|
|
365
|
+
children: [/* @__PURE__ */ _jsx(Avatar, {
|
|
366
|
+
className: ringClassName,
|
|
367
|
+
name: member.name,
|
|
368
|
+
src: member.src,
|
|
369
|
+
status: member.status,
|
|
370
|
+
size
|
|
371
|
+
}), /* @__PURE__ */ _jsx("span", {
|
|
372
|
+
"aria-hidden": "true",
|
|
373
|
+
className: "pointer-events-none absolute bottom-[calc(100%+8px)] left-1/2 z-2 -translate-x-1/2 translate-y-[3px] rounded-(--radius-pill) bg-foreground px-2 py-1 text-xs leading-(--leading-body) font-medium whitespace-nowrap text-background opacity-0 transition-[opacity,translate] duration-(--duration-fast) ease-(--ease-standard) pointer-fine:group-hover/avatar-group-slot:translate-y-0 pointer-fine:group-hover/avatar-group-slot:opacity-100 pointer-fine:group-hover/avatar-group-slot:delay-60 motion-reduce:translate-y-0 motion-reduce:transition-none",
|
|
374
|
+
children: member.name
|
|
375
|
+
})]
|
|
376
|
+
})
|
|
377
|
+
}, member.key ?? member.name);
|
|
378
|
+
$[18] = size;
|
|
379
|
+
$[19] = slotTransition;
|
|
380
|
+
$[20] = t12;
|
|
305
381
|
} else {
|
|
306
|
-
|
|
382
|
+
t12 = $[20];
|
|
307
383
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
384
|
+
const t13 = visibleMembers.map(t12);
|
|
385
|
+
let t14;
|
|
386
|
+
if ($[21] !== label || $[22] !== overflow || $[23] !== reduceMotion || $[24] !== shownCount.direction || $[25] !== size || $[26] !== slotTransition || $[27] !== visibleMembers) {
|
|
387
|
+
t14 = overflow > 0 ? /* @__PURE__ */ _jsx(AvatarGroupSlot, {
|
|
388
|
+
className: slotClassName,
|
|
389
|
+
style: { "--index": visibleMembers.length },
|
|
390
|
+
...slotPresence,
|
|
391
|
+
transition: slotTransition,
|
|
392
|
+
children: /* @__PURE__ */ _jsx("span", {
|
|
393
|
+
role: "img",
|
|
394
|
+
"aria-label": buildOverflowLabel(overflow, label),
|
|
395
|
+
"data-slot": "avatar-group-count",
|
|
396
|
+
"data-size": size,
|
|
397
|
+
className: cn(liftClassName, ringClassName, "relative grid size-8 place-items-center overflow-hidden bg-surface-muted text-xs font-medium text-text-secondary tabular-nums data-[size=lg]:size-10 data-[size=lg]:text-sm data-[size=sm]:size-6 data-[size=sm]:text-[10px]"),
|
|
398
|
+
children: /* @__PURE__ */ _jsx(AnimatePresence, {
|
|
399
|
+
mode: "popLayout",
|
|
400
|
+
initial: false,
|
|
401
|
+
custom: shownCount.direction,
|
|
402
|
+
children: /* @__PURE__ */ _jsxs(motion.span, {
|
|
403
|
+
"aria-hidden": "true",
|
|
404
|
+
className: "inline-block",
|
|
405
|
+
custom: shownCount.direction,
|
|
406
|
+
variants: reduceMotion ? countFade : countRoll,
|
|
407
|
+
initial: "hidden",
|
|
408
|
+
animate: "shown",
|
|
409
|
+
exit: "gone",
|
|
410
|
+
children: ["+", overflow]
|
|
411
|
+
}, overflow)
|
|
412
|
+
})
|
|
413
|
+
})
|
|
414
|
+
}, "overflow") : null;
|
|
415
|
+
$[21] = label;
|
|
416
|
+
$[22] = overflow;
|
|
417
|
+
$[23] = reduceMotion;
|
|
418
|
+
$[24] = shownCount.direction;
|
|
419
|
+
$[25] = size;
|
|
420
|
+
$[26] = slotTransition;
|
|
421
|
+
$[27] = visibleMembers;
|
|
422
|
+
$[28] = t14;
|
|
319
423
|
} else {
|
|
320
|
-
|
|
321
|
-
props = $[2];
|
|
424
|
+
t14 = $[28];
|
|
322
425
|
}
|
|
323
|
-
let
|
|
324
|
-
if ($[
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
426
|
+
let t15;
|
|
427
|
+
if ($[29] !== T0 || $[30] !== t13 || $[31] !== t14) {
|
|
428
|
+
t15 = /* @__PURE__ */ _jsxs(T0, {
|
|
429
|
+
initial: t11,
|
|
430
|
+
children: [t13, t14]
|
|
431
|
+
});
|
|
432
|
+
$[29] = T0;
|
|
433
|
+
$[30] = t13;
|
|
434
|
+
$[31] = t14;
|
|
435
|
+
$[32] = t15;
|
|
328
436
|
} else {
|
|
329
|
-
|
|
437
|
+
t15 = $[32];
|
|
330
438
|
}
|
|
331
|
-
let
|
|
332
|
-
if ($[
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
439
|
+
let t16;
|
|
440
|
+
if ($[33] !== groupStyle || $[34] !== label || $[35] !== props || $[36] !== size || $[37] !== t10 || $[38] !== t15) {
|
|
441
|
+
t16 = /* @__PURE__ */ _jsx("div", {
|
|
442
|
+
...props,
|
|
443
|
+
role: t8,
|
|
444
|
+
"aria-label": label,
|
|
445
|
+
"data-slot": t9,
|
|
446
|
+
"data-size": size,
|
|
447
|
+
className: t10,
|
|
448
|
+
style: groupStyle,
|
|
449
|
+
children: t15
|
|
337
450
|
});
|
|
338
|
-
$[
|
|
339
|
-
$[
|
|
340
|
-
$[
|
|
451
|
+
$[33] = groupStyle;
|
|
452
|
+
$[34] = label;
|
|
453
|
+
$[35] = props;
|
|
454
|
+
$[36] = size;
|
|
455
|
+
$[37] = t10;
|
|
456
|
+
$[38] = t15;
|
|
457
|
+
$[39] = t16;
|
|
341
458
|
} else {
|
|
342
|
-
|
|
459
|
+
t16 = $[39];
|
|
343
460
|
}
|
|
344
|
-
return
|
|
461
|
+
return t16;
|
|
345
462
|
}
|
|
346
|
-
export { Avatar,
|
|
463
|
+
export { Avatar, AvatarGroup };
|