@refraction-ui/react 0.4.0 → 0.4.1
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/dist/index.cjs +841 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +796 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -7093,6 +7093,798 @@ var VideoPlayer = React11.forwardRef(
|
|
|
7093
7093
|
);
|
|
7094
7094
|
VideoPlayer.displayName = "VideoPlayer";
|
|
7095
7095
|
|
|
7096
|
+
// ../voice-pill/dist/index.js
|
|
7097
|
+
var DEFAULT_VOICE_PILL_SPEAKER = "ai";
|
|
7098
|
+
var DEFAULT_VOICE_PILL_POSITION = "bottom-center";
|
|
7099
|
+
function formatNumber(value) {
|
|
7100
|
+
return Number(value.toFixed(3)).toString();
|
|
7101
|
+
}
|
|
7102
|
+
function getRawSpeaker(speaker) {
|
|
7103
|
+
const value = String(speaker ?? DEFAULT_VOICE_PILL_SPEAKER).trim();
|
|
7104
|
+
return value.length > 0 ? value : DEFAULT_VOICE_PILL_SPEAKER;
|
|
7105
|
+
}
|
|
7106
|
+
function clampVoicePillIntensity(intensity = 0) {
|
|
7107
|
+
const value = Number(intensity);
|
|
7108
|
+
if (!Number.isFinite(value)) {
|
|
7109
|
+
return 0;
|
|
7110
|
+
}
|
|
7111
|
+
return Math.min(1, Math.max(0, value));
|
|
7112
|
+
}
|
|
7113
|
+
function getVoicePillSpeakerKey(speaker) {
|
|
7114
|
+
const normalized = getRawSpeaker(speaker).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
7115
|
+
return normalized.length > 0 ? normalized : DEFAULT_VOICE_PILL_SPEAKER;
|
|
7116
|
+
}
|
|
7117
|
+
function getVoicePillSpeakerLabel(speaker) {
|
|
7118
|
+
const raw = getRawSpeaker(speaker);
|
|
7119
|
+
const key = getVoicePillSpeakerKey(raw);
|
|
7120
|
+
if (key === "ai") return "AI";
|
|
7121
|
+
if (key === "user") return "User";
|
|
7122
|
+
return raw;
|
|
7123
|
+
}
|
|
7124
|
+
function getVoicePillInitials(speaker) {
|
|
7125
|
+
const key = getVoicePillSpeakerKey(speaker);
|
|
7126
|
+
if (key === "ai") return "AI";
|
|
7127
|
+
if (key === "user") return "U";
|
|
7128
|
+
const initials = getVoicePillSpeakerLabel(speaker).split(/[\s_-]+/).map((part) => part.charAt(0)).filter(Boolean).join("").slice(0, 2).toUpperCase();
|
|
7129
|
+
return initials.length > 0 ? initials : "V";
|
|
7130
|
+
}
|
|
7131
|
+
function getVoicePillPosition(position) {
|
|
7132
|
+
return position ?? DEFAULT_VOICE_PILL_POSITION;
|
|
7133
|
+
}
|
|
7134
|
+
function getVoicePillAriaLabel(props) {
|
|
7135
|
+
const parts = [`${getVoicePillSpeakerLabel(props.speaker)}: ${props.label}`];
|
|
7136
|
+
if (props.sub) {
|
|
7137
|
+
parts.push(props.sub);
|
|
7138
|
+
}
|
|
7139
|
+
if (props.muted) {
|
|
7140
|
+
parts.push("muted");
|
|
7141
|
+
}
|
|
7142
|
+
return parts.join(", ");
|
|
7143
|
+
}
|
|
7144
|
+
function getVoicePillPulseStyle(intensity, muted = false) {
|
|
7145
|
+
const clamped = clampVoicePillIntensity(intensity);
|
|
7146
|
+
const visualIntensity = muted ? 0 : clamped;
|
|
7147
|
+
const ringOpacity = visualIntensity === 0 ? 0 : 0.12 + visualIntensity * 0.42;
|
|
7148
|
+
const ringScale = 1 + visualIntensity * 0.35;
|
|
7149
|
+
const duration = visualIntensity === 0 ? 1800 : Math.round(1700 - visualIntensity * 700);
|
|
7150
|
+
return {
|
|
7151
|
+
"--rfr-voice-pill-intensity": formatNumber(clamped),
|
|
7152
|
+
"--rfr-voice-pill-visual-intensity": formatNumber(visualIntensity),
|
|
7153
|
+
"--rfr-voice-pill-ring-opacity": formatNumber(ringOpacity),
|
|
7154
|
+
"--rfr-voice-pill-ring-scale": formatNumber(ringScale),
|
|
7155
|
+
"--rfr-voice-pill-pulse-duration": `${duration}ms`,
|
|
7156
|
+
"--rfr-voice-pill-pulse-delay": `-${Math.round(duration / 2)}ms`
|
|
7157
|
+
};
|
|
7158
|
+
}
|
|
7159
|
+
function createVoicePill(props) {
|
|
7160
|
+
const {
|
|
7161
|
+
speaker: speakerProp,
|
|
7162
|
+
label,
|
|
7163
|
+
sub,
|
|
7164
|
+
intensity: intensityProp,
|
|
7165
|
+
muted: mutedProp = false,
|
|
7166
|
+
onToggleMute,
|
|
7167
|
+
position: positionProp
|
|
7168
|
+
} = props;
|
|
7169
|
+
const speaker = getVoicePillSpeakerLabel(speakerProp);
|
|
7170
|
+
const speakerKey = getVoicePillSpeakerKey(speakerProp);
|
|
7171
|
+
const intensity = clampVoicePillIntensity(intensityProp);
|
|
7172
|
+
const muted = Boolean(mutedProp);
|
|
7173
|
+
const visualIntensity = muted ? 0 : intensity;
|
|
7174
|
+
const position = getVoicePillPosition(positionProp);
|
|
7175
|
+
function toggleMute() {
|
|
7176
|
+
onToggleMute?.();
|
|
7177
|
+
}
|
|
7178
|
+
const ariaProps = {
|
|
7179
|
+
role: "status",
|
|
7180
|
+
"aria-live": "polite",
|
|
7181
|
+
"aria-atomic": true,
|
|
7182
|
+
"aria-label": getVoicePillAriaLabel({ speaker: speakerProp, label, sub, muted })
|
|
7183
|
+
};
|
|
7184
|
+
const toggleMuteAriaProps = {
|
|
7185
|
+
"aria-label": muted ? "Unmute voice" : "Mute voice",
|
|
7186
|
+
"aria-pressed": muted
|
|
7187
|
+
};
|
|
7188
|
+
const dataAttributes = {
|
|
7189
|
+
"data-speaker": speakerKey,
|
|
7190
|
+
"data-muted": String(muted),
|
|
7191
|
+
"data-position": position,
|
|
7192
|
+
"data-intensity": formatNumber(intensity),
|
|
7193
|
+
"data-active": String(visualIntensity > 0)
|
|
7194
|
+
};
|
|
7195
|
+
return {
|
|
7196
|
+
speaker,
|
|
7197
|
+
speakerKey,
|
|
7198
|
+
label,
|
|
7199
|
+
sub,
|
|
7200
|
+
intensity,
|
|
7201
|
+
visualIntensity,
|
|
7202
|
+
muted,
|
|
7203
|
+
position,
|
|
7204
|
+
initials: getVoicePillInitials(speakerProp),
|
|
7205
|
+
toggleMute,
|
|
7206
|
+
ariaProps,
|
|
7207
|
+
toggleMuteAriaProps,
|
|
7208
|
+
dataAttributes,
|
|
7209
|
+
style: getVoicePillPulseStyle(intensity, muted)
|
|
7210
|
+
};
|
|
7211
|
+
}
|
|
7212
|
+
var voicePillTokens = {
|
|
7213
|
+
name: "voice-pill",
|
|
7214
|
+
tokens: {
|
|
7215
|
+
bg: { variable: "--rfr-voice-pill-bg", fallback: "hsl(var(--background))" },
|
|
7216
|
+
fg: { variable: "--rfr-voice-pill-fg", fallback: "hsl(var(--foreground))" },
|
|
7217
|
+
border: { variable: "--rfr-voice-pill-border", fallback: "hsl(var(--border))" },
|
|
7218
|
+
accent: { variable: "--rfr-voice-pill-accent", fallback: "hsl(var(--primary))" },
|
|
7219
|
+
accentFg: {
|
|
7220
|
+
variable: "--rfr-voice-pill-accent-foreground",
|
|
7221
|
+
fallback: "hsl(var(--primary-foreground))"
|
|
7222
|
+
}
|
|
7223
|
+
}
|
|
7224
|
+
};
|
|
7225
|
+
var voicePillRootStyles = "inline-flex min-w-0 max-w-[min(calc(100vw-2rem),22rem)] items-center gap-3 rounded-full border border-border bg-background px-3 py-2 text-foreground shadow-lg ring-1 ring-border/50 transition-opacity data-[muted=true]:opacity-80";
|
|
7226
|
+
var voicePillSpeakerStyles = "[--rfr-voice-pill-accent:hsl(var(--primary))] [--rfr-voice-pill-accent-foreground:hsl(var(--primary-foreground))] data-[speaker=user]:[--rfr-voice-pill-accent:hsl(var(--accent-foreground))] data-[speaker=user]:[--rfr-voice-pill-accent-foreground:hsl(var(--accent))] data-[muted=true]:[--rfr-voice-pill-accent:hsl(var(--muted-foreground))]";
|
|
7227
|
+
var voicePillPositionVariants = cva({
|
|
7228
|
+
base: "fixed z-50",
|
|
7229
|
+
variants: {
|
|
7230
|
+
position: {
|
|
7231
|
+
"top-start": "top-[calc(env(safe-area-inset-top)+1rem)] left-[calc(env(safe-area-inset-left)+1rem)]",
|
|
7232
|
+
"top-center": "top-[calc(env(safe-area-inset-top)+1rem)] left-1/2 -translate-x-1/2",
|
|
7233
|
+
"top-end": "top-[calc(env(safe-area-inset-top)+1rem)] right-[calc(env(safe-area-inset-right)+1rem)]",
|
|
7234
|
+
"bottom-start": "bottom-[calc(env(safe-area-inset-bottom)+1rem)] left-[calc(env(safe-area-inset-left)+1rem)]",
|
|
7235
|
+
"bottom-center": "bottom-[calc(env(safe-area-inset-bottom)+1rem)] left-1/2 -translate-x-1/2",
|
|
7236
|
+
"bottom-end": "bottom-[calc(env(safe-area-inset-bottom)+1rem)] right-[calc(env(safe-area-inset-right)+1rem)]",
|
|
7237
|
+
"left-start": "left-[calc(env(safe-area-inset-left)+1rem)] top-[calc(env(safe-area-inset-top)+1rem)]",
|
|
7238
|
+
"left-center": "left-[calc(env(safe-area-inset-left)+1rem)] top-1/2 -translate-y-1/2",
|
|
7239
|
+
"left-end": "left-[calc(env(safe-area-inset-left)+1rem)] bottom-[calc(env(safe-area-inset-bottom)+1rem)]",
|
|
7240
|
+
"right-start": "right-[calc(env(safe-area-inset-right)+1rem)] top-[calc(env(safe-area-inset-top)+1rem)]",
|
|
7241
|
+
"right-center": "right-[calc(env(safe-area-inset-right)+1rem)] top-1/2 -translate-y-1/2",
|
|
7242
|
+
"right-end": "right-[calc(env(safe-area-inset-right)+1rem)] bottom-[calc(env(safe-area-inset-bottom)+1rem)]"
|
|
7243
|
+
}
|
|
7244
|
+
},
|
|
7245
|
+
defaultVariants: {
|
|
7246
|
+
position: "bottom-center"
|
|
7247
|
+
}
|
|
7248
|
+
});
|
|
7249
|
+
var voicePillAvatarWrapStyles = "relative flex h-10 w-10 shrink-0 items-center justify-center";
|
|
7250
|
+
var voicePillPulseRingStyles = "pointer-events-none absolute inset-0 rounded-full border border-[var(--rfr-voice-pill-accent)] opacity-[var(--rfr-voice-pill-ring-opacity)] motion-safe:animate-ping motion-reduce:animate-none";
|
|
7251
|
+
var voicePillAvatarStyles = "relative z-10 flex h-10 w-10 items-center justify-center overflow-hidden rounded-full bg-[var(--rfr-voice-pill-accent)] text-[var(--rfr-voice-pill-accent-foreground)] text-xs font-semibold uppercase";
|
|
7252
|
+
var voicePillTextStyles = "min-w-0 flex-1";
|
|
7253
|
+
var voicePillLabelStyles = "block truncate text-sm font-medium leading-tight";
|
|
7254
|
+
var voicePillSubStyles = "block truncate text-xs leading-tight text-muted-foreground";
|
|
7255
|
+
var voicePillMuteButtonStyles = "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-border text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
|
|
7256
|
+
|
|
7257
|
+
// ../react-voice-pill/dist/index.js
|
|
7258
|
+
var VoicePill = React11.forwardRef(
|
|
7259
|
+
({
|
|
7260
|
+
speaker,
|
|
7261
|
+
label,
|
|
7262
|
+
sub,
|
|
7263
|
+
intensity,
|
|
7264
|
+
muted,
|
|
7265
|
+
onToggleMute,
|
|
7266
|
+
position,
|
|
7267
|
+
avatar,
|
|
7268
|
+
className,
|
|
7269
|
+
style,
|
|
7270
|
+
...props
|
|
7271
|
+
}, ref) => {
|
|
7272
|
+
const api = createVoicePill({
|
|
7273
|
+
speaker,
|
|
7274
|
+
label,
|
|
7275
|
+
sub,
|
|
7276
|
+
intensity,
|
|
7277
|
+
muted,
|
|
7278
|
+
onToggleMute,
|
|
7279
|
+
position
|
|
7280
|
+
});
|
|
7281
|
+
const mergedStyle = {
|
|
7282
|
+
...api.style,
|
|
7283
|
+
...style
|
|
7284
|
+
};
|
|
7285
|
+
const pulseStyle = {
|
|
7286
|
+
animationDuration: "var(--rfr-voice-pill-pulse-duration)",
|
|
7287
|
+
transform: "scale(var(--rfr-voice-pill-ring-scale))"
|
|
7288
|
+
};
|
|
7289
|
+
const delayedPulseStyle = {
|
|
7290
|
+
...pulseStyle,
|
|
7291
|
+
animationDelay: "var(--rfr-voice-pill-pulse-delay)"
|
|
7292
|
+
};
|
|
7293
|
+
return React11.createElement(
|
|
7294
|
+
"div",
|
|
7295
|
+
{
|
|
7296
|
+
...props,
|
|
7297
|
+
...api.ariaProps,
|
|
7298
|
+
...api.dataAttributes,
|
|
7299
|
+
ref,
|
|
7300
|
+
className: cn(
|
|
7301
|
+
voicePillPositionVariants({ position: api.position }),
|
|
7302
|
+
voicePillRootStyles,
|
|
7303
|
+
voicePillSpeakerStyles,
|
|
7304
|
+
className
|
|
7305
|
+
),
|
|
7306
|
+
style: mergedStyle
|
|
7307
|
+
},
|
|
7308
|
+
React11.createElement(
|
|
7309
|
+
"span",
|
|
7310
|
+
{
|
|
7311
|
+
className: voicePillAvatarWrapStyles,
|
|
7312
|
+
"aria-hidden": true
|
|
7313
|
+
},
|
|
7314
|
+
api.visualIntensity > 0 && React11.createElement("span", {
|
|
7315
|
+
className: voicePillPulseRingStyles,
|
|
7316
|
+
style: pulseStyle
|
|
7317
|
+
}),
|
|
7318
|
+
api.visualIntensity > 0 && React11.createElement("span", {
|
|
7319
|
+
className: voicePillPulseRingStyles,
|
|
7320
|
+
style: delayedPulseStyle
|
|
7321
|
+
}),
|
|
7322
|
+
React11.createElement(
|
|
7323
|
+
"span",
|
|
7324
|
+
{ className: voicePillAvatarStyles },
|
|
7325
|
+
avatar ?? api.initials
|
|
7326
|
+
)
|
|
7327
|
+
),
|
|
7328
|
+
React11.createElement(
|
|
7329
|
+
"span",
|
|
7330
|
+
{ className: voicePillTextStyles },
|
|
7331
|
+
React11.createElement("span", { className: voicePillLabelStyles }, api.label),
|
|
7332
|
+
api.sub && React11.createElement("span", { className: voicePillSubStyles }, api.sub)
|
|
7333
|
+
),
|
|
7334
|
+
onToggleMute && React11.createElement(
|
|
7335
|
+
"button",
|
|
7336
|
+
{
|
|
7337
|
+
type: "button",
|
|
7338
|
+
className: voicePillMuteButtonStyles,
|
|
7339
|
+
onClick: api.toggleMute,
|
|
7340
|
+
...api.toggleMuteAriaProps
|
|
7341
|
+
},
|
|
7342
|
+
renderMuteIcon(api.muted)
|
|
7343
|
+
)
|
|
7344
|
+
);
|
|
7345
|
+
}
|
|
7346
|
+
);
|
|
7347
|
+
VoicePill.displayName = "VoicePill";
|
|
7348
|
+
function renderMuteIcon(muted) {
|
|
7349
|
+
return React11.createElement(
|
|
7350
|
+
"svg",
|
|
7351
|
+
{
|
|
7352
|
+
"aria-hidden": true,
|
|
7353
|
+
className: "h-4 w-4",
|
|
7354
|
+
fill: "none",
|
|
7355
|
+
stroke: "currentColor",
|
|
7356
|
+
strokeLinecap: "round",
|
|
7357
|
+
strokeLinejoin: "round",
|
|
7358
|
+
strokeWidth: 2,
|
|
7359
|
+
viewBox: "0 0 24 24"
|
|
7360
|
+
},
|
|
7361
|
+
React11.createElement("path", {
|
|
7362
|
+
d: "M4 9v6h4l5 4V5L8 9H4Z"
|
|
7363
|
+
}),
|
|
7364
|
+
muted ? React11.createElement(
|
|
7365
|
+
React11.Fragment,
|
|
7366
|
+
null,
|
|
7367
|
+
React11.createElement("path", { d: "m19 9-4 4" }),
|
|
7368
|
+
React11.createElement("path", { d: "m15 9 4 4" })
|
|
7369
|
+
) : React11.createElement(
|
|
7370
|
+
React11.Fragment,
|
|
7371
|
+
null,
|
|
7372
|
+
React11.createElement("path", { d: "M16 8.5a4 4 0 0 1 0 7" }),
|
|
7373
|
+
React11.createElement("path", { d: "M18.5 6a7 7 0 0 1 0 12" })
|
|
7374
|
+
)
|
|
7375
|
+
);
|
|
7376
|
+
}
|
|
7377
|
+
|
|
7378
|
+
// ../waveform/dist/index.js
|
|
7379
|
+
var DEFAULT_WAVEFORM_BAR_COUNT = 48;
|
|
7380
|
+
var DEFAULT_WAVEFORM_COLOR = "var(--accent-2)";
|
|
7381
|
+
var DEFAULT_WAVEFORM_HEIGHT = 80;
|
|
7382
|
+
var DEFAULT_WAVEFORM_INTENSITY = 1;
|
|
7383
|
+
var DEFAULT_WAVEFORM_SMOOTHING = 0.8;
|
|
7384
|
+
var MAX_BAR_COUNT = 1024;
|
|
7385
|
+
var MAX_INTENSITY = 1;
|
|
7386
|
+
function normalizeBarCount(value) {
|
|
7387
|
+
if (value == null || !Number.isFinite(value)) return DEFAULT_WAVEFORM_BAR_COUNT;
|
|
7388
|
+
return Math.min(MAX_BAR_COUNT, Math.max(1, Math.round(value)));
|
|
7389
|
+
}
|
|
7390
|
+
function normalizeSmoothing(value) {
|
|
7391
|
+
if (value == null || !Number.isFinite(value)) return DEFAULT_WAVEFORM_SMOOTHING;
|
|
7392
|
+
return Math.min(0.99, Math.max(0, value));
|
|
7393
|
+
}
|
|
7394
|
+
function normalizeIntensity(value) {
|
|
7395
|
+
if (value == null || !Number.isFinite(value)) return DEFAULT_WAVEFORM_INTENSITY;
|
|
7396
|
+
return Math.min(MAX_INTENSITY, Math.max(0, value));
|
|
7397
|
+
}
|
|
7398
|
+
function normalizeWaveformConfig(props = {}) {
|
|
7399
|
+
return {
|
|
7400
|
+
variant: props.variant ?? "bars",
|
|
7401
|
+
intensity: normalizeIntensity(props.intensity),
|
|
7402
|
+
height: props.height ?? DEFAULT_WAVEFORM_HEIGHT,
|
|
7403
|
+
width: props.width ?? "100%",
|
|
7404
|
+
barCount: normalizeBarCount(props.barCount),
|
|
7405
|
+
smoothing: normalizeSmoothing(props.smoothing),
|
|
7406
|
+
color: props.color ?? DEFAULT_WAVEFORM_COLOR,
|
|
7407
|
+
paused: props.paused ?? false
|
|
7408
|
+
};
|
|
7409
|
+
}
|
|
7410
|
+
function isWaveformSampleInput(value) {
|
|
7411
|
+
return value instanceof Float32Array || Array.isArray(value);
|
|
7412
|
+
}
|
|
7413
|
+
function createSilentSamples(count = DEFAULT_WAVEFORM_BAR_COUNT) {
|
|
7414
|
+
return new Float32Array(normalizeBarCount(count));
|
|
7415
|
+
}
|
|
7416
|
+
function createIntensitySamples(intensity = DEFAULT_WAVEFORM_INTENSITY, count = DEFAULT_WAVEFORM_BAR_COUNT) {
|
|
7417
|
+
const normalizedIntensity = normalizeIntensity(intensity);
|
|
7418
|
+
const normalizedCount = normalizeBarCount(count);
|
|
7419
|
+
const samples = new Float32Array(normalizedCount);
|
|
7420
|
+
if (normalizedIntensity === 0) return samples;
|
|
7421
|
+
for (let i = 0; i < normalizedCount; i += 1) {
|
|
7422
|
+
const progress = normalizedCount <= 1 ? 0.5 : i / (normalizedCount - 1);
|
|
7423
|
+
const envelope = 0.35 + Math.sin(progress * Math.PI) * 0.65;
|
|
7424
|
+
const carrier = Math.sin(progress * Math.PI * 6);
|
|
7425
|
+
samples[i] = carrier * envelope * normalizedIntensity;
|
|
7426
|
+
}
|
|
7427
|
+
return samples;
|
|
7428
|
+
}
|
|
7429
|
+
function normalizeWaveformSamples(input, targetCount) {
|
|
7430
|
+
const sourceLength = input?.length ?? 0;
|
|
7431
|
+
if (sourceLength === 0) {
|
|
7432
|
+
return targetCount == null ? new Float32Array() : createSilentSamples(targetCount);
|
|
7433
|
+
}
|
|
7434
|
+
const normalized = new Float32Array(sourceLength);
|
|
7435
|
+
let maxAbs = 0;
|
|
7436
|
+
for (let i = 0; i < sourceLength; i += 1) {
|
|
7437
|
+
const value = Number(input?.[i]);
|
|
7438
|
+
const sample = Number.isFinite(value) ? value : 0;
|
|
7439
|
+
normalized[i] = sample;
|
|
7440
|
+
maxAbs = Math.max(maxAbs, Math.abs(sample));
|
|
7441
|
+
}
|
|
7442
|
+
const divisor = maxAbs > 1 ? maxAbs : 1;
|
|
7443
|
+
for (let i = 0; i < normalized.length; i += 1) {
|
|
7444
|
+
normalized[i] = clamp(normalized[i] / divisor, -1, 1);
|
|
7445
|
+
}
|
|
7446
|
+
if (targetCount == null || targetCount === normalized.length) {
|
|
7447
|
+
return normalized;
|
|
7448
|
+
}
|
|
7449
|
+
return resampleWaveformSamples(normalized, targetCount);
|
|
7450
|
+
}
|
|
7451
|
+
function resampleWaveformSamples(samples, targetCount) {
|
|
7452
|
+
const count = normalizeBarCount(targetCount);
|
|
7453
|
+
const sourceLength = samples.length;
|
|
7454
|
+
if (sourceLength === 0) return createSilentSamples(count);
|
|
7455
|
+
if (sourceLength === count) return Float32Array.from(samples);
|
|
7456
|
+
const output = new Float32Array(count);
|
|
7457
|
+
for (let i = 0; i < count; i += 1) {
|
|
7458
|
+
const start = i * sourceLength / count;
|
|
7459
|
+
const end = (i + 1) * sourceLength / count;
|
|
7460
|
+
const firstIndex = Math.floor(start);
|
|
7461
|
+
const lastIndex = Math.max(firstIndex + 1, Math.ceil(end));
|
|
7462
|
+
let total = 0;
|
|
7463
|
+
let values = 0;
|
|
7464
|
+
for (let j = firstIndex; j < lastIndex && j < sourceLength; j += 1) {
|
|
7465
|
+
total += Number(samples[j]);
|
|
7466
|
+
values += 1;
|
|
7467
|
+
}
|
|
7468
|
+
output[i] = values > 0 ? total / values : Number(samples[Math.min(firstIndex, sourceLength - 1)]);
|
|
7469
|
+
}
|
|
7470
|
+
return output;
|
|
7471
|
+
}
|
|
7472
|
+
function smoothWaveformSamples(previous, next, smoothing = DEFAULT_WAVEFORM_SMOOTHING) {
|
|
7473
|
+
if (previous == null || previous.length === 0) {
|
|
7474
|
+
return Float32Array.from(next);
|
|
7475
|
+
}
|
|
7476
|
+
const amount = normalizeSmoothing(smoothing);
|
|
7477
|
+
const output = new Float32Array(next.length);
|
|
7478
|
+
for (let i = 0; i < next.length; i += 1) {
|
|
7479
|
+
const previousValue = Number(previous[i] ?? next[i]);
|
|
7480
|
+
output[i] = previousValue * amount + Number(next[i]) * (1 - amount);
|
|
7481
|
+
}
|
|
7482
|
+
return output;
|
|
7483
|
+
}
|
|
7484
|
+
function scaleWaveformSamples(samples, intensity = DEFAULT_WAVEFORM_INTENSITY) {
|
|
7485
|
+
const amount = normalizeIntensity(intensity);
|
|
7486
|
+
const output = new Float32Array(samples.length);
|
|
7487
|
+
for (let i = 0; i < samples.length; i += 1) {
|
|
7488
|
+
output[i] = clamp(Number(samples[i]) * amount, -1, 1);
|
|
7489
|
+
}
|
|
7490
|
+
return output;
|
|
7491
|
+
}
|
|
7492
|
+
function getWaveformPeak(samples) {
|
|
7493
|
+
let peak = 0;
|
|
7494
|
+
for (let i = 0; i < samples.length; i += 1) {
|
|
7495
|
+
peak = Math.max(peak, Math.abs(Number(samples[i]) || 0));
|
|
7496
|
+
}
|
|
7497
|
+
return Math.min(1, peak);
|
|
7498
|
+
}
|
|
7499
|
+
function toCssDimension(value) {
|
|
7500
|
+
if (value == null) return void 0;
|
|
7501
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
7502
|
+
}
|
|
7503
|
+
function createWaveform(props = {}) {
|
|
7504
|
+
const config = normalizeWaveformConfig(props);
|
|
7505
|
+
const inputSamples = props.samples ?? (isWaveformSampleInput(props.source) ? props.source : void 0);
|
|
7506
|
+
const samples = inputSamples == null ? createIntensitySamples(config.intensity, config.barCount) : normalizeWaveformSamples(inputSamples, config.barCount);
|
|
7507
|
+
return {
|
|
7508
|
+
config,
|
|
7509
|
+
samples,
|
|
7510
|
+
ariaProps: {
|
|
7511
|
+
role: "img",
|
|
7512
|
+
"aria-label": "Audio waveform"
|
|
7513
|
+
},
|
|
7514
|
+
dataAttributes: {
|
|
7515
|
+
"data-variant": config.variant,
|
|
7516
|
+
"data-paused": String(config.paused)
|
|
7517
|
+
},
|
|
7518
|
+
getSamples(barCount = config.barCount) {
|
|
7519
|
+
return inputSamples == null ? createIntensitySamples(config.intensity, barCount) : normalizeWaveformSamples(inputSamples, barCount);
|
|
7520
|
+
}
|
|
7521
|
+
};
|
|
7522
|
+
}
|
|
7523
|
+
function clamp(value, min, max) {
|
|
7524
|
+
return Math.min(max, Math.max(min, value));
|
|
7525
|
+
}
|
|
7526
|
+
function prepareWaveformCanvas(canvas, size) {
|
|
7527
|
+
const width = Math.max(1, Math.floor(size.width));
|
|
7528
|
+
const height = Math.max(1, Math.floor(size.height));
|
|
7529
|
+
const pixelRatio = Math.max(1, size.pixelRatio ?? 1);
|
|
7530
|
+
const pixelWidth = Math.floor(width * pixelRatio);
|
|
7531
|
+
const pixelHeight = Math.floor(height * pixelRatio);
|
|
7532
|
+
if (canvas.width !== pixelWidth) {
|
|
7533
|
+
canvas.width = pixelWidth;
|
|
7534
|
+
}
|
|
7535
|
+
if (canvas.height !== pixelHeight) {
|
|
7536
|
+
canvas.height = pixelHeight;
|
|
7537
|
+
}
|
|
7538
|
+
const context = canvas.getContext("2d");
|
|
7539
|
+
if (!context) return null;
|
|
7540
|
+
context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
|
|
7541
|
+
return context;
|
|
7542
|
+
}
|
|
7543
|
+
function drawWaveform(context, samples, size, options = {}) {
|
|
7544
|
+
const width = Math.max(1, Math.floor(size.width));
|
|
7545
|
+
const height = Math.max(1, Math.floor(size.height));
|
|
7546
|
+
const variant = options.variant ?? "bars";
|
|
7547
|
+
const color = options.color ?? DEFAULT_WAVEFORM_COLOR;
|
|
7548
|
+
const intensity = normalizeIntensity(options.intensity ?? DEFAULT_WAVEFORM_INTENSITY);
|
|
7549
|
+
const barCount = normalizeBarCount(options.barCount);
|
|
7550
|
+
context.clearRect(0, 0, width, height);
|
|
7551
|
+
applyCanvasColor(context, color);
|
|
7552
|
+
if (variant === "line") {
|
|
7553
|
+
drawLine(context, samples, width, height, intensity);
|
|
7554
|
+
return;
|
|
7555
|
+
}
|
|
7556
|
+
if (variant === "rings") {
|
|
7557
|
+
drawRings(context, samples, width, height, intensity);
|
|
7558
|
+
return;
|
|
7559
|
+
}
|
|
7560
|
+
drawBars(context, samples, width, height, intensity, barCount);
|
|
7561
|
+
}
|
|
7562
|
+
function drawBars(context, samples, width, height, intensity, barCount) {
|
|
7563
|
+
const bars = scaleWaveformSamples(resampleWaveformSamples(samples, barCount), intensity);
|
|
7564
|
+
const slotWidth = width / bars.length;
|
|
7565
|
+
const barWidth = Math.max(1, slotWidth * 0.64);
|
|
7566
|
+
const center = height / 2;
|
|
7567
|
+
for (let i = 0; i < bars.length; i += 1) {
|
|
7568
|
+
const value = Math.abs(bars[i]);
|
|
7569
|
+
const barHeight = Math.max(value * height, value > 0 ? 1 : 0);
|
|
7570
|
+
const x = i * slotWidth + (slotWidth - barWidth) / 2;
|
|
7571
|
+
const y = center - barHeight / 2;
|
|
7572
|
+
context.fillRect(x, y, barWidth, barHeight);
|
|
7573
|
+
}
|
|
7574
|
+
}
|
|
7575
|
+
function drawLine(context, samples, width, height, intensity) {
|
|
7576
|
+
const lineSamples = scaleWaveformSamples(samples, intensity);
|
|
7577
|
+
const center = height / 2;
|
|
7578
|
+
const amplitude = height * 0.45;
|
|
7579
|
+
context.beginPath();
|
|
7580
|
+
for (let i = 0; i < lineSamples.length; i += 1) {
|
|
7581
|
+
const x = lineSamples.length <= 1 ? width / 2 : i / (lineSamples.length - 1) * width;
|
|
7582
|
+
const y = center - Number(lineSamples[i]) * amplitude;
|
|
7583
|
+
if (i === 0) {
|
|
7584
|
+
context.moveTo(x, y);
|
|
7585
|
+
} else {
|
|
7586
|
+
context.lineTo(x, y);
|
|
7587
|
+
}
|
|
7588
|
+
}
|
|
7589
|
+
context.lineWidth = Math.max(1.5, Math.min(width, height) * 0.025);
|
|
7590
|
+
context.lineCap = "round";
|
|
7591
|
+
context.lineJoin = "round";
|
|
7592
|
+
context.stroke();
|
|
7593
|
+
}
|
|
7594
|
+
function drawRings(context, samples, width, height, intensity) {
|
|
7595
|
+
const peak = getWaveformPeak(scaleWaveformSamples(samples, intensity));
|
|
7596
|
+
const minDimension = Math.min(width, height);
|
|
7597
|
+
const centerX = width / 2;
|
|
7598
|
+
const centerY = height / 2;
|
|
7599
|
+
const ringCount = 3;
|
|
7600
|
+
const baseRadius = minDimension * 0.16;
|
|
7601
|
+
const radiusStep = minDimension * 0.13;
|
|
7602
|
+
context.save();
|
|
7603
|
+
context.lineWidth = Math.max(1.5, minDimension * 0.018);
|
|
7604
|
+
for (let i = 0; i < ringCount; i += 1) {
|
|
7605
|
+
const progress = (i + 1) / ringCount;
|
|
7606
|
+
const pulse = peak * minDimension * 0.1 * progress;
|
|
7607
|
+
const radius = baseRadius + radiusStep * i + pulse;
|
|
7608
|
+
context.globalAlpha = 0.28 + progress * 0.34;
|
|
7609
|
+
context.beginPath();
|
|
7610
|
+
context.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
|
7611
|
+
context.stroke();
|
|
7612
|
+
}
|
|
7613
|
+
context.restore();
|
|
7614
|
+
}
|
|
7615
|
+
function applyCanvasColor(context, color) {
|
|
7616
|
+
try {
|
|
7617
|
+
context.fillStyle = color;
|
|
7618
|
+
context.strokeStyle = color;
|
|
7619
|
+
} catch {
|
|
7620
|
+
context.fillStyle = "#000";
|
|
7621
|
+
context.strokeStyle = "#000";
|
|
7622
|
+
}
|
|
7623
|
+
}
|
|
7624
|
+
var waveformVariants = cva({
|
|
7625
|
+
base: "relative block overflow-hidden",
|
|
7626
|
+
variants: {
|
|
7627
|
+
variant: {
|
|
7628
|
+
bars: "",
|
|
7629
|
+
line: "",
|
|
7630
|
+
rings: ""
|
|
7631
|
+
}
|
|
7632
|
+
},
|
|
7633
|
+
defaultVariants: {
|
|
7634
|
+
variant: "bars"
|
|
7635
|
+
}
|
|
7636
|
+
});
|
|
7637
|
+
var waveformCanvasVariants = cva({
|
|
7638
|
+
base: "block h-full w-full"
|
|
7639
|
+
});
|
|
7640
|
+
var Waveform = React11.forwardRef(
|
|
7641
|
+
({
|
|
7642
|
+
source,
|
|
7643
|
+
samples,
|
|
7644
|
+
intensity,
|
|
7645
|
+
variant,
|
|
7646
|
+
height,
|
|
7647
|
+
width,
|
|
7648
|
+
barCount,
|
|
7649
|
+
smoothing,
|
|
7650
|
+
color,
|
|
7651
|
+
paused,
|
|
7652
|
+
className,
|
|
7653
|
+
style,
|
|
7654
|
+
...props
|
|
7655
|
+
}, ref) => {
|
|
7656
|
+
const rootRef = React11.useRef(null);
|
|
7657
|
+
const canvasRef = React11.useRef(null);
|
|
7658
|
+
const previousSamplesRef = React11.useRef(null);
|
|
7659
|
+
const mediaAnalyserRef = React11.useRef(null);
|
|
7660
|
+
const floatBufferRef = React11.useRef(null);
|
|
7661
|
+
const byteBufferRef = React11.useRef(null);
|
|
7662
|
+
const prefersReducedMotion = usePrefersReducedMotion();
|
|
7663
|
+
const api = createWaveform({
|
|
7664
|
+
source,
|
|
7665
|
+
samples,
|
|
7666
|
+
intensity,
|
|
7667
|
+
variant,
|
|
7668
|
+
height,
|
|
7669
|
+
width,
|
|
7670
|
+
barCount,
|
|
7671
|
+
smoothing,
|
|
7672
|
+
color,
|
|
7673
|
+
paused
|
|
7674
|
+
});
|
|
7675
|
+
const rootStyle = React11.useMemo(
|
|
7676
|
+
() => ({
|
|
7677
|
+
...style,
|
|
7678
|
+
width: toCssDimension(width) ?? style?.width ?? "100%",
|
|
7679
|
+
height: toCssDimension(height) ?? style?.height ?? `${api.config.height}px`,
|
|
7680
|
+
"--waveform-color": api.config.color
|
|
7681
|
+
}),
|
|
7682
|
+
[api.config.color, api.config.height, height, style, width]
|
|
7683
|
+
);
|
|
7684
|
+
const setRootRef = React11.useCallback(
|
|
7685
|
+
(node) => {
|
|
7686
|
+
rootRef.current = node;
|
|
7687
|
+
if (typeof ref === "function") {
|
|
7688
|
+
ref(node);
|
|
7689
|
+
} else if (ref) {
|
|
7690
|
+
ref.current = node;
|
|
7691
|
+
}
|
|
7692
|
+
},
|
|
7693
|
+
[ref]
|
|
7694
|
+
);
|
|
7695
|
+
React11.useEffect(() => {
|
|
7696
|
+
if (!isMediaStreamSource(source)) {
|
|
7697
|
+
mediaAnalyserRef.current = null;
|
|
7698
|
+
return;
|
|
7699
|
+
}
|
|
7700
|
+
if (typeof window === "undefined") return;
|
|
7701
|
+
const AudioContextClass = window.AudioContext ?? window.webkitAudioContext;
|
|
7702
|
+
if (!AudioContextClass) return;
|
|
7703
|
+
const audioContext = new AudioContextClass();
|
|
7704
|
+
const analyser = audioContext.createAnalyser();
|
|
7705
|
+
const streamSource = audioContext.createMediaStreamSource(source);
|
|
7706
|
+
analyser.smoothingTimeConstant = normalizeSmoothing(api.config.smoothing);
|
|
7707
|
+
streamSource.connect(analyser);
|
|
7708
|
+
mediaAnalyserRef.current = analyser;
|
|
7709
|
+
return () => {
|
|
7710
|
+
mediaAnalyserRef.current = null;
|
|
7711
|
+
streamSource.disconnect();
|
|
7712
|
+
analyser.disconnect();
|
|
7713
|
+
if (audioContext.state !== "closed") {
|
|
7714
|
+
void audioContext.close();
|
|
7715
|
+
}
|
|
7716
|
+
};
|
|
7717
|
+
}, [api.config.smoothing, source]);
|
|
7718
|
+
React11.useEffect(() => {
|
|
7719
|
+
if (isAnalyserSource(source)) {
|
|
7720
|
+
source.smoothingTimeConstant = normalizeSmoothing(api.config.smoothing);
|
|
7721
|
+
}
|
|
7722
|
+
}, [api.config.smoothing, source]);
|
|
7723
|
+
React11.useEffect(() => {
|
|
7724
|
+
const root = rootRef.current;
|
|
7725
|
+
const canvas = canvasRef.current;
|
|
7726
|
+
if (!root || !canvas) return;
|
|
7727
|
+
let size = measureWaveform(root, api.config.width, api.config.height);
|
|
7728
|
+
let frame = null;
|
|
7729
|
+
let disposed = false;
|
|
7730
|
+
const cancelFrame = () => {
|
|
7731
|
+
if (frame == null) return;
|
|
7732
|
+
if (typeof window.requestAnimationFrame === "function") {
|
|
7733
|
+
window.cancelAnimationFrame(frame);
|
|
7734
|
+
} else {
|
|
7735
|
+
clearTimeout(frame);
|
|
7736
|
+
}
|
|
7737
|
+
frame = null;
|
|
7738
|
+
};
|
|
7739
|
+
const readSamples = () => {
|
|
7740
|
+
if (samples != null) {
|
|
7741
|
+
return normalizeWaveformSamples(samples, api.config.barCount);
|
|
7742
|
+
}
|
|
7743
|
+
if (isWaveformSampleInput(source)) {
|
|
7744
|
+
return normalizeWaveformSamples(source, api.config.barCount);
|
|
7745
|
+
}
|
|
7746
|
+
const analyser = isAnalyserSource(source) ? source : mediaAnalyserRef.current;
|
|
7747
|
+
if (analyser) {
|
|
7748
|
+
return readAnalyserSamples(analyser, api.config.barCount, floatBufferRef, byteBufferRef);
|
|
7749
|
+
}
|
|
7750
|
+
return createIntensitySamples(api.config.intensity, api.config.barCount);
|
|
7751
|
+
};
|
|
7752
|
+
const draw = () => {
|
|
7753
|
+
const context = prepareWaveformCanvas(canvas, {
|
|
7754
|
+
...size,
|
|
7755
|
+
pixelRatio: window.devicePixelRatio || 1
|
|
7756
|
+
});
|
|
7757
|
+
if (!context) return;
|
|
7758
|
+
const nextSamples = readSamples();
|
|
7759
|
+
const renderedSamples = smoothWaveformSamples(
|
|
7760
|
+
previousSamplesRef.current ?? void 0,
|
|
7761
|
+
nextSamples,
|
|
7762
|
+
api.config.smoothing
|
|
7763
|
+
);
|
|
7764
|
+
previousSamplesRef.current = renderedSamples;
|
|
7765
|
+
drawWaveform(context, renderedSamples, size, {
|
|
7766
|
+
variant: api.config.variant,
|
|
7767
|
+
color: resolveCanvasColor(root, api.config.color),
|
|
7768
|
+
intensity: api.config.intensity,
|
|
7769
|
+
barCount: api.config.barCount
|
|
7770
|
+
});
|
|
7771
|
+
};
|
|
7772
|
+
const schedule = () => {
|
|
7773
|
+
if (disposed || api.config.paused || prefersReducedMotion) return;
|
|
7774
|
+
if (typeof window.requestAnimationFrame === "function") {
|
|
7775
|
+
frame = window.requestAnimationFrame(tick);
|
|
7776
|
+
} else {
|
|
7777
|
+
frame = window.setTimeout(() => tick(), 16);
|
|
7778
|
+
}
|
|
7779
|
+
};
|
|
7780
|
+
const tick = () => {
|
|
7781
|
+
draw();
|
|
7782
|
+
schedule();
|
|
7783
|
+
};
|
|
7784
|
+
draw();
|
|
7785
|
+
schedule();
|
|
7786
|
+
const observer = typeof ResizeObserver === "function" ? new ResizeObserver(() => {
|
|
7787
|
+
size = measureWaveform(root, api.config.width, api.config.height);
|
|
7788
|
+
draw();
|
|
7789
|
+
}) : null;
|
|
7790
|
+
observer?.observe(root);
|
|
7791
|
+
return () => {
|
|
7792
|
+
disposed = true;
|
|
7793
|
+
cancelFrame();
|
|
7794
|
+
observer?.disconnect();
|
|
7795
|
+
};
|
|
7796
|
+
}, [
|
|
7797
|
+
api.config.barCount,
|
|
7798
|
+
api.config.color,
|
|
7799
|
+
api.config.height,
|
|
7800
|
+
api.config.intensity,
|
|
7801
|
+
api.config.paused,
|
|
7802
|
+
api.config.smoothing,
|
|
7803
|
+
api.config.variant,
|
|
7804
|
+
api.config.width,
|
|
7805
|
+
prefersReducedMotion,
|
|
7806
|
+
samples,
|
|
7807
|
+
source
|
|
7808
|
+
]);
|
|
7809
|
+
return /* @__PURE__ */ jsx(
|
|
7810
|
+
"div",
|
|
7811
|
+
{
|
|
7812
|
+
ref: setRootRef,
|
|
7813
|
+
className: cn(waveformVariants({ variant: api.config.variant }), className),
|
|
7814
|
+
style: rootStyle,
|
|
7815
|
+
...api.ariaProps,
|
|
7816
|
+
...api.dataAttributes,
|
|
7817
|
+
...props,
|
|
7818
|
+
children: /* @__PURE__ */ jsx(
|
|
7819
|
+
"canvas",
|
|
7820
|
+
{
|
|
7821
|
+
ref: canvasRef,
|
|
7822
|
+
className: waveformCanvasVariants(),
|
|
7823
|
+
"aria-hidden": "true",
|
|
7824
|
+
"data-waveform-canvas": ""
|
|
7825
|
+
}
|
|
7826
|
+
)
|
|
7827
|
+
}
|
|
7828
|
+
);
|
|
7829
|
+
}
|
|
7830
|
+
);
|
|
7831
|
+
Waveform.displayName = "Waveform";
|
|
7832
|
+
function usePrefersReducedMotion() {
|
|
7833
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = React11.useState(false);
|
|
7834
|
+
React11.useEffect(() => {
|
|
7835
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
7836
|
+
return;
|
|
7837
|
+
}
|
|
7838
|
+
const media = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
7839
|
+
const update = () => setPrefersReducedMotion(media.matches);
|
|
7840
|
+
update();
|
|
7841
|
+
media.addEventListener?.("change", update);
|
|
7842
|
+
return () => {
|
|
7843
|
+
media.removeEventListener?.("change", update);
|
|
7844
|
+
};
|
|
7845
|
+
}, []);
|
|
7846
|
+
return prefersReducedMotion;
|
|
7847
|
+
}
|
|
7848
|
+
function readAnalyserSamples(analyser, barCount, floatBufferRef, byteBufferRef) {
|
|
7849
|
+
if (typeof analyser.getFloatTimeDomainData === "function") {
|
|
7850
|
+
const length2 = Math.max(1, analyser.fftSize || analyser.frequencyBinCount || barCount);
|
|
7851
|
+
if (floatBufferRef.current?.length !== length2) {
|
|
7852
|
+
floatBufferRef.current = new Float32Array(length2);
|
|
7853
|
+
}
|
|
7854
|
+
analyser.getFloatTimeDomainData(floatBufferRef.current);
|
|
7855
|
+
return normalizeWaveformSamples(floatBufferRef.current, barCount);
|
|
7856
|
+
}
|
|
7857
|
+
const length = Math.max(1, analyser.frequencyBinCount || barCount);
|
|
7858
|
+
if (byteBufferRef.current?.length !== length) {
|
|
7859
|
+
byteBufferRef.current = new Uint8Array(length);
|
|
7860
|
+
}
|
|
7861
|
+
analyser.getByteFrequencyData(byteBufferRef.current);
|
|
7862
|
+
return normalizeWaveformSamples(Array.from(byteBufferRef.current), barCount);
|
|
7863
|
+
}
|
|
7864
|
+
function measureWaveform(element, width, height) {
|
|
7865
|
+
const rect = element.getBoundingClientRect();
|
|
7866
|
+
const fallbackWidth = typeof width === "number" ? width : 300;
|
|
7867
|
+
const fallbackHeight = typeof height === "number" ? height : 80;
|
|
7868
|
+
return {
|
|
7869
|
+
width: Math.max(1, Math.round(rect.width || element.clientWidth || fallbackWidth)),
|
|
7870
|
+
height: Math.max(1, Math.round(rect.height || element.clientHeight || fallbackHeight))
|
|
7871
|
+
};
|
|
7872
|
+
}
|
|
7873
|
+
function resolveCanvasColor(element, color) {
|
|
7874
|
+
const variableMatch = color.match(/^var\((--[^),\s]+)(?:,[^)]+)?\)$/);
|
|
7875
|
+
if (!variableMatch || typeof window.getComputedStyle !== "function") {
|
|
7876
|
+
return color;
|
|
7877
|
+
}
|
|
7878
|
+
const value = window.getComputedStyle(element).getPropertyValue(variableMatch[1]).trim();
|
|
7879
|
+
return value || color;
|
|
7880
|
+
}
|
|
7881
|
+
function isAnalyserSource(value) {
|
|
7882
|
+
return value != null && typeof value.frequencyBinCount === "number" && (typeof value.getFloatTimeDomainData === "function" || typeof value.getByteFrequencyData === "function");
|
|
7883
|
+
}
|
|
7884
|
+
function isMediaStreamSource(value) {
|
|
7885
|
+
return value != null && typeof value.getTracks === "function";
|
|
7886
|
+
}
|
|
7887
|
+
|
|
7096
7888
|
// ../progress-display/dist/index.js
|
|
7097
7889
|
function createProgressDisplay(props) {
|
|
7098
7890
|
const { stats, badges } = props;
|
|
@@ -8046,7 +8838,7 @@ function VersionSelector({
|
|
|
8046
8838
|
VersionSelector.displayName = "VersionSelector";
|
|
8047
8839
|
|
|
8048
8840
|
// ../resizable-layout/dist/index.js
|
|
8049
|
-
function
|
|
8841
|
+
function clamp2(value, min, max) {
|
|
8050
8842
|
return Math.min(Math.max(value, min), max);
|
|
8051
8843
|
}
|
|
8052
8844
|
function createResizableLayout(props = {}) {
|
|
@@ -8101,9 +8893,9 @@ function createResizableLayout(props = {}) {
|
|
|
8101
8893
|
if (j >= sizes.length) return;
|
|
8102
8894
|
const totalAvailable = sizesBeforeResize[i] + sizesBeforeResize[j];
|
|
8103
8895
|
let newSizeI = sizesBeforeResize[i] + delta;
|
|
8104
|
-
newSizeI =
|
|
8896
|
+
newSizeI = clamp2(newSizeI, getMinSize(i), getMaxSize(i));
|
|
8105
8897
|
let newSizeJ = totalAvailable - newSizeI;
|
|
8106
|
-
newSizeJ =
|
|
8898
|
+
newSizeJ = clamp2(newSizeJ, getMinSize(j), getMaxSize(j));
|
|
8107
8899
|
newSizeI = totalAvailable - newSizeJ;
|
|
8108
8900
|
sizes[i] = newSizeI;
|
|
8109
8901
|
sizes[j] = newSizeJ;
|
|
@@ -12819,6 +13611,6 @@ var PaymentButton = React11.forwardRef(
|
|
|
12819
13611
|
);
|
|
12820
13612
|
PaymentButton.displayName = "PaymentButton";
|
|
12821
13613
|
|
|
12822
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AltHintState, AnimatedText, AppShell, AuthGuard, AuthProvider, Avatar, AvatarFallback, AvatarGroup, AvatarImage, Badge, BadgeDisplay, BottomNav, Breadcrumbs, Button, CATEGORY_LABELS, Calendar, CalendarHeader, Callout, CalloutContent, CalloutDescription, CalloutIcon, CalloutTitle, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselTrigger, Checkbox, CodeBlock, CodeBlockContent, CodeBlockHeader, CodeEditor, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList, ComboboxTrigger, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, ContentProtection, DataTable, DatePicker, DeviceFrame, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, EMOJI_CATEGORIES, EMOJI_DATA, EmojiPicker, FeedbackButton, FeedbackDialog, FileTree, FileUpload, Footer, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, IconSystem, InlineEditor, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, InstallPrompt, KeyboardShortcut, LanguageSelector, LinkCard, MarkdownRenderer, MobileNav, MobileNavContent, MobileNavLink, MobileNavTrigger, Navbar, OtpInput, STATUS_COLORS as PRESENCE_STATUS_COLORS, STATUS_LABELS as PRESENCE_STATUS_LABELS, Pagination, Payment, Popover, PopoverClose, PopoverContent, PopoverTrigger, PresenceIndicator, ProgressBar, RadioGroup, RadioItem, ReactionBar, ResizableDivider, ResizableLayout, ResizablePane, SANE_DEFAULTS, STATUS_INDICATOR_COLORS as STATUS_COLORS, STATUS_INDICATOR_LABELS as STATUS_LABELS, SearchBar, SearchResultItem, SearchResults, Select, SelectContent, SelectItem, SelectTrigger, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetTitle, SheetTrigger, ShortcutBadge, ShortcutContext, ShortcutHint, ShortcutProvider, ShortcutRegistry, Sidebar, Skeleton, SkeletonText, SkipToContent, SlideViewer, Slot, StatsGrid, StatusIndicator, Step, StepContent, StepDescription, StepIndicator, StepTitle, Steps, Switch, TableOfContents, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThreadView, Toast, ToastProvider, Toaster, Tooltip, TooltipContent, TooltipTrigger, TypewriterText, VersionSelector, VideoPlayer, altHintState, animatedTextVariants, avatarFallbackVariants, avatarImageVariants, avatarTokens, avatarVariants, badgeGridVariants, badgeItemVariants, badgeVariants, bottomNavTabVariants, bottomNavVariants, breadcrumbItemVariants, breadcrumbSeparatorStyles, breadcrumbsVariants, buttonTokens, buttonVariants, calendarVariants, canAccessAdmin, canAccessReviewer, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardTokens, cardVariants, cellVariants, checkIconPath, checkboxTokens, checkboxVariants, codeEditorTokens, codeEditorVariants, collapsibleContentVariants, comboboxContentVariants, comboboxEmptyVariants, comboboxInputVariants, comboboxItemVariants, comboboxListVariants, comboboxTriggerVariants, commandGroupVariants, commandInputVariants, commandItemVariants, commandVariants, contentProtectionVariants, controlsVariants, dayVariants, deviceFrameVariants, dialogContentVariants, editorVariants, emojiPickerContainerStyles, emojiPickerEmojiButtonStyles, emojiPickerGridStyles, feedbackDialogVariants, fileUploadDropZoneVariants, fileUploadFileItemStyles, fileUploadFileListStyles, footerVariants, formItemVariants, formLabelVariants, formatFileSize, formatRelativeTime, formatShortcut, formatTimestamp, getAssignableRoles, getDefaultPortal, getInitials, globalShortcutRegistry, hasAllRoles, hasAnyRole, hasRole, headerVariants, indeterminateIconPath, inputGroupAddonVariants, inputGroupButtonVariants, inputGroupTokens, inputGroupVariants, inputVariants, installPromptVariants, latestBadgeVariants, markdownRendererTokens, menuContentVariants, menuItemVariants, mobileNavContentVariants, mobileNavLinkVariants, mobileNavTokens, mobileNavTriggerVariants, mobileNavVariants, navLinkVariants, navbarVariants, optionVariants, otpInputContainerVariants, otpInputSlotVariants, otpInputTokens, overlayStyles, overlayVariants, playerVariants, popoverContentVariants, previewVariants, progressBarVariants, proseVariants, radioCircleVariants, radioGroupVariants, radioItemVariants, reactionAddButtonStyles, reactionBarStyles, reactionCountStyles, reactionEmojiStyles, reactionPillVariants, resizableDividerVariants, resizableLayoutTokens, resizableLayoutVariants, resizablePaneVariants, rowVariants, searchBarVariants, searchResultVariants, selectContentVariants, selectItemVariants, selectTokens, selectTriggerVariants, selectorVariants, sheetContentVariants, sheetOverlayStyles, shortcutBadgeStyles, shortcutKeyStyles, shortcutSeparatorStyles, sidebarItemVariants, sidebarVariants, skeletonVariants, slideTypeBadgeVariants, slideViewerProgressBarVariants, slideViewerTokens, slideViewerVariants, statCardVariants, statsGridVariants, statusContainerStyles, statusDotVariants, statusLabelStyles, statusPulseVariants, switchThumbVariants, switchTokens, switchVariants, tableVariants, tabsListVariants, tabsTriggerVariants, textareaVariants, threadAuthorStyles, threadAvatarStyles, threadBodyStyles, threadContainerStyles, threadContentStyles, threadMessageStyles, threadReactionsStyles, threadTimestampStyles, toastVariants, toolbarVariants, tooltipContentVariants, typewriterVariants, useAuth, useFormField, useShortcut, useToast, versionSelectorOptionVariants, versionSelectorVariants, watermarkVariants };
|
|
13614
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AltHintState, AnimatedText, AppShell, AuthGuard, AuthProvider, Avatar, AvatarFallback, AvatarGroup, AvatarImage, Badge, BadgeDisplay, BottomNav, Breadcrumbs, Button, CATEGORY_LABELS, Calendar, CalendarHeader, Callout, CalloutContent, CalloutDescription, CalloutIcon, CalloutTitle, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselTrigger, Checkbox, CodeBlock, CodeBlockContent, CodeBlockHeader, CodeEditor, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList, ComboboxTrigger, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, ContentProtection, DEFAULT_VOICE_PILL_POSITION, DEFAULT_VOICE_PILL_SPEAKER, DEFAULT_WAVEFORM_BAR_COUNT, DEFAULT_WAVEFORM_COLOR, DEFAULT_WAVEFORM_HEIGHT, DEFAULT_WAVEFORM_INTENSITY, DEFAULT_WAVEFORM_SMOOTHING, DataTable, DatePicker, DeviceFrame, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, EMOJI_CATEGORIES, EMOJI_DATA, EmojiPicker, FeedbackButton, FeedbackDialog, FileTree, FileUpload, Footer, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, IconSystem, InlineEditor, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, InstallPrompt, KeyboardShortcut, LanguageSelector, LinkCard, MarkdownRenderer, MobileNav, MobileNavContent, MobileNavLink, MobileNavTrigger, Navbar, OtpInput, STATUS_COLORS as PRESENCE_STATUS_COLORS, STATUS_LABELS as PRESENCE_STATUS_LABELS, Pagination, Payment, Popover, PopoverClose, PopoverContent, PopoverTrigger, PresenceIndicator, ProgressBar, RadioGroup, RadioItem, ReactionBar, ResizableDivider, ResizableLayout, ResizablePane, SANE_DEFAULTS, STATUS_INDICATOR_COLORS as STATUS_COLORS, STATUS_INDICATOR_LABELS as STATUS_LABELS, SearchBar, SearchResultItem, SearchResults, Select, SelectContent, SelectItem, SelectTrigger, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetTitle, SheetTrigger, ShortcutBadge, ShortcutContext, ShortcutHint, ShortcutProvider, ShortcutRegistry, Sidebar, Skeleton, SkeletonText, SkipToContent, SlideViewer, Slot, StatsGrid, StatusIndicator, Step, StepContent, StepDescription, StepIndicator, StepTitle, Steps, Switch, TableOfContents, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThreadView, Toast, ToastProvider, Toaster, Tooltip, TooltipContent, TooltipTrigger, TypewriterText, VersionSelector, VideoPlayer, VoicePill, Waveform, altHintState, animatedTextVariants, avatarFallbackVariants, avatarImageVariants, avatarTokens, avatarVariants, badgeGridVariants, badgeItemVariants, badgeVariants, bottomNavTabVariants, bottomNavVariants, breadcrumbItemVariants, breadcrumbSeparatorStyles, breadcrumbsVariants, buttonTokens, buttonVariants, calendarVariants, canAccessAdmin, canAccessReviewer, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardTokens, cardVariants, cellVariants, checkIconPath, checkboxTokens, checkboxVariants, clampVoicePillIntensity, codeEditorTokens, codeEditorVariants, collapsibleContentVariants, comboboxContentVariants, comboboxEmptyVariants, comboboxInputVariants, comboboxItemVariants, comboboxListVariants, comboboxTriggerVariants, commandGroupVariants, commandInputVariants, commandItemVariants, commandVariants, contentProtectionVariants, controlsVariants, createIntensitySamples, createSilentSamples, createVoicePill, createWaveform, dayVariants, deviceFrameVariants, dialogContentVariants, drawWaveform, editorVariants, emojiPickerContainerStyles, emojiPickerEmojiButtonStyles, emojiPickerGridStyles, feedbackDialogVariants, fileUploadDropZoneVariants, fileUploadFileItemStyles, fileUploadFileListStyles, footerVariants, formItemVariants, formLabelVariants, formatFileSize, formatRelativeTime, formatShortcut, formatTimestamp, getAssignableRoles, getDefaultPortal, getInitials, getVoicePillAriaLabel, getVoicePillInitials, getVoicePillPosition, getVoicePillPulseStyle, getVoicePillSpeakerKey, getVoicePillSpeakerLabel, getWaveformPeak, globalShortcutRegistry, hasAllRoles, hasAnyRole, hasRole, headerVariants, indeterminateIconPath, inputGroupAddonVariants, inputGroupButtonVariants, inputGroupTokens, inputGroupVariants, inputVariants, installPromptVariants, isWaveformSampleInput, latestBadgeVariants, markdownRendererTokens, menuContentVariants, menuItemVariants, mobileNavContentVariants, mobileNavLinkVariants, mobileNavTokens, mobileNavTriggerVariants, mobileNavVariants, navLinkVariants, navbarVariants, normalizeBarCount, normalizeIntensity, normalizeSmoothing, normalizeWaveformConfig, normalizeWaveformSamples, optionVariants, otpInputContainerVariants, otpInputSlotVariants, otpInputTokens, overlayStyles, overlayVariants, playerVariants, popoverContentVariants, prepareWaveformCanvas, previewVariants, progressBarVariants, proseVariants, radioCircleVariants, radioGroupVariants, radioItemVariants, reactionAddButtonStyles, reactionBarStyles, reactionCountStyles, reactionEmojiStyles, reactionPillVariants, resampleWaveformSamples, resizableDividerVariants, resizableLayoutTokens, resizableLayoutVariants, resizablePaneVariants, rowVariants, scaleWaveformSamples, searchBarVariants, searchResultVariants, selectContentVariants, selectItemVariants, selectTokens, selectTriggerVariants, selectorVariants, sheetContentVariants, sheetOverlayStyles, shortcutBadgeStyles, shortcutKeyStyles, shortcutSeparatorStyles, sidebarItemVariants, sidebarVariants, skeletonVariants, slideTypeBadgeVariants, slideViewerProgressBarVariants, slideViewerTokens, slideViewerVariants, smoothWaveformSamples, statCardVariants, statsGridVariants, statusContainerStyles, statusDotVariants, statusLabelStyles, statusPulseVariants, switchThumbVariants, switchTokens, switchVariants, tableVariants, tabsListVariants, tabsTriggerVariants, textareaVariants, threadAuthorStyles, threadAvatarStyles, threadBodyStyles, threadContainerStyles, threadContentStyles, threadMessageStyles, threadReactionsStyles, threadTimestampStyles, toCssDimension, toastVariants, toolbarVariants, tooltipContentVariants, typewriterVariants, useAuth, useFormField, useShortcut, useToast, versionSelectorOptionVariants, versionSelectorVariants, voicePillAvatarStyles, voicePillAvatarWrapStyles, voicePillLabelStyles, voicePillMuteButtonStyles, voicePillPositionVariants, voicePillPulseRingStyles, voicePillRootStyles, voicePillSpeakerStyles, voicePillSubStyles, voicePillTextStyles, voicePillTokens, watermarkVariants, waveformCanvasVariants, waveformVariants };
|
|
12823
13615
|
//# sourceMappingURL=index.js.map
|
|
12824
13616
|
//# sourceMappingURL=index.js.map
|