@mieweb/ui 0.11.0-dev.36 → 0.11.0-dev.38
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/agent/README.md +1 -1
- package/agent/agents/mieweb-ui-design.agent.md +12 -7
- package/agent/agents/mieweb-ui-migration.agent.md +144 -0
- package/agent/skills/mieweb-ui-catalog/SKILL.md +8 -6
- package/agent/skills/mieweb-ui-catalog/selection-guidance.md +9 -5
- package/dist/{chunk-TUYWCUKH.js → chunk-4LKAZW2W.js} +7 -3
- package/dist/chunk-4LKAZW2W.js.map +1 -0
- package/dist/{chunk-MNXIN4MS.js → chunk-5WA6IYZD.js} +60 -2
- package/dist/chunk-5WA6IYZD.js.map +1 -0
- package/dist/{chunk-DT3X3RBM.js → chunk-7U7SONM5.js} +3 -3
- package/dist/{chunk-DT3X3RBM.js.map → chunk-7U7SONM5.js.map} +1 -1
- package/dist/{chunk-OGFSFUIX.cjs → chunk-AHYDJN4H.cjs} +501 -120
- package/dist/chunk-AHYDJN4H.cjs.map +1 -0
- package/dist/{chunk-C4GEPUE7.js → chunk-CKECOCYJ.js} +2 -2
- package/dist/{chunk-C4GEPUE7.js.map → chunk-CKECOCYJ.js.map} +1 -1
- package/dist/{chunk-V5VPECJI.js → chunk-CRR7AE5D.js} +11 -7
- package/dist/chunk-CRR7AE5D.js.map +1 -0
- package/dist/chunk-D3FNZMOB.cjs +4 -0
- package/dist/{chunk-GLXTVCHN.cjs.map → chunk-D3FNZMOB.cjs.map} +1 -1
- package/dist/{chunk-ZK2R6UGF.cjs → chunk-DCV34MEF.cjs} +4 -4
- package/dist/{chunk-ZK2R6UGF.cjs.map → chunk-DCV34MEF.cjs.map} +1 -1
- package/dist/chunk-G4VQEQGW.js +3 -0
- package/dist/{chunk-RISZWWEQ.js.map → chunk-G4VQEQGW.js.map} +1 -1
- package/dist/{chunk-S3LTUSO5.cjs → chunk-GG3IK5TL.cjs} +7 -7
- package/dist/{chunk-S3LTUSO5.cjs.map → chunk-GG3IK5TL.cjs.map} +1 -1
- package/dist/{chunk-QHCAWDMG.cjs → chunk-HDZQLTBP.cjs} +7 -3
- package/dist/chunk-HDZQLTBP.cjs.map +1 -0
- package/dist/chunk-JCIQIR5V.js +546 -0
- package/dist/chunk-JCIQIR5V.js.map +1 -0
- package/dist/{chunk-AIO2GCTL.js → chunk-JUY2JLFL.js} +501 -120
- package/dist/chunk-JUY2JLFL.js.map +1 -0
- package/dist/{chunk-2S76TRBJ.cjs → chunk-JUYBJLPI.cjs} +4 -4
- package/dist/{chunk-2S76TRBJ.cjs.map → chunk-JUYBJLPI.cjs.map} +1 -1
- package/dist/{chunk-UDUYZDTA.js → chunk-JWMMWNTT.js} +3 -3
- package/dist/{chunk-UDUYZDTA.js.map → chunk-JWMMWNTT.js.map} +1 -1
- package/dist/{chunk-RM4CBS7Y.js → chunk-LQ22CY7X.js} +4 -4
- package/dist/{chunk-RM4CBS7Y.js.map → chunk-LQ22CY7X.js.map} +1 -1
- package/dist/{chunk-AKMTPCLC.cjs → chunk-LTCHD3K5.cjs} +2 -2
- package/dist/{chunk-AKMTPCLC.cjs.map → chunk-LTCHD3K5.cjs.map} +1 -1
- package/dist/{chunk-GDKOYVX3.cjs → chunk-NZUQL42A.cjs} +11 -7
- package/dist/chunk-NZUQL42A.cjs.map +1 -0
- package/dist/chunk-QAEAC7HO.cjs +4 -0
- package/dist/chunk-QAEAC7HO.cjs.map +1 -0
- package/dist/chunk-SCGXD334.js +3 -0
- package/dist/chunk-SCGXD334.js.map +1 -0
- package/dist/chunk-TZKBW4GA.cjs +578 -0
- package/dist/chunk-TZKBW4GA.cjs.map +1 -0
- package/dist/{chunk-47AOS5EC.cjs → chunk-XX6PNPF2.cjs} +60 -2
- package/dist/chunk-XX6PNPF2.cjs.map +1 -0
- package/dist/components/AudioPlayer/index.cjs +7 -6
- package/dist/components/AudioPlayer/index.js +2 -1
- package/dist/components/MediaEditor/index.cjs +10 -9
- package/dist/components/MediaEditor/index.js +5 -4
- package/dist/components/MediaFeed/index.cjs +8 -5
- package/dist/components/MediaFeed/index.d.cts +33 -0
- package/dist/components/MediaFeed/index.d.ts +33 -0
- package/dist/components/MediaFeed/index.js +7 -4
- package/dist/components/MediaPlayer/index.cjs +13 -6
- package/dist/components/MediaPlayer/index.d.cts +103 -5
- package/dist/components/MediaPlayer/index.d.ts +103 -5
- package/dist/components/MediaPlayer/index.js +6 -3
- package/dist/components/Slider/index.cjs +5 -5
- package/dist/components/Slider/index.d.cts +6 -0
- package/dist/components/Slider/index.d.ts +6 -0
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/SliderCalculator/index.cjs +4 -4
- package/dist/components/SliderCalculator/index.js +2 -2
- package/dist/components/SuperChat/index.cjs +16 -14
- package/dist/components/SuperChat/index.cjs.map +1 -1
- package/dist/components/SuperChat/index.d.cts +2 -2
- package/dist/components/SuperChat/index.d.ts +2 -2
- package/dist/components/SuperChat/index.js +8 -6
- package/dist/components/SuperChat/index.js.map +1 -1
- package/dist/components/SuperChat/plugins/index.d.cts +2 -2
- package/dist/components/SuperChat/plugins/index.d.ts +2 -2
- package/dist/hooks/index.cjs +2 -2
- package/dist/hooks/index.js +1 -1
- package/dist/index.cjs +73 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +187 -90
- package/dist/index.d.ts +187 -90
- package/dist/index.js +14 -13
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/{types-DSWbrVkM.d.cts → types-BfVolads.d.cts} +33 -0
- package/dist/{types-DSWbrVkM.d.ts → types-BfVolads.d.ts} +33 -0
- package/package.json +1 -1
- package/dist/chunk-47AOS5EC.cjs.map +0 -1
- package/dist/chunk-AIO2GCTL.js.map +0 -1
- package/dist/chunk-ECKIFQSD.cjs +0 -183
- package/dist/chunk-ECKIFQSD.cjs.map +0 -1
- package/dist/chunk-GDKOYVX3.cjs.map +0 -1
- package/dist/chunk-GLXTVCHN.cjs +0 -4
- package/dist/chunk-MNXIN4MS.js.map +0 -1
- package/dist/chunk-OGFSFUIX.cjs.map +0 -1
- package/dist/chunk-QHCAWDMG.cjs.map +0 -1
- package/dist/chunk-R5P7NAJQ.js +0 -159
- package/dist/chunk-R5P7NAJQ.js.map +0 -1
- package/dist/chunk-RISZWWEQ.js +0 -3
- package/dist/chunk-TUYWCUKH.js.map +0 -1
- package/dist/chunk-V5VPECJI.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MediaPlayer } from './chunk-
|
|
1
|
+
import { defaultMediaControlsLabels, overlayButtonClass, isInPictureInPicture, exitPictureInPicture, PIP_EVENTS, MediaPlayer, playBadgeIconClass, playBadgeClass } from './chunk-JCIQIR5V.js';
|
|
2
2
|
import { Avatar } from './chunk-TI3TQQ7F.js';
|
|
3
3
|
import { Modal, ModalHeader, ModalTitle, ModalClose } from './chunk-GKMMDKYY.js';
|
|
4
4
|
import { usePrefersReducedMotion } from './chunk-XDU65GLW.js';
|
|
@@ -39,7 +39,8 @@ function NativeFeedMedia({
|
|
|
39
39
|
labels,
|
|
40
40
|
onActivate,
|
|
41
41
|
playbackPosition,
|
|
42
|
-
playbackRequestId
|
|
42
|
+
playbackRequestId,
|
|
43
|
+
overlay
|
|
43
44
|
}) {
|
|
44
45
|
const mediaElementRef = React2.useRef(null);
|
|
45
46
|
const [state, setState] = React2.useState("idle");
|
|
@@ -55,24 +56,29 @@ function NativeFeedMedia({
|
|
|
55
56
|
const attemptId = React2.useRef(0);
|
|
56
57
|
const activeRef = React2.useRef(active);
|
|
57
58
|
const canSavePosition = React2.useRef(false);
|
|
59
|
+
const autoAttempt = React2.useRef(null);
|
|
58
60
|
activeRef.current = active;
|
|
59
|
-
const tryPlay = React2.useCallback(async () => {
|
|
61
|
+
const tryPlay = React2.useCallback(async (automatic = false) => {
|
|
60
62
|
const element = mediaElementRef.current;
|
|
61
63
|
if (!element || !activeRef.current) return;
|
|
62
64
|
const attempt = ++attemptId.current;
|
|
63
65
|
setBlocked(false);
|
|
66
|
+
autoAttempt.current = automatic ? attempt : null;
|
|
64
67
|
try {
|
|
65
68
|
await element.play();
|
|
66
|
-
if (!activeRef.current || element !== mediaElementRef.current)
|
|
69
|
+
if ((!activeRef.current || element !== mediaElementRef.current) && !isInPictureInPicture(element))
|
|
67
70
|
element.pause();
|
|
68
71
|
} catch (error) {
|
|
69
72
|
if (!activeRef.current || attempt !== attemptId.current) return;
|
|
70
73
|
if (error instanceof Error && error.name === "AbortError") return;
|
|
71
74
|
setBlocked(true);
|
|
75
|
+
} finally {
|
|
76
|
+
if (autoAttempt.current === attempt) autoAttempt.current = null;
|
|
72
77
|
}
|
|
73
78
|
}, []);
|
|
74
79
|
const pauseForOwnership = React2.useCallback(
|
|
75
80
|
(element) => {
|
|
81
|
+
if (isInPictureInPicture(element)) return;
|
|
76
82
|
if (element && element === mediaElementRef.current && !element.paused)
|
|
77
83
|
ownershipPause.current = true;
|
|
78
84
|
element?.pause();
|
|
@@ -95,9 +101,13 @@ function NativeFeedMedia({
|
|
|
95
101
|
else element.addEventListener("loadedmetadata", restorePosition);
|
|
96
102
|
}
|
|
97
103
|
if (active && (latestPlaybackRequest.current === void 0 || latestPlaybackRequest.current === handledPlaybackRequest.current) && (autoPlay || wantsPlayback.current)) {
|
|
98
|
-
void tryPlay();
|
|
104
|
+
void tryPlay(!wantsPlayback.current);
|
|
99
105
|
} else if (!active) {
|
|
100
106
|
attemptId.current++;
|
|
107
|
+
const fullscreen = document.fullscreenElement;
|
|
108
|
+
if (element && fullscreen && (fullscreen === element || fullscreen === element.closest('[data-slot="media-player-box"]')))
|
|
109
|
+
void document.exitFullscreen?.()?.catch(() => {
|
|
110
|
+
});
|
|
101
111
|
pauseForOwnership(element);
|
|
102
112
|
setBlocked(false);
|
|
103
113
|
}
|
|
@@ -116,6 +126,17 @@ function NativeFeedMedia({
|
|
|
116
126
|
retryVersion,
|
|
117
127
|
tryPlay
|
|
118
128
|
]);
|
|
129
|
+
React2.useEffect(() => {
|
|
130
|
+
const element = mediaElementRef.current;
|
|
131
|
+
if (!element) return;
|
|
132
|
+
const landed = () => {
|
|
133
|
+
if (!activeRef.current && !isInPictureInPicture(element)) element.pause();
|
|
134
|
+
};
|
|
135
|
+
for (const name of PIP_EVENTS) element.addEventListener(name, landed);
|
|
136
|
+
return () => {
|
|
137
|
+
for (const name of PIP_EVENTS) element.removeEventListener(name, landed);
|
|
138
|
+
};
|
|
139
|
+
}, [retryVersion]);
|
|
119
140
|
React2.useEffect(() => {
|
|
120
141
|
if (!active || playbackRequestId === void 0 || playbackRequestId === handledPlaybackRequest.current)
|
|
121
142
|
return;
|
|
@@ -136,64 +157,126 @@ function NativeFeedMedia({
|
|
|
136
157
|
if (active) void tryPlay();
|
|
137
158
|
}
|
|
138
159
|
};
|
|
139
|
-
return /* @__PURE__ */ jsxs(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
return /* @__PURE__ */ jsxs(
|
|
161
|
+
"div",
|
|
162
|
+
{
|
|
163
|
+
className: cn(
|
|
164
|
+
"flex h-full min-h-0 w-full flex-col items-center justify-center",
|
|
165
|
+
overlay ? "relative" : "gap-3"
|
|
166
|
+
),
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ jsx(
|
|
169
|
+
MediaPlayer,
|
|
170
|
+
{
|
|
171
|
+
src: media.src,
|
|
172
|
+
kind: media.kind === "audio" ? "audio" : "video",
|
|
173
|
+
mediaElementRef,
|
|
174
|
+
muted,
|
|
175
|
+
loop,
|
|
176
|
+
poster: media.poster,
|
|
177
|
+
preload: active ? "metadata" : "none",
|
|
178
|
+
controls: active,
|
|
179
|
+
controlsStyle: overlay ? "overlay" : "native",
|
|
180
|
+
"aria-label": title,
|
|
181
|
+
onStateChange: (next) => {
|
|
182
|
+
setState(next);
|
|
183
|
+
if (next === "playing") {
|
|
184
|
+
ownershipPause.current = false;
|
|
185
|
+
setBlocked(false);
|
|
186
|
+
if ((activeRef.current || isInPictureInPicture(mediaElementRef.current)) && autoAttempt.current !== attemptId.current) {
|
|
187
|
+
wantsPlayback.current = true;
|
|
188
|
+
playbackPosition.playRequested = true;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (next === "paused") {
|
|
192
|
+
if ((activeRef.current || isInPictureInPicture(mediaElementRef.current)) && !ownershipPause.current) {
|
|
193
|
+
wantsPlayback.current = false;
|
|
194
|
+
playbackPosition.playRequested = false;
|
|
195
|
+
}
|
|
196
|
+
ownershipPause.current = false;
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
onTimeUpdate: (timeMs) => {
|
|
200
|
+
if (canSavePosition.current) playbackPosition.timeMs = timeMs;
|
|
201
|
+
},
|
|
202
|
+
onRetry: () => {
|
|
203
|
+
ownershipPause.current = false;
|
|
204
|
+
canSavePosition.current = false;
|
|
205
|
+
setState("idle");
|
|
206
|
+
setBlocked(false);
|
|
207
|
+
setRetryVersion((version) => version + 1);
|
|
208
|
+
},
|
|
209
|
+
labels: {
|
|
210
|
+
error: labels.mediaError,
|
|
211
|
+
retry: labels.retry,
|
|
212
|
+
play: labels.play,
|
|
213
|
+
pause: labels.pause,
|
|
214
|
+
mute: labels.mute,
|
|
215
|
+
unmute: labels.unmute,
|
|
216
|
+
seek: labels.seek,
|
|
217
|
+
fullscreen: labels.playerFullscreen,
|
|
218
|
+
exitFullscreen: labels.exitPlayerFullscreen,
|
|
219
|
+
pictureInPicture: labels.pictureInPicture,
|
|
220
|
+
exitPictureInPicture: labels.exitPictureInPicture,
|
|
221
|
+
time: labels.time,
|
|
222
|
+
rate: labels.playerRate,
|
|
223
|
+
speed: labels.playerSpeed,
|
|
224
|
+
showCaptions: labels.showCaptions,
|
|
225
|
+
hideCaptions: labels.hideCaptions
|
|
226
|
+
},
|
|
227
|
+
className: "min-h-0 flex-1 [&_video]:h-full [&_video]:w-full"
|
|
228
|
+
}
|
|
229
|
+
),
|
|
230
|
+
overlay ? (
|
|
231
|
+
// An item that isn't the active one has no controls yet: its ▶
|
|
232
|
+
// selects it and starts it.
|
|
233
|
+
!active && state !== "error" && state !== "playing" && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
234
|
+
Button,
|
|
235
|
+
{
|
|
236
|
+
type: "button",
|
|
237
|
+
variant: "ghost",
|
|
238
|
+
size: "icon",
|
|
239
|
+
"aria-label": labels.play,
|
|
240
|
+
title: labels.play,
|
|
241
|
+
className: cn(
|
|
242
|
+
overlayButtonClass,
|
|
243
|
+
playBadgeClass,
|
|
244
|
+
"pointer-events-auto pointer-fine:h-14 pointer-fine:w-14"
|
|
245
|
+
),
|
|
246
|
+
onClick: togglePlayback,
|
|
247
|
+
children: /* @__PURE__ */ jsx(Play, { className: playBadgeIconClass, "aria-hidden": "true" })
|
|
159
248
|
}
|
|
160
|
-
|
|
249
|
+
) })
|
|
250
|
+
) : state !== "error" && /* @__PURE__ */ jsx(
|
|
251
|
+
Button,
|
|
252
|
+
{
|
|
253
|
+
type: "button",
|
|
254
|
+
variant: "secondary",
|
|
255
|
+
size: "sm",
|
|
256
|
+
leftIcon: state === "playing" ? /* @__PURE__ */ jsx(Pause, { className: "h-4 w-4", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Play, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
257
|
+
onClick: togglePlayback,
|
|
258
|
+
children: state === "playing" ? labels.pause : labels.play
|
|
161
259
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
leftIcon: state === "playing" ? /* @__PURE__ */ jsx(Pause, { className: "h-4 w-4", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Play, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
183
|
-
onClick: togglePlayback,
|
|
184
|
-
children: state === "playing" ? labels.pause : labels.play
|
|
185
|
-
}
|
|
186
|
-
),
|
|
187
|
-
blocked && /* @__PURE__ */ jsx(
|
|
188
|
-
"p",
|
|
189
|
-
{
|
|
190
|
-
role: "status",
|
|
191
|
-
className: "text-muted-foreground m-0 text-center text-sm",
|
|
192
|
-
children: labels.blockedAutoplay
|
|
193
|
-
}
|
|
194
|
-
),
|
|
195
|
-
state === "error" && /* @__PURE__ */ jsx(SourceLink, { src: media.src, labels })
|
|
196
|
-
] });
|
|
260
|
+
),
|
|
261
|
+
blocked && state !== "playing" && /* @__PURE__ */ jsx(
|
|
262
|
+
"p",
|
|
263
|
+
{
|
|
264
|
+
role: "status",
|
|
265
|
+
className: cn(
|
|
266
|
+
"m-0 text-center text-sm",
|
|
267
|
+
overlay ? (
|
|
268
|
+
// Along the top, clear of the details and actions at the foot
|
|
269
|
+
// and of a host's Back button in the top corner.
|
|
270
|
+
"pointer-events-none absolute inset-x-0 top-3 flex justify-center px-14"
|
|
271
|
+
) : "text-muted-foreground"
|
|
272
|
+
),
|
|
273
|
+
children: overlay ? /* @__PURE__ */ jsx("span", { className: "rounded bg-black/60 px-2 py-1 text-white", children: labels.blockedAutoplay }) : labels.blockedAutoplay
|
|
274
|
+
}
|
|
275
|
+
),
|
|
276
|
+
state === "error" && /* @__PURE__ */ jsx(SourceLink, { src: media.src, labels })
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
);
|
|
197
280
|
}
|
|
198
281
|
function ImageFeedMedia({ media, title, labels }) {
|
|
199
282
|
const [failed, setFailed] = React2.useState(false);
|
|
@@ -298,6 +381,7 @@ function YouTubeFeedMedia({
|
|
|
298
381
|
id && !failed ? /* @__PURE__ */ jsx(
|
|
299
382
|
Button,
|
|
300
383
|
{
|
|
384
|
+
type: "button",
|
|
301
385
|
variant: "secondary",
|
|
302
386
|
leftIcon: /* @__PURE__ */ jsx(Play, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
303
387
|
onClick: () => {
|
|
@@ -335,6 +419,21 @@ var defaultLabels = {
|
|
|
335
419
|
next: "Next item",
|
|
336
420
|
play: "Play",
|
|
337
421
|
pause: "Pause",
|
|
422
|
+
// The player's own controls, in the overlay layout.
|
|
423
|
+
mute: defaultMediaControlsLabels.mute,
|
|
424
|
+
unmute: defaultMediaControlsLabels.unmute,
|
|
425
|
+
seek: defaultMediaControlsLabels.seek,
|
|
426
|
+
playerFullscreen: defaultMediaControlsLabels.fullscreen,
|
|
427
|
+
exitPlayerFullscreen: defaultMediaControlsLabels.exitFullscreen,
|
|
428
|
+
pictureInPicture: defaultMediaControlsLabels.pictureInPicture,
|
|
429
|
+
exitPictureInPicture: defaultMediaControlsLabels.exitPictureInPicture,
|
|
430
|
+
time: defaultMediaControlsLabels.time,
|
|
431
|
+
playerRate: defaultMediaControlsLabels.rate,
|
|
432
|
+
playerSpeed: defaultMediaControlsLabels.speed,
|
|
433
|
+
showCaptions: defaultMediaControlsLabels.showCaptions,
|
|
434
|
+
hideCaptions: defaultMediaControlsLabels.hideCaptions,
|
|
435
|
+
showMore: "Show more",
|
|
436
|
+
showLess: "Show less",
|
|
338
437
|
blockedAutoplay: "Playback did not start. Press Play to try again.",
|
|
339
438
|
mediaError: "This media is unavailable.",
|
|
340
439
|
openSource: "Open source",
|
|
@@ -342,6 +441,181 @@ var defaultLabels = {
|
|
|
342
441
|
item: (position, total) => `Media item ${position} of ${total}`,
|
|
343
442
|
position: (position, total) => `${position} / ${total}`
|
|
344
443
|
};
|
|
444
|
+
var OVERLAY_BAR_SCRIM = "[&_[data-slot=media-controls-bar]]:bg-none [&_[data-slot=media-controls-bar]]:bg-black/55";
|
|
445
|
+
function useControlsBarHeight(ref) {
|
|
446
|
+
const [height, setHeight] = React2.useState(0);
|
|
447
|
+
React2.useLayoutEffect(() => {
|
|
448
|
+
const item = ref.current?.closest('[data-slot="item"]');
|
|
449
|
+
if (!item) return;
|
|
450
|
+
let bar = null;
|
|
451
|
+
const resize = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(
|
|
452
|
+
() => setHeight(bar?.getBoundingClientRect().height ?? 0)
|
|
453
|
+
);
|
|
454
|
+
const attach = () => {
|
|
455
|
+
const next = item.querySelector('[data-slot="media-controls-bar"]');
|
|
456
|
+
if (next === bar) return;
|
|
457
|
+
if (bar) resize?.unobserve(bar);
|
|
458
|
+
bar = next;
|
|
459
|
+
if (bar) resize?.observe(bar);
|
|
460
|
+
setHeight(bar?.getBoundingClientRect().height ?? 0);
|
|
461
|
+
};
|
|
462
|
+
attach();
|
|
463
|
+
const mutations = typeof MutationObserver === "undefined" ? null : new MutationObserver(attach);
|
|
464
|
+
mutations?.observe(item, { childList: true, subtree: true });
|
|
465
|
+
return () => {
|
|
466
|
+
mutations?.disconnect();
|
|
467
|
+
resize?.disconnect();
|
|
468
|
+
};
|
|
469
|
+
}, [ref]);
|
|
470
|
+
return height;
|
|
471
|
+
}
|
|
472
|
+
function OverlayDetails({
|
|
473
|
+
author,
|
|
474
|
+
title,
|
|
475
|
+
caption,
|
|
476
|
+
actions,
|
|
477
|
+
fullscreenButton,
|
|
478
|
+
labels,
|
|
479
|
+
classNames
|
|
480
|
+
}) {
|
|
481
|
+
const rootRef = React2.useRef(null);
|
|
482
|
+
const barHeight = useControlsBarHeight(rootRef);
|
|
483
|
+
const showCaption = caption != null && caption !== "" && !(typeof caption === "string" && caption.trim() === (title ?? "").trim());
|
|
484
|
+
const textId = React2.useId();
|
|
485
|
+
const titleRef = React2.useRef(null);
|
|
486
|
+
const captionRef = React2.useRef(null);
|
|
487
|
+
const [expanded, setExpanded] = React2.useState(false);
|
|
488
|
+
const [clipped, setClipped] = React2.useState(false);
|
|
489
|
+
React2.useLayoutEffect(() => {
|
|
490
|
+
if (expanded) return;
|
|
491
|
+
const titleEl = titleRef.current;
|
|
492
|
+
const captionEl = captionRef.current;
|
|
493
|
+
const measure = () => setClipped(
|
|
494
|
+
!!titleEl && titleEl.scrollWidth > titleEl.clientWidth + 1 || !!captionEl && captionEl.scrollHeight > captionEl.clientHeight + 1
|
|
495
|
+
);
|
|
496
|
+
measure();
|
|
497
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
498
|
+
const observer = new ResizeObserver(measure);
|
|
499
|
+
for (const el of [titleEl, captionEl]) if (el) observer.observe(el);
|
|
500
|
+
return () => observer.disconnect();
|
|
501
|
+
}, [title, caption, expanded]);
|
|
502
|
+
return /* @__PURE__ */ jsxs(
|
|
503
|
+
"div",
|
|
504
|
+
{
|
|
505
|
+
ref: rootRef,
|
|
506
|
+
"data-slot": "details",
|
|
507
|
+
"data-expanded": expanded || void 0,
|
|
508
|
+
style: { bottom: barHeight, maxHeight: `calc(100% - ${barHeight}px)` },
|
|
509
|
+
className: cn(
|
|
510
|
+
"pointer-events-none absolute inset-x-0 z-10 flex items-end justify-between gap-3 bg-gradient-to-t from-black/55 via-black/30 to-transparent ps-3 pe-2 pt-16 pb-3 text-white [text-shadow:0_1px_2px_rgb(0_0_0/0.6)]",
|
|
511
|
+
// A darker scrim behind the full text, which can run over a bright frame.
|
|
512
|
+
expanded && "via-black/55",
|
|
513
|
+
classNames.details
|
|
514
|
+
),
|
|
515
|
+
children: [
|
|
516
|
+
/* @__PURE__ */ jsx(
|
|
517
|
+
"div",
|
|
518
|
+
{
|
|
519
|
+
id: textId,
|
|
520
|
+
className: cn(
|
|
521
|
+
"flex max-w-xl min-w-0 flex-1 flex-col leading-5",
|
|
522
|
+
expanded && "pointer-events-auto min-h-0 self-stretch overflow-y-auto overscroll-contain"
|
|
523
|
+
),
|
|
524
|
+
children: /* @__PURE__ */ jsxs("div", { className: "mt-auto", children: [
|
|
525
|
+
author && /* @__PURE__ */ jsxs(
|
|
526
|
+
"div",
|
|
527
|
+
{
|
|
528
|
+
"data-slot": "author",
|
|
529
|
+
className: cn(
|
|
530
|
+
"mb-1 flex min-w-0 items-center gap-2",
|
|
531
|
+
classNames.author
|
|
532
|
+
),
|
|
533
|
+
children: [
|
|
534
|
+
/* @__PURE__ */ jsx(
|
|
535
|
+
Avatar,
|
|
536
|
+
{
|
|
537
|
+
name: author.name,
|
|
538
|
+
src: author.avatar,
|
|
539
|
+
alt: "",
|
|
540
|
+
size: "sm",
|
|
541
|
+
className: "shrink-0 ring-1 ring-white/70"
|
|
542
|
+
}
|
|
543
|
+
),
|
|
544
|
+
/* @__PURE__ */ jsx(
|
|
545
|
+
"p",
|
|
546
|
+
{
|
|
547
|
+
dir: "auto",
|
|
548
|
+
className: "m-0 w-fit max-w-full truncate text-sm font-semibold",
|
|
549
|
+
children: author.name
|
|
550
|
+
}
|
|
551
|
+
)
|
|
552
|
+
]
|
|
553
|
+
}
|
|
554
|
+
),
|
|
555
|
+
title && /* @__PURE__ */ jsx(
|
|
556
|
+
"h3",
|
|
557
|
+
{
|
|
558
|
+
ref: titleRef,
|
|
559
|
+
"data-slot": "title",
|
|
560
|
+
dir: "auto",
|
|
561
|
+
className: cn(
|
|
562
|
+
"m-0 w-fit max-w-full text-sm font-semibold",
|
|
563
|
+
expanded ? "break-words" : "truncate",
|
|
564
|
+
classNames.title
|
|
565
|
+
),
|
|
566
|
+
children: title
|
|
567
|
+
}
|
|
568
|
+
),
|
|
569
|
+
showCaption && // A div, not a p: a host caption can hold block content, and its
|
|
570
|
+
// links stay tappable through the details layer.
|
|
571
|
+
/* @__PURE__ */ jsx(
|
|
572
|
+
"div",
|
|
573
|
+
{
|
|
574
|
+
ref: captionRef,
|
|
575
|
+
"data-slot": "caption",
|
|
576
|
+
dir: "auto",
|
|
577
|
+
className: cn(
|
|
578
|
+
"pointer-events-auto m-0 w-fit max-w-full text-sm break-words text-white/90",
|
|
579
|
+
!expanded && "line-clamp-2",
|
|
580
|
+
classNames.caption
|
|
581
|
+
),
|
|
582
|
+
children: caption
|
|
583
|
+
}
|
|
584
|
+
),
|
|
585
|
+
(clipped || expanded) && /* @__PURE__ */ jsx(
|
|
586
|
+
"button",
|
|
587
|
+
{
|
|
588
|
+
type: "button",
|
|
589
|
+
"data-slot": "details-toggle",
|
|
590
|
+
"aria-expanded": expanded,
|
|
591
|
+
"aria-controls": textId,
|
|
592
|
+
onClick: () => setExpanded((open) => !open),
|
|
593
|
+
className: "pointer-events-auto mt-0.5 rounded-sm text-sm font-semibold text-white/80 underline-offset-2 hover:underline focus-visible:outline-2 focus-visible:outline-white/70",
|
|
594
|
+
children: expanded ? labels.showLess : labels.showMore
|
|
595
|
+
}
|
|
596
|
+
)
|
|
597
|
+
] })
|
|
598
|
+
}
|
|
599
|
+
),
|
|
600
|
+
(actions || fullscreenButton) && // The action column, at the bottom end beside the text.
|
|
601
|
+
/* @__PURE__ */ jsxs("div", { className: "pointer-events-auto flex shrink-0 flex-col items-center gap-3", children: [
|
|
602
|
+
actions && /* @__PURE__ */ jsx(
|
|
603
|
+
"div",
|
|
604
|
+
{
|
|
605
|
+
"data-slot": "actions",
|
|
606
|
+
className: cn(
|
|
607
|
+
"flex flex-col items-center gap-3",
|
|
608
|
+
classNames.actions
|
|
609
|
+
),
|
|
610
|
+
children: actions
|
|
611
|
+
}
|
|
612
|
+
),
|
|
613
|
+
fullscreenButton
|
|
614
|
+
] })
|
|
615
|
+
]
|
|
616
|
+
}
|
|
617
|
+
);
|
|
618
|
+
}
|
|
345
619
|
function MediaFeedInner({
|
|
346
620
|
items,
|
|
347
621
|
getId,
|
|
@@ -351,6 +625,8 @@ function MediaFeedInner({
|
|
|
351
625
|
getAuthor,
|
|
352
626
|
renderActions,
|
|
353
627
|
renderMedia,
|
|
628
|
+
layout = "stacked",
|
|
629
|
+
allowFullscreen: allowFullscreenProp,
|
|
354
630
|
activeItemId,
|
|
355
631
|
defaultActiveItemId,
|
|
356
632
|
onActiveItemChange,
|
|
@@ -367,6 +643,8 @@ function MediaFeedInner({
|
|
|
367
643
|
...rest
|
|
368
644
|
}, forwardedRef) {
|
|
369
645
|
const labels = { ...defaultLabels, ...labelOverrides };
|
|
646
|
+
const overlay = layout === "overlay";
|
|
647
|
+
const allowFullscreen = allowFullscreenProp ?? !overlay;
|
|
370
648
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
371
649
|
const allowAutoPlay = autoPlay && !prefersReducedMotion;
|
|
372
650
|
const ids = items.map(getId);
|
|
@@ -486,8 +764,8 @@ function MediaFeedInner({
|
|
|
486
764
|
}
|
|
487
765
|
}, [activeId, idsKey, hasObserver, loading, error]);
|
|
488
766
|
React2.useEffect(() => {
|
|
489
|
-
if (!items.length) setFullscreen(false);
|
|
490
|
-
}, [items.length]);
|
|
767
|
+
if (!items.length || !allowFullscreen) setFullscreen(false);
|
|
768
|
+
}, [items.length, allowFullscreen]);
|
|
491
769
|
React2.useEffect(() => {
|
|
492
770
|
if (loading || error || activeIndex < 0 || !playbackRequest || playbackRequest.itemId !== activeId)
|
|
493
771
|
return;
|
|
@@ -577,12 +855,76 @@ function MediaFeedInner({
|
|
|
577
855
|
playbackPosition = { src: media.src, timeMs: 0 };
|
|
578
856
|
playbackPositions.current.set(id, playbackPosition);
|
|
579
857
|
}
|
|
580
|
-
const
|
|
858
|
+
const ownTitle = getTitle?.(item);
|
|
859
|
+
const title = ownTitle || labels.item(index + 1, items.length);
|
|
581
860
|
const author = getAuthor?.(item);
|
|
582
861
|
const caption = getCaption?.(item);
|
|
583
862
|
const active = !loading && !error && pageVisible && (immersive ? fullscreen && id === activeId : !fullscreen && viewportVisible && id === activeId && id === visibleId);
|
|
584
863
|
const playbackRequestId = active && playbackRequest?.itemId === id && consumedPlaybackRequests.current.get(id) !== playbackRequest.requestId ? playbackRequest.requestId : void 0;
|
|
585
|
-
|
|
864
|
+
const fullscreenButton = allowFullscreen && !immersive && /* @__PURE__ */ jsx(
|
|
865
|
+
Button,
|
|
866
|
+
{
|
|
867
|
+
type: "button",
|
|
868
|
+
variant: "ghost",
|
|
869
|
+
size: "sm",
|
|
870
|
+
"aria-label": labels.fullscreen,
|
|
871
|
+
title: labels.fullscreen,
|
|
872
|
+
className: overlay ? cn(overlayButtonClass, "shrink-0 bg-transparent") : void 0,
|
|
873
|
+
onClick: (event) => {
|
|
874
|
+
fullscreenTriggerRef.current = event.currentTarget;
|
|
875
|
+
const open = () => {
|
|
876
|
+
select(id);
|
|
877
|
+
setFullscreen(true);
|
|
878
|
+
};
|
|
879
|
+
const video = event.currentTarget.closest('[data-slot="item"]')?.querySelector("video");
|
|
880
|
+
if (isInPictureInPicture(video))
|
|
881
|
+
void exitPictureInPicture(video).then(() => {
|
|
882
|
+
if (isInPictureInPicture(video)) video?.pause();
|
|
883
|
+
open();
|
|
884
|
+
});
|
|
885
|
+
else open();
|
|
886
|
+
},
|
|
887
|
+
children: /* @__PURE__ */ jsx(Maximize2, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
888
|
+
}
|
|
889
|
+
);
|
|
890
|
+
const mediaSlot = /* @__PURE__ */ jsx(
|
|
891
|
+
"div",
|
|
892
|
+
{
|
|
893
|
+
"data-slot": "media",
|
|
894
|
+
className: cn(
|
|
895
|
+
overlay ? (
|
|
896
|
+
// Black letterboxing around the clip, as on VideoCard.
|
|
897
|
+
"absolute inset-0 flex items-center justify-center bg-black"
|
|
898
|
+
) : "bg-muted flex min-h-0 flex-1 items-center justify-center p-3",
|
|
899
|
+
classNames.media
|
|
900
|
+
),
|
|
901
|
+
children: renderMedia ? renderMedia(media, {
|
|
902
|
+
item,
|
|
903
|
+
active,
|
|
904
|
+
autoPlay: allowAutoPlay,
|
|
905
|
+
muted,
|
|
906
|
+
loop,
|
|
907
|
+
playbackRequestId
|
|
908
|
+
}) : /* @__PURE__ */ jsx(
|
|
909
|
+
FeedMedia,
|
|
910
|
+
{
|
|
911
|
+
media,
|
|
912
|
+
title,
|
|
913
|
+
active,
|
|
914
|
+
autoPlay: allowAutoPlay,
|
|
915
|
+
muted,
|
|
916
|
+
loop,
|
|
917
|
+
labels,
|
|
918
|
+
onActivate: () => select(id),
|
|
919
|
+
playbackPosition,
|
|
920
|
+
playbackRequestId,
|
|
921
|
+
overlay
|
|
922
|
+
},
|
|
923
|
+
`${id}:${media.kind}:${media.src}:${immersive}`
|
|
924
|
+
)
|
|
925
|
+
}
|
|
926
|
+
);
|
|
927
|
+
return /* @__PURE__ */ jsx(
|
|
586
928
|
"article",
|
|
587
929
|
{
|
|
588
930
|
ref: immersive ? void 0 : (node) => {
|
|
@@ -597,44 +939,29 @@ function MediaFeedInner({
|
|
|
597
939
|
"aria-setsize": items.length,
|
|
598
940
|
tabIndex: id === activeId ? 0 : -1,
|
|
599
941
|
className: cn(
|
|
600
|
-
|
|
601
|
-
|
|
942
|
+
overlay ? cn(
|
|
943
|
+
"relative h-full min-h-0 w-full snap-start snap-always overflow-hidden bg-black focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-white/70",
|
|
944
|
+
OVERLAY_BAR_SCRIM
|
|
945
|
+
) : "border-border bg-card text-card-foreground focus-visible:ring-ring flex min-h-0 w-full snap-start flex-col overflow-hidden border focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset",
|
|
946
|
+
overlay ? immersive ? "flex-1" : "shrink-0" : immersive ? "h-full flex-1 border-0" : "h-full shrink-0 rounded-xl",
|
|
602
947
|
classNames.item
|
|
603
948
|
),
|
|
604
|
-
children: [
|
|
949
|
+
children: overlay ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
605
950
|
/* @__PURE__ */ jsx(
|
|
606
|
-
|
|
951
|
+
OverlayDetails,
|
|
607
952
|
{
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
active,
|
|
616
|
-
autoPlay: allowAutoPlay,
|
|
617
|
-
muted,
|
|
618
|
-
loop,
|
|
619
|
-
playbackRequestId
|
|
620
|
-
}) : /* @__PURE__ */ jsx(
|
|
621
|
-
FeedMedia,
|
|
622
|
-
{
|
|
623
|
-
media,
|
|
624
|
-
title,
|
|
625
|
-
active,
|
|
626
|
-
autoPlay: allowAutoPlay,
|
|
627
|
-
muted,
|
|
628
|
-
loop,
|
|
629
|
-
labels,
|
|
630
|
-
onActivate: () => select(id),
|
|
631
|
-
playbackPosition,
|
|
632
|
-
playbackRequestId
|
|
633
|
-
},
|
|
634
|
-
`${id}:${media.kind}:${media.src}:${immersive}`
|
|
635
|
-
)
|
|
953
|
+
author,
|
|
954
|
+
title: ownTitle,
|
|
955
|
+
caption,
|
|
956
|
+
actions: renderActions?.(item),
|
|
957
|
+
fullscreenButton,
|
|
958
|
+
labels,
|
|
959
|
+
classNames
|
|
636
960
|
}
|
|
637
961
|
),
|
|
962
|
+
mediaSlot
|
|
963
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
964
|
+
mediaSlot,
|
|
638
965
|
/* @__PURE__ */ jsxs(
|
|
639
966
|
"div",
|
|
640
967
|
{
|
|
@@ -672,26 +999,15 @@ function MediaFeedInner({
|
|
|
672
999
|
"h3",
|
|
673
1000
|
{
|
|
674
1001
|
"data-slot": "title",
|
|
675
|
-
className: cn(
|
|
1002
|
+
className: cn(
|
|
1003
|
+
"m-0 text-base font-semibold",
|
|
1004
|
+
classNames.title
|
|
1005
|
+
),
|
|
676
1006
|
children: title
|
|
677
1007
|
}
|
|
678
1008
|
)
|
|
679
1009
|
] }),
|
|
680
|
-
|
|
681
|
-
Button,
|
|
682
|
-
{
|
|
683
|
-
variant: "ghost",
|
|
684
|
-
size: "sm",
|
|
685
|
-
"aria-label": labels.fullscreen,
|
|
686
|
-
title: labels.fullscreen,
|
|
687
|
-
onClick: (event) => {
|
|
688
|
-
fullscreenTriggerRef.current = event.currentTarget;
|
|
689
|
-
select(id);
|
|
690
|
-
setFullscreen(true);
|
|
691
|
-
},
|
|
692
|
-
children: /* @__PURE__ */ jsx(Maximize2, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
693
|
-
}
|
|
694
|
-
)
|
|
1010
|
+
fullscreenButton
|
|
695
1011
|
] }),
|
|
696
1012
|
caption != null && /* @__PURE__ */ jsx(
|
|
697
1013
|
"div",
|
|
@@ -718,12 +1034,67 @@ function MediaFeedInner({
|
|
|
718
1034
|
]
|
|
719
1035
|
}
|
|
720
1036
|
)
|
|
721
|
-
]
|
|
1037
|
+
] })
|
|
722
1038
|
},
|
|
723
1039
|
id
|
|
724
1040
|
);
|
|
725
1041
|
};
|
|
726
|
-
const controls =
|
|
1042
|
+
const controls = overlay ? (
|
|
1043
|
+
// Over the middle of the feed's end edge, stacked the way the feed
|
|
1044
|
+
// scrolls, above the actions and the player's bar at the bottom. On a
|
|
1045
|
+
// short screen (a phone held sideways, as SuperChat reckons it) the middle
|
|
1046
|
+
// runs into the actions, so they move to the top end, clear of a host's
|
|
1047
|
+
// Back at the top start.
|
|
1048
|
+
/* @__PURE__ */ jsxs(
|
|
1049
|
+
"div",
|
|
1050
|
+
{
|
|
1051
|
+
"data-slot": "controls",
|
|
1052
|
+
className: cn(
|
|
1053
|
+
"pointer-events-none absolute end-2 top-1/2 z-10 flex -translate-y-1/2 flex-col items-center gap-1.5 [@media(max-height:30rem)]:top-2 [@media(max-height:30rem)]:translate-y-0",
|
|
1054
|
+
classNames.controls
|
|
1055
|
+
),
|
|
1056
|
+
children: [
|
|
1057
|
+
/* @__PURE__ */ jsx(
|
|
1058
|
+
Button,
|
|
1059
|
+
{
|
|
1060
|
+
type: "button",
|
|
1061
|
+
variant: "ghost",
|
|
1062
|
+
size: "icon",
|
|
1063
|
+
"aria-label": labels.previous,
|
|
1064
|
+
title: labels.previous,
|
|
1065
|
+
className: cn(overlayButtonClass, "pointer-events-auto"),
|
|
1066
|
+
disabled: activeIndex <= 0,
|
|
1067
|
+
onClick: () => navigate(activeIndex - 1),
|
|
1068
|
+
children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-5 w-5", "aria-hidden": "true" })
|
|
1069
|
+
}
|
|
1070
|
+
),
|
|
1071
|
+
/* @__PURE__ */ jsx(
|
|
1072
|
+
"span",
|
|
1073
|
+
{
|
|
1074
|
+
role: "status",
|
|
1075
|
+
"aria-live": "polite",
|
|
1076
|
+
className: "rounded-full bg-black/45 px-1.5 py-0.5 text-xs whitespace-nowrap text-white tabular-nums backdrop-blur-sm",
|
|
1077
|
+
children: /* @__PURE__ */ jsx("bdi", { children: labels.position(activeIndex + 1, items.length) })
|
|
1078
|
+
}
|
|
1079
|
+
),
|
|
1080
|
+
/* @__PURE__ */ jsx(
|
|
1081
|
+
Button,
|
|
1082
|
+
{
|
|
1083
|
+
type: "button",
|
|
1084
|
+
variant: "ghost",
|
|
1085
|
+
size: "icon",
|
|
1086
|
+
"aria-label": labels.next,
|
|
1087
|
+
title: labels.next,
|
|
1088
|
+
className: cn(overlayButtonClass, "pointer-events-auto"),
|
|
1089
|
+
disabled: activeIndex >= items.length - 1,
|
|
1090
|
+
onClick: () => navigate(activeIndex + 1),
|
|
1091
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-5 w-5", "aria-hidden": "true" })
|
|
1092
|
+
}
|
|
1093
|
+
)
|
|
1094
|
+
]
|
|
1095
|
+
}
|
|
1096
|
+
)
|
|
1097
|
+
) : /* @__PURE__ */ jsxs(
|
|
727
1098
|
"div",
|
|
728
1099
|
{
|
|
729
1100
|
"data-slot": "controls",
|
|
@@ -735,6 +1106,7 @@ function MediaFeedInner({
|
|
|
735
1106
|
/* @__PURE__ */ jsx(
|
|
736
1107
|
Button,
|
|
737
1108
|
{
|
|
1109
|
+
type: "button",
|
|
738
1110
|
variant: "ghost",
|
|
739
1111
|
size: "sm",
|
|
740
1112
|
className: "h-auto min-h-8 flex-1 py-2 [&_[data-slot=button-label]]:whitespace-normal",
|
|
@@ -750,12 +1122,13 @@ function MediaFeedInner({
|
|
|
750
1122
|
role: "status",
|
|
751
1123
|
"aria-live": "polite",
|
|
752
1124
|
className: "text-muted-foreground shrink-0 text-sm whitespace-nowrap",
|
|
753
|
-
children: labels.position(activeIndex + 1, items.length)
|
|
1125
|
+
children: /* @__PURE__ */ jsx("bdi", { children: labels.position(activeIndex + 1, items.length) })
|
|
754
1126
|
}
|
|
755
1127
|
),
|
|
756
1128
|
/* @__PURE__ */ jsx(
|
|
757
1129
|
Button,
|
|
758
1130
|
{
|
|
1131
|
+
type: "button",
|
|
759
1132
|
variant: "ghost",
|
|
760
1133
|
size: "sm",
|
|
761
1134
|
className: "h-auto min-h-8 flex-1 py-2 [&_[data-slot=button-label]]:whitespace-normal",
|
|
@@ -774,8 +1147,11 @@ function MediaFeedInner({
|
|
|
774
1147
|
ref: setRoot,
|
|
775
1148
|
"data-slot": "root",
|
|
776
1149
|
"data-component": "media-feed",
|
|
1150
|
+
"data-layout": layout,
|
|
1151
|
+
"data-theme": overlay ? "dark" : void 0,
|
|
777
1152
|
className: cn(
|
|
778
1153
|
"bg-background text-foreground flex h-[min(48rem,80dvh)] min-h-0 w-full flex-col",
|
|
1154
|
+
overlay && "relative",
|
|
779
1155
|
classNames.root,
|
|
780
1156
|
className
|
|
781
1157
|
),
|
|
@@ -796,6 +1172,7 @@ function MediaFeedInner({
|
|
|
796
1172
|
error && onRetry && /* @__PURE__ */ jsx(
|
|
797
1173
|
Button,
|
|
798
1174
|
{
|
|
1175
|
+
type: "button",
|
|
799
1176
|
variant: "outline",
|
|
800
1177
|
isLoading: retrying,
|
|
801
1178
|
loadingText: labels.loading,
|
|
@@ -820,7 +1197,8 @@ function MediaFeedInner({
|
|
|
820
1197
|
tabIndex: 0,
|
|
821
1198
|
onKeyDown: handleKeyDown,
|
|
822
1199
|
className: cn(
|
|
823
|
-
"focus-visible:ring-ring relative flex min-h-0 flex-1 snap-y snap-mandatory flex-col
|
|
1200
|
+
"focus-visible:ring-ring relative flex min-h-0 flex-1 snap-y snap-mandatory flex-col overflow-y-auto overscroll-contain focus-visible:ring-2 focus-visible:outline-none",
|
|
1201
|
+
!overlay && "gap-4",
|
|
824
1202
|
classNames.viewport
|
|
825
1203
|
),
|
|
826
1204
|
children: items.map((item, index) => renderCard(item, index, false))
|
|
@@ -831,7 +1209,7 @@ function MediaFeedInner({
|
|
|
831
1209
|
/* @__PURE__ */ jsxs(
|
|
832
1210
|
Modal,
|
|
833
1211
|
{
|
|
834
|
-
open: fullscreen && !loading && !error && !!items.length,
|
|
1212
|
+
open: allowFullscreen && fullscreen && !loading && !error && !!items.length,
|
|
835
1213
|
onOpenChange: setFullscreen,
|
|
836
1214
|
size: "full",
|
|
837
1215
|
className: "h-dvh min-h-0 sm:h-[calc(100dvh-2rem)]",
|
|
@@ -845,12 +1223,15 @@ function MediaFeedInner({
|
|
|
845
1223
|
{
|
|
846
1224
|
"data-slot": "fullscreen",
|
|
847
1225
|
"data-component": "media-feed",
|
|
1226
|
+
"data-layout": layout,
|
|
1227
|
+
"data-theme": overlay ? "dark" : void 0,
|
|
848
1228
|
role: "feed",
|
|
849
1229
|
"aria-label": labels.feed,
|
|
850
1230
|
tabIndex: 0,
|
|
851
1231
|
onKeyDown: handleKeyDown,
|
|
852
1232
|
className: cn(
|
|
853
1233
|
"flex min-h-0 flex-1 flex-col px-2 pb-2 sm:px-4",
|
|
1234
|
+
overlay && "relative",
|
|
854
1235
|
classNames.fullscreen
|
|
855
1236
|
),
|
|
856
1237
|
children: [
|
|
@@ -870,5 +1251,5 @@ var MediaFeed = React2.forwardRef(MediaFeedInner);
|
|
|
870
1251
|
MediaFeed.displayName = "MediaFeed";
|
|
871
1252
|
|
|
872
1253
|
export { MediaFeed };
|
|
873
|
-
//# sourceMappingURL=chunk-
|
|
874
|
-
//# sourceMappingURL=chunk-
|
|
1254
|
+
//# sourceMappingURL=chunk-JUY2JLFL.js.map
|
|
1255
|
+
//# sourceMappingURL=chunk-JUY2JLFL.js.map
|