@fanvue/ui 3.16.0 → 3.18.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/README.md +1 -1
- package/dist/cjs/components/AudioPlayer/AudioPlayer.cjs +16 -89
- package/dist/cjs/components/AudioPlayer/AudioPlayer.cjs.map +1 -1
- package/dist/cjs/components/Icons/ReceiveMoneyIcon.cjs +79 -0
- package/dist/cjs/components/Icons/ReceiveMoneyIcon.cjs.map +1 -0
- package/dist/cjs/components/PhoneField/PhoneField.cjs +198 -0
- package/dist/cjs/components/PhoneField/PhoneField.cjs.map +1 -0
- package/dist/cjs/components/RatingSummary/RatingSummary.cjs +30 -23
- package/dist/cjs/components/RatingSummary/RatingSummary.cjs.map +1 -1
- package/dist/cjs/components/TextArea/TextArea.cjs +2 -2
- package/dist/cjs/components/TextArea/TextArea.cjs.map +1 -1
- package/dist/cjs/components/TextField/TextField.cjs +13 -6
- package/dist/cjs/components/TextField/TextField.cjs.map +1 -1
- package/dist/cjs/components/VoiceNote/VoiceNote.cjs +305 -0
- package/dist/cjs/components/VoiceNote/VoiceNote.cjs.map +1 -0
- package/dist/cjs/index.cjs +6 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/utils/audioWaveform.cjs +76 -0
- package/dist/cjs/utils/audioWaveform.cjs.map +1 -0
- package/dist/cjs/utils/useAudioPlayback.cjs +123 -0
- package/dist/cjs/utils/useAudioPlayback.cjs.map +1 -0
- package/dist/cjs/utils/useFittedBarCount.cjs +42 -0
- package/dist/cjs/utils/useFittedBarCount.cjs.map +1 -0
- package/dist/cjs/utils/useWaveformPeaks.cjs +48 -0
- package/dist/cjs/utils/useWaveformPeaks.cjs.map +1 -0
- package/dist/cjs/utils/useWaveformSeek.cjs +100 -0
- package/dist/cjs/utils/useWaveformSeek.cjs.map +1 -0
- package/dist/components/AudioPlayer/AudioPlayer.mjs +7 -80
- package/dist/components/AudioPlayer/AudioPlayer.mjs.map +1 -1
- package/dist/components/Icons/ReceiveMoneyIcon.mjs +62 -0
- package/dist/components/Icons/ReceiveMoneyIcon.mjs.map +1 -0
- package/dist/components/PhoneField/PhoneField.mjs +181 -0
- package/dist/components/PhoneField/PhoneField.mjs.map +1 -0
- package/dist/components/RatingSummary/RatingSummary.mjs +30 -23
- package/dist/components/RatingSummary/RatingSummary.mjs.map +1 -1
- package/dist/components/TextArea/TextArea.mjs +2 -2
- package/dist/components/TextArea/TextArea.mjs.map +1 -1
- package/dist/components/TextField/TextField.mjs +13 -6
- package/dist/components/TextField/TextField.mjs.map +1 -1
- package/dist/components/VoiceNote/VoiceNote.mjs +288 -0
- package/dist/components/VoiceNote/VoiceNote.mjs.map +1 -0
- package/dist/index.d.ts +158 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -1
- package/dist/styles/base.css +11 -2
- package/dist/utils/audioWaveform.mjs +76 -0
- package/dist/utils/audioWaveform.mjs.map +1 -0
- package/dist/utils/useAudioPlayback.mjs +106 -0
- package/dist/utils/useAudioPlayback.mjs.map +1 -0
- package/dist/utils/useFittedBarCount.mjs +25 -0
- package/dist/utils/useFittedBarCount.mjs.map +1 -0
- package/dist/utils/useWaveformPeaks.mjs +31 -0
- package/dist/utils/useWaveformPeaks.mjs.map +1 -0
- package/dist/utils/useWaveformSeek.mjs +83 -0
- package/dist/utils/useWaveformSeek.mjs.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ React component library built with Tailwind CSS for the Fanvue ecosystem.
|
|
|
10
10
|
[](https://bundlephobia.com/package/@fanvue/ui)
|
|
11
11
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
12
12
|
[](https://www.typescriptlang.org/)
|
|
13
|
-
[](https://697a1b6dd4dad73ee9c0e5f5
|
|
13
|
+
[](https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/)
|
|
14
14
|
[](https://fanvue.github.io/fanv-ui/)
|
|
15
15
|
[](https://github.com/fanvue/fanv-ui)
|
|
16
16
|
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
4
|
const jsxRuntime = require("react/jsx-runtime");
|
|
5
5
|
const React = require("react");
|
|
6
|
+
const audioWaveform = require("../../utils/audioWaveform.cjs");
|
|
6
7
|
const cn = require("../../utils/cn.cjs");
|
|
8
|
+
const useFittedBarCount = require("../../utils/useFittedBarCount.cjs");
|
|
7
9
|
const PauseIcon = require("../Icons/PauseIcon.cjs");
|
|
8
10
|
const PlayIcon = require("../Icons/PlayIcon.cjs");
|
|
9
11
|
function _interopNamespaceDefault(e) {
|
|
@@ -28,72 +30,8 @@ const BAR_GAP_PX = 4;
|
|
|
28
30
|
const MIN_BAR_HEIGHT_PX = 4;
|
|
29
31
|
const MAX_BAR_HEIGHT_PX = 26;
|
|
30
32
|
const DEFAULT_BAR_COUNT = 24;
|
|
31
|
-
const RAW_PEAK_COUNT = 128;
|
|
32
33
|
const SEEK_STEP_SECONDS = 1;
|
|
33
34
|
const SEEK_STEP_LARGE_SECONDS = 5;
|
|
34
|
-
function formatTime(seconds) {
|
|
35
|
-
if (seconds === void 0 || !Number.isFinite(seconds)) return "--:--";
|
|
36
|
-
const totalSeconds = Math.max(0, Math.floor(seconds));
|
|
37
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
38
|
-
const remainingSeconds = totalSeconds % 60;
|
|
39
|
-
return `${minutes}:${String(remainingSeconds).padStart(2, "0")}`;
|
|
40
|
-
}
|
|
41
|
-
function hashString(value) {
|
|
42
|
-
let hash = 2166136261;
|
|
43
|
-
for (let i = 0; i < value.length; i++) {
|
|
44
|
-
hash ^= value.charCodeAt(i);
|
|
45
|
-
hash = Math.imul(hash, 16777619);
|
|
46
|
-
}
|
|
47
|
-
return hash >>> 0;
|
|
48
|
-
}
|
|
49
|
-
function createSeededRandom(seed) {
|
|
50
|
-
let state = seed;
|
|
51
|
-
return () => {
|
|
52
|
-
state = state + 1831565813 | 0;
|
|
53
|
-
let t = Math.imul(state ^ state >>> 15, 1 | state);
|
|
54
|
-
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
55
|
-
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function generateFallbackPeaks(src, count) {
|
|
59
|
-
const random = createSeededRandom(hashString(src));
|
|
60
|
-
return Array.from({ length: count }, () => 0.2 + random() * 0.8);
|
|
61
|
-
}
|
|
62
|
-
function computePeaksFromChannelData(channelData, count) {
|
|
63
|
-
const blockSize = Math.max(1, Math.floor(channelData.length / count));
|
|
64
|
-
const peaks = [];
|
|
65
|
-
for (let i = 0; i < count; i++) {
|
|
66
|
-
const start = i * blockSize;
|
|
67
|
-
let max = 0;
|
|
68
|
-
for (let j = 0; j < blockSize && start + j < channelData.length; j++) {
|
|
69
|
-
max = Math.max(max, Math.abs(channelData[start + j] ?? 0));
|
|
70
|
-
}
|
|
71
|
-
peaks.push(max);
|
|
72
|
-
}
|
|
73
|
-
return peaks;
|
|
74
|
-
}
|
|
75
|
-
function resamplePeaks(peaks, barCount) {
|
|
76
|
-
if (peaks.length === 0 || barCount <= 0) return [];
|
|
77
|
-
const step = peaks.length / barCount;
|
|
78
|
-
return Array.from(
|
|
79
|
-
{ length: barCount },
|
|
80
|
-
(_, i) => peaks[Math.min(peaks.length - 1, Math.floor(i * step))] ?? 0
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
async function decodeAudioPeaks(src, signal) {
|
|
84
|
-
const AudioContextCtor = window.AudioContext ?? window.webkitAudioContext;
|
|
85
|
-
if (!AudioContextCtor) throw new Error("WebAudio unsupported");
|
|
86
|
-
const response = await fetch(src, { signal });
|
|
87
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
88
|
-
const audioContext = new AudioContextCtor();
|
|
89
|
-
try {
|
|
90
|
-
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
|
91
|
-
return computePeaksFromChannelData(audioBuffer.getChannelData(0), RAW_PEAK_COUNT);
|
|
92
|
-
} finally {
|
|
93
|
-
if (audioContext.state !== "closed") audioContext.close().catch(() => {
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
35
|
const AudioPlayer = React__namespace.forwardRef(
|
|
98
36
|
({
|
|
99
37
|
className,
|
|
@@ -114,9 +52,13 @@ const AudioPlayer = React__namespace.forwardRef(
|
|
|
114
52
|
const playing = isControlled ? controlledPlaying : internalPlaying;
|
|
115
53
|
const [currentTime, setCurrentTime] = React__namespace.useState(0);
|
|
116
54
|
const [mediaDuration, setMediaDuration] = React__namespace.useState(void 0);
|
|
117
|
-
const
|
|
55
|
+
const barCount = useFittedBarCount.useFittedBarCount(trackRef, {
|
|
56
|
+
barWidthPx: BAR_WIDTH_PX,
|
|
57
|
+
gapPx: BAR_GAP_PX,
|
|
58
|
+
fallback: DEFAULT_BAR_COUNT
|
|
59
|
+
});
|
|
118
60
|
const [peaks, setPeaks] = React__namespace.useState(
|
|
119
|
-
() => generateFallbackPeaks(src, RAW_PEAK_COUNT)
|
|
61
|
+
() => audioWaveform.generateFallbackPeaks(src, audioWaveform.RAW_PEAK_COUNT)
|
|
120
62
|
);
|
|
121
63
|
const [isDragging, setIsDragging] = React__namespace.useState(false);
|
|
122
64
|
const displayDuration = mediaDuration ?? duration;
|
|
@@ -135,7 +77,7 @@ const AudioPlayer = React__namespace.forwardRef(
|
|
|
135
77
|
}
|
|
136
78
|
setCurrentTime(0);
|
|
137
79
|
setMediaDuration(void 0);
|
|
138
|
-
setPeaks(generateFallbackPeaks(src, RAW_PEAK_COUNT));
|
|
80
|
+
setPeaks(audioWaveform.generateFallbackPeaks(src, audioWaveform.RAW_PEAK_COUNT));
|
|
139
81
|
if (playingRef.current) {
|
|
140
82
|
if (!isControlledRef.current) setInternalPlaying(false);
|
|
141
83
|
onPauseRef.current?.();
|
|
@@ -144,31 +86,16 @@ const AudioPlayer = React__namespace.forwardRef(
|
|
|
144
86
|
React__namespace.useEffect(() => {
|
|
145
87
|
let cancelled = false;
|
|
146
88
|
const abortController = new AbortController();
|
|
147
|
-
decodeAudioPeaks(src, abortController.signal).then((decodedPeaks) => {
|
|
89
|
+
audioWaveform.decodeAudioPeaks(src, abortController.signal).then((decodedPeaks) => {
|
|
148
90
|
if (!cancelled) setPeaks(decodedPeaks);
|
|
149
91
|
}).catch(() => {
|
|
150
|
-
if (!cancelled) setPeaks(generateFallbackPeaks(src, RAW_PEAK_COUNT));
|
|
92
|
+
if (!cancelled) setPeaks(audioWaveform.generateFallbackPeaks(src, audioWaveform.RAW_PEAK_COUNT));
|
|
151
93
|
});
|
|
152
94
|
return () => {
|
|
153
95
|
cancelled = true;
|
|
154
96
|
abortController.abort();
|
|
155
97
|
};
|
|
156
98
|
}, [src]);
|
|
157
|
-
React__namespace.useEffect(() => {
|
|
158
|
-
const track = trackRef.current;
|
|
159
|
-
if (!track) return;
|
|
160
|
-
const updateFromWidth = (width) => {
|
|
161
|
-
if (width <= 0) return;
|
|
162
|
-
setBarCount(Math.max(1, Math.floor((width + BAR_GAP_PX) / (BAR_WIDTH_PX + BAR_GAP_PX))));
|
|
163
|
-
};
|
|
164
|
-
updateFromWidth(track.getBoundingClientRect().width);
|
|
165
|
-
const observer = new ResizeObserver((entries) => {
|
|
166
|
-
const entry = entries[0];
|
|
167
|
-
if (entry) updateFromWidth(entry.contentRect.width);
|
|
168
|
-
});
|
|
169
|
-
observer.observe(track);
|
|
170
|
-
return () => observer.disconnect();
|
|
171
|
-
}, []);
|
|
172
99
|
React__namespace.useEffect(() => {
|
|
173
100
|
const audio = audioRef.current;
|
|
174
101
|
if (!audio) return;
|
|
@@ -254,7 +181,7 @@ const AudioPlayer = React__namespace.forwardRef(
|
|
|
254
181
|
break;
|
|
255
182
|
}
|
|
256
183
|
};
|
|
257
|
-
const bars = resamplePeaks(peaks, barCount);
|
|
184
|
+
const bars = audioWaveform.resamplePeaks(peaks, barCount);
|
|
258
185
|
const progressFraction = displayDuration && displayDuration > 0 ? Math.min(Math.max(currentTime / displayDuration, 0), 1) : 0;
|
|
259
186
|
const playedBarCount = hasStarted ? Math.round(progressFraction * bars.length) : bars.length;
|
|
260
187
|
const barData = bars.map((amplitude, index) => {
|
|
@@ -304,7 +231,7 @@ const AudioPlayer = React__namespace.forwardRef(
|
|
|
304
231
|
"aria-valuemin": 0,
|
|
305
232
|
"aria-valuemax": displayDuration,
|
|
306
233
|
"aria-valuenow": Math.round(currentTime),
|
|
307
|
-
"aria-valuetext": displayDuration !== void 0 ? `${formatTime(currentTime)} of ${formatTime(displayDuration)}` : formatTime(currentTime),
|
|
234
|
+
"aria-valuetext": displayDuration !== void 0 ? `${audioWaveform.formatTime(currentTime)} of ${audioWaveform.formatTime(displayDuration)}` : audioWaveform.formatTime(currentTime),
|
|
308
235
|
onPointerDown: handlePointerDown,
|
|
309
236
|
onKeyDown: handleKeyDown,
|
|
310
237
|
className: cn.cn(
|
|
@@ -318,12 +245,12 @@ const AudioPlayer = React__namespace.forwardRef(
|
|
|
318
245
|
}
|
|
319
246
|
),
|
|
320
247
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-body-small-14px-semibold flex shrink-0 items-center gap-0.5 whitespace-nowrap", children: hasStarted ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
321
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-content-primary", children: formatTime(currentTime) }),
|
|
248
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-content-primary", children: audioWaveform.formatTime(currentTime) }),
|
|
322
249
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-content-secondary", children: [
|
|
323
250
|
"/",
|
|
324
|
-
formatTime(displayDuration)
|
|
251
|
+
audioWaveform.formatTime(displayDuration)
|
|
325
252
|
] })
|
|
326
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-content-primary", children: formatTime(displayDuration) }) })
|
|
253
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-content-primary", children: audioWaveform.formatTime(displayDuration) }) })
|
|
327
254
|
] }),
|
|
328
255
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
329
256
|
"audio",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioPlayer.cjs","sources":["../../../../src/components/AudioPlayer/AudioPlayer.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { PauseIcon } from \"../Icons/PauseIcon\";\nimport { PlayIcon } from \"../Icons/PlayIcon\";\n\n/** Width of a single waveform bar, in pixels. */\nconst BAR_WIDTH_PX = 4;\n/** Gap between waveform bars, in pixels. */\nconst BAR_GAP_PX = 4;\n/** Shortest a waveform bar can render, in pixels. */\nconst MIN_BAR_HEIGHT_PX = 4;\n/** Tallest a waveform bar can render, in pixels — matches the 40px row height. */\nconst MAX_BAR_HEIGHT_PX = 26;\n/** Bar count used before the container has been measured (e.g. during SSR or in jsdom, where layout is unavailable). */\nconst DEFAULT_BAR_COUNT = 24;\n/** Number of amplitude samples kept internally, resampled to the rendered bar count. */\nconst RAW_PEAK_COUNT = 128;\n/** Seconds moved per Arrow key press while seeking. */\nconst SEEK_STEP_SECONDS = 1;\n/** Seconds moved per Page Up/Down press while seeking. */\nconst SEEK_STEP_LARGE_SECONDS = 5;\n\n/** Height of the audio player row, in pixels. Matches both the Vault card overlay and the \"Generated Audio\" modal row in Figma — both use an identical 32px play button and 40px row. */\nexport type AudioPlayerSize = \"40\";\n\nexport interface AudioPlayerProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onPlay\" | \"onPause\" | \"onEnded\"> {\n /** URL of the audio file to play. */\n src: string;\n /**\n * Total duration in seconds, used to render the timestamp before the\n * media's own metadata has loaded (and as a fallback if it never does).\n */\n duration?: number;\n /**\n * Whether playback is active (controlled). Note: once `onEnded` fires, the\n * browser has already stopped native playback. To loop or replay under\n * controlled usage, toggle this prop `false` then `true` (rather than\n * leaving it `true`) — the sync effect only calls `play()` again when this\n * value actually changes.\n */\n playing?: boolean;\n /** Initial playback state (uncontrolled). @default false */\n defaultPlaying?: boolean;\n /** Called when playback starts. */\n onPlay?: () => void;\n /** Called when playback is paused. */\n onPause?: () => void;\n /** Called when playback reaches the end of the media. */\n onEnded?: () => void;\n /** Height of the player row, in pixels. @default \"40\" */\n size?: AudioPlayerSize;\n}\n\nfunction formatTime(seconds: number | undefined): string {\n if (seconds === undefined || !Number.isFinite(seconds)) return \"--:--\";\n const totalSeconds = Math.max(0, Math.floor(seconds));\n const minutes = Math.floor(totalSeconds / 60);\n const remainingSeconds = totalSeconds % 60;\n return `${minutes}:${String(remainingSeconds).padStart(2, \"0\")}`;\n}\n\n/** Deterministic 32-bit string hash (FNV-1a), used to seed the fallback waveform. */\nfunction hashString(value: string): number {\n let hash = 2166136261;\n for (let i = 0; i < value.length; i++) {\n hash ^= value.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n}\n\n/** Seeded PRNG (mulberry32) — deterministic across runs, unlike `Math.random`. */\nfunction createSeededRandom(seed: number): () => number {\n let state = seed;\n return () => {\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/** Deterministic placeholder amplitudes used when audio can't be decoded (network/CORS/format failure). */\nfunction generateFallbackPeaks(src: string, count: number): number[] {\n const random = createSeededRandom(hashString(src));\n return Array.from({ length: count }, () => 0.2 + random() * 0.8);\n}\n\n/** Downsamples decoded PCM data to `count` peak (max-abs) amplitudes. */\nfunction computePeaksFromChannelData(channelData: Float32Array, count: number): number[] {\n const blockSize = Math.max(1, Math.floor(channelData.length / count));\n const peaks: number[] = [];\n for (let i = 0; i < count; i++) {\n const start = i * blockSize;\n let max = 0;\n for (let j = 0; j < blockSize && start + j < channelData.length; j++) {\n max = Math.max(max, Math.abs(channelData[start + j] ?? 0));\n }\n peaks.push(max);\n }\n return peaks;\n}\n\n/** Resamples a peaks array to the number of bars that currently fit the container. */\nfunction resamplePeaks(peaks: number[], barCount: number): number[] {\n if (peaks.length === 0 || barCount <= 0) return [];\n const step = peaks.length / barCount;\n return Array.from(\n { length: barCount },\n (_, i) => peaks[Math.min(peaks.length - 1, Math.floor(i * step))] ?? 0,\n );\n}\n\n/** Decodes `src` via WebAudio and returns downsampled peak amplitudes. Throws on any failure. */\nasync function decodeAudioPeaks(src: string, signal: AbortSignal): Promise<number[]> {\n const AudioContextCtor =\n window.AudioContext ??\n (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!AudioContextCtor) throw new Error(\"WebAudio unsupported\");\n\n const response = await fetch(src, { signal });\n const arrayBuffer = await response.arrayBuffer();\n const audioContext = new AudioContextCtor();\n try {\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n return computePeaksFromChannelData(audioBuffer.getChannelData(0), RAW_PEAK_COUNT);\n } finally {\n if (audioContext.state !== \"closed\") audioContext.close().catch(() => {});\n }\n}\n\n/**\n * A compact playback control for a single audio clip: a play/pause toggle, a\n * static amplitude waveform that doubles as a seek scrubber, and elapsed/total\n * timestamps. Designed to sit as an overlay on media thumbnails (Vault cards)\n * as well as inline rows (the AI Voice Message \"Generated Audio\" row).\n *\n * The waveform is seeded from the decoded audio when possible, falling back\n * to a deterministic (not random) placeholder derived from `src` so the\n * result is stable across renders, SSR, and Chromatic snapshots.\n *\n * @example\n * ```tsx\n * <AudioPlayer src=\"https://example.com/clip.mp3\" duration={5} />\n * ```\n */\nexport const AudioPlayer = React.forwardRef<HTMLDivElement, AudioPlayerProps>(\n (\n {\n className,\n src,\n duration,\n playing: controlledPlaying,\n defaultPlaying = false,\n onPlay,\n onPause,\n onEnded,\n size = \"40\",\n ...props\n },\n ref,\n ) => {\n const audioRef = React.useRef<HTMLAudioElement>(null);\n const trackRef = React.useRef<HTMLDivElement>(null);\n\n const [internalPlaying, setInternalPlaying] = React.useState(defaultPlaying);\n const isControlled = controlledPlaying !== undefined;\n const playing = isControlled ? controlledPlaying : internalPlaying;\n\n const [currentTime, setCurrentTime] = React.useState(0);\n const [mediaDuration, setMediaDuration] = React.useState<number | undefined>(undefined);\n const [barCount, setBarCount] = React.useState(DEFAULT_BAR_COUNT);\n const [peaks, setPeaks] = React.useState<number[]>(() =>\n generateFallbackPeaks(src, RAW_PEAK_COUNT),\n );\n const [isDragging, setIsDragging] = React.useState(false);\n\n const displayDuration = mediaDuration ?? duration;\n const hasStarted = playing || currentTime > 0;\n\n // Latest-value refs so the src-change effect below can react to a src swap\n // without re-running whenever `playing`/`isControlled`/`onPause` change.\n const playingRef = React.useRef(playing);\n playingRef.current = playing;\n const isControlledRef = React.useRef(isControlled);\n isControlledRef.current = isControlled;\n const onPauseRef = React.useRef(onPause);\n onPauseRef.current = onPause;\n\n // Reset transient playback state when the source changes. Skips the\n // initial mount (there's nothing to reset yet) and, if playback was\n // active, stops it — the browser silently drops playback on a source\n // swap, so the UI (and any controlled parent) must be told via onPause.\n const isFirstSrcRenderRef = React.useRef(true);\n React.useEffect(() => {\n if (isFirstSrcRenderRef.current) {\n isFirstSrcRenderRef.current = false;\n return;\n }\n setCurrentTime(0);\n setMediaDuration(undefined);\n setPeaks(generateFallbackPeaks(src, RAW_PEAK_COUNT));\n if (playingRef.current) {\n if (!isControlledRef.current) setInternalPlaying(false);\n onPauseRef.current?.();\n }\n }, [src]);\n\n // Decode the audio to derive real waveform amplitudes, falling back to a\n // deterministic placeholder on any failure (network, CORS, unsupported format).\n React.useEffect(() => {\n let cancelled = false;\n const abortController = new AbortController();\n\n decodeAudioPeaks(src, abortController.signal)\n .then((decodedPeaks) => {\n if (!cancelled) setPeaks(decodedPeaks);\n })\n .catch(() => {\n if (!cancelled) setPeaks(generateFallbackPeaks(src, RAW_PEAK_COUNT));\n });\n\n return () => {\n cancelled = true;\n abortController.abort();\n };\n }, [src]);\n\n // Measure the track to decide how many bars fit; falls back to DEFAULT_BAR_COUNT\n // when layout is unavailable (SSR, jsdom).\n React.useEffect(() => {\n const track = trackRef.current;\n if (!track) return;\n\n const updateFromWidth = (width: number) => {\n if (width <= 0) return;\n setBarCount(Math.max(1, Math.floor((width + BAR_GAP_PX) / (BAR_WIDTH_PX + BAR_GAP_PX))));\n };\n\n updateFromWidth(track.getBoundingClientRect().width);\n\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) updateFromWidth(entry.contentRect.width);\n });\n observer.observe(track);\n return () => observer.disconnect();\n }, []);\n\n // Sync the controlled/uncontrolled `playing` state to the media element.\n React.useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n if (playing) {\n audio.play().catch(() => {\n if (!isControlled) setInternalPlaying(false);\n onPauseRef.current?.();\n });\n } else {\n audio.pause();\n }\n }, [playing, isControlled]);\n\n const handleToggle = () => {\n const next = !playing;\n if (!isControlled) setInternalPlaying(next);\n if (next) onPlay?.();\n else onPause?.();\n };\n\n const seekTo = React.useCallback(\n (time: number) => {\n if (displayDuration === undefined) return;\n const clamped = Math.min(Math.max(time, 0), displayDuration);\n setCurrentTime(clamped);\n const audio = audioRef.current;\n if (audio) audio.currentTime = clamped;\n },\n [displayDuration],\n );\n\n const seekFromClientX = React.useCallback(\n (clientX: number) => {\n const track = trackRef.current;\n if (!track || displayDuration === undefined) return;\n const rect = track.getBoundingClientRect();\n if (rect.width <= 0) return;\n const fraction = Math.min(Math.max((clientX - rect.left) / rect.width, 0), 1);\n seekTo(fraction * displayDuration);\n },\n [displayDuration, seekTo],\n );\n\n // Track drag outside the element via window listeners rather than pointer\n // capture, which some environments (and jsdom) don't fully implement.\n React.useEffect(() => {\n if (!isDragging) return;\n const handleWindowPointerMove = (event: PointerEvent) => seekFromClientX(event.clientX);\n const handleWindowPointerUp = () => setIsDragging(false);\n window.addEventListener(\"pointermove\", handleWindowPointerMove);\n window.addEventListener(\"pointerup\", handleWindowPointerUp);\n return () => {\n window.removeEventListener(\"pointermove\", handleWindowPointerMove);\n window.removeEventListener(\"pointerup\", handleWindowPointerUp);\n };\n }, [isDragging, seekFromClientX]);\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n seekFromClientX(event.clientX);\n setIsDragging(true);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (displayDuration === undefined) return;\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowUp\":\n event.preventDefault();\n seekTo(currentTime + SEEK_STEP_SECONDS);\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n event.preventDefault();\n seekTo(currentTime - SEEK_STEP_SECONDS);\n break;\n case \"PageUp\":\n event.preventDefault();\n seekTo(currentTime + SEEK_STEP_LARGE_SECONDS);\n break;\n case \"PageDown\":\n event.preventDefault();\n seekTo(currentTime - SEEK_STEP_LARGE_SECONDS);\n break;\n case \"Home\":\n event.preventDefault();\n seekTo(0);\n break;\n case \"End\":\n event.preventDefault();\n seekTo(displayDuration);\n break;\n default:\n break;\n }\n };\n\n const bars = resamplePeaks(peaks, barCount);\n const progressFraction =\n displayDuration && displayDuration > 0\n ? Math.min(Math.max(currentTime / displayDuration, 0), 1)\n : 0;\n const playedBarCount = hasStarted ? Math.round(progressFraction * bars.length) : bars.length;\n const barData = bars.map((amplitude, index) => {\n const isPlayed = index < playedBarCount;\n return {\n heightPx: MIN_BAR_HEIGHT_PX + amplitude * (MAX_BAR_HEIGHT_PX - MIN_BAR_HEIGHT_PX),\n className: cn(\n \"w-1 shrink-0 rounded-3xs bg-messages-waveform-default\",\n \"motion-safe:transition-opacity motion-safe:duration-150 motion-safe:ease-in-out\",\n isPlayed ? \"opacity-100\" : \"opacity-50\",\n ),\n };\n });\n\n return (\n <div\n ref={ref}\n data-size={size}\n className={cn(\"flex w-full items-center gap-3\", className)}\n {...props}\n >\n <button\n type=\"button\"\n onClick={handleToggle}\n aria-label={playing ? \"Pause\" : \"Play\"}\n className={cn(\n \"flex size-8 shrink-0 items-center justify-center rounded-full\",\n \"bg-buttons-secondary-default text-icons-primary backdrop-blur-[40px]\",\n \"motion-safe:transition-colors motion-safe:duration-150 motion-safe:ease-in-out\",\n \"hover:bg-buttons-secondary-hover\",\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n )}\n >\n {playing ? <PauseIcon size={16} filled /> : <PlayIcon size={16} filled />}\n </button>\n\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <div\n ref={trackRef}\n role=\"slider\"\n tabIndex={0}\n aria-label=\"Seek\"\n aria-orientation=\"horizontal\"\n aria-valuemin={0}\n aria-valuemax={displayDuration}\n aria-valuenow={Math.round(currentTime)}\n aria-valuetext={\n displayDuration !== undefined\n ? `${formatTime(currentTime)} of ${formatTime(displayDuration)}`\n : formatTime(currentTime)\n }\n onPointerDown={handlePointerDown}\n onKeyDown={handleKeyDown}\n className={cn(\n \"flex h-10 min-w-0 flex-1 cursor-pointer touch-none select-none items-center gap-1 overflow-hidden\",\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n )}\n >\n {barData.map((bar, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: bars are a fixed-count, non-reorderable list\n <span key={index} className={bar.className} style={{ height: bar.heightPx }} />\n ))}\n </div>\n\n <span className=\"typography-body-small-14px-semibold flex shrink-0 items-center gap-0.5 whitespace-nowrap\">\n {hasStarted ? (\n <>\n <span className=\"text-content-primary\">{formatTime(currentTime)}</span>\n <span className=\"text-content-secondary\">/{formatTime(displayDuration)}</span>\n </>\n ) : (\n <span className=\"text-content-primary\">{formatTime(displayDuration)}</span>\n )}\n </span>\n </div>\n\n {/* biome-ignore lint/a11y/useMediaCaption: this is a UI sound clip (voice note / short recording), not spoken/narrated content requiring captions. */}\n <audio\n ref={audioRef}\n src={src}\n preload=\"metadata\"\n className=\"hidden\"\n onLoadedMetadata={(event) => {\n const { duration: nativeDuration } = event.currentTarget;\n setMediaDuration(Number.isFinite(nativeDuration) ? nativeDuration : undefined);\n }}\n onTimeUpdate={(event) => {\n if (isDragging) return;\n setCurrentTime(event.currentTarget.currentTime);\n }}\n onEnded={() => {\n setCurrentTime(0);\n if (!isControlled) setInternalPlaying(false);\n onEnded?.();\n }}\n />\n </div>\n );\n },\n);\n\nAudioPlayer.displayName = \"AudioPlayer\";\n"],"names":["React","cn","jsxs","jsx","PauseIcon","PlayIcon","Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AudioPlayer.cjs","sources":["../../../../src/components/AudioPlayer/AudioPlayer.tsx"],"sourcesContent":["import * as React from \"react\";\nimport {\n decodeAudioPeaks,\n formatTime,\n generateFallbackPeaks,\n RAW_PEAK_COUNT,\n resamplePeaks,\n} from \"../../utils/audioWaveform\";\nimport { cn } from \"../../utils/cn\";\nimport { useFittedBarCount } from \"../../utils/useFittedBarCount\";\nimport { PauseIcon } from \"../Icons/PauseIcon\";\nimport { PlayIcon } from \"../Icons/PlayIcon\";\n\n/** Width of a single waveform bar, in pixels. */\nconst BAR_WIDTH_PX = 4;\n/** Gap between waveform bars, in pixels. */\nconst BAR_GAP_PX = 4;\n/** Shortest a waveform bar can render, in pixels. */\nconst MIN_BAR_HEIGHT_PX = 4;\n/** Tallest a waveform bar can render, in pixels — matches the 40px row height. */\nconst MAX_BAR_HEIGHT_PX = 26;\n/** Bar count used before the container has been measured (e.g. during SSR or in jsdom, where layout is unavailable). */\nconst DEFAULT_BAR_COUNT = 24;\n/** Seconds moved per Arrow key press while seeking. */\nconst SEEK_STEP_SECONDS = 1;\n/** Seconds moved per Page Up/Down press while seeking. */\nconst SEEK_STEP_LARGE_SECONDS = 5;\n\n/** Height of the audio player row, in pixels. Matches both the Vault card overlay and the \"Generated Audio\" modal row in Figma — both use an identical 32px play button and 40px row. */\nexport type AudioPlayerSize = \"40\";\n\nexport interface AudioPlayerProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onPlay\" | \"onPause\" | \"onEnded\"> {\n /** URL of the audio file to play. */\n src: string;\n /**\n * Total duration in seconds, used to render the timestamp before the\n * media's own metadata has loaded (and as a fallback if it never does).\n */\n duration?: number;\n /**\n * Whether playback is active (controlled). Note: once `onEnded` fires, the\n * browser has already stopped native playback. To loop or replay under\n * controlled usage, toggle this prop `false` then `true` (rather than\n * leaving it `true`) — the sync effect only calls `play()` again when this\n * value actually changes.\n */\n playing?: boolean;\n /** Initial playback state (uncontrolled). @default false */\n defaultPlaying?: boolean;\n /** Called when playback starts. */\n onPlay?: () => void;\n /** Called when playback is paused. */\n onPause?: () => void;\n /** Called when playback reaches the end of the media. */\n onEnded?: () => void;\n /** Height of the player row, in pixels. @default \"40\" */\n size?: AudioPlayerSize;\n}\n\n/**\n * A compact playback control for a single audio clip: a play/pause toggle, a\n * static amplitude waveform that doubles as a seek scrubber, and elapsed/total\n * timestamps. Designed to sit as an overlay on media thumbnails (Vault cards)\n * as well as inline rows (the AI Voice Message \"Generated Audio\" row).\n *\n * The waveform is seeded from the decoded audio when possible, falling back\n * to a deterministic (not random) placeholder derived from `src` so the\n * result is stable across renders, SSR, and Chromatic snapshots.\n *\n * @example\n * ```tsx\n * <AudioPlayer src=\"https://example.com/clip.mp3\" duration={5} />\n * ```\n */\nexport const AudioPlayer = React.forwardRef<HTMLDivElement, AudioPlayerProps>(\n (\n {\n className,\n src,\n duration,\n playing: controlledPlaying,\n defaultPlaying = false,\n onPlay,\n onPause,\n onEnded,\n size = \"40\",\n ...props\n },\n ref,\n ) => {\n const audioRef = React.useRef<HTMLAudioElement>(null);\n const trackRef = React.useRef<HTMLDivElement>(null);\n\n const [internalPlaying, setInternalPlaying] = React.useState(defaultPlaying);\n const isControlled = controlledPlaying !== undefined;\n const playing = isControlled ? controlledPlaying : internalPlaying;\n\n const [currentTime, setCurrentTime] = React.useState(0);\n const [mediaDuration, setMediaDuration] = React.useState<number | undefined>(undefined);\n const barCount = useFittedBarCount(trackRef, {\n barWidthPx: BAR_WIDTH_PX,\n gapPx: BAR_GAP_PX,\n fallback: DEFAULT_BAR_COUNT,\n });\n const [peaks, setPeaks] = React.useState<number[]>(() =>\n generateFallbackPeaks(src, RAW_PEAK_COUNT),\n );\n const [isDragging, setIsDragging] = React.useState(false);\n\n const displayDuration = mediaDuration ?? duration;\n const hasStarted = playing || currentTime > 0;\n\n // Latest-value refs so the src-change effect below can react to a src swap\n // without re-running whenever `playing`/`isControlled`/`onPause` change.\n const playingRef = React.useRef(playing);\n playingRef.current = playing;\n const isControlledRef = React.useRef(isControlled);\n isControlledRef.current = isControlled;\n const onPauseRef = React.useRef(onPause);\n onPauseRef.current = onPause;\n\n // Reset transient playback state when the source changes. Skips the\n // initial mount (there's nothing to reset yet) and, if playback was\n // active, stops it — the browser silently drops playback on a source\n // swap, so the UI (and any controlled parent) must be told via onPause.\n const isFirstSrcRenderRef = React.useRef(true);\n React.useEffect(() => {\n if (isFirstSrcRenderRef.current) {\n isFirstSrcRenderRef.current = false;\n return;\n }\n setCurrentTime(0);\n setMediaDuration(undefined);\n setPeaks(generateFallbackPeaks(src, RAW_PEAK_COUNT));\n if (playingRef.current) {\n if (!isControlledRef.current) setInternalPlaying(false);\n onPauseRef.current?.();\n }\n }, [src]);\n\n // Decode the audio to derive real waveform amplitudes, falling back to a\n // deterministic placeholder on any failure (network, CORS, unsupported format).\n React.useEffect(() => {\n let cancelled = false;\n const abortController = new AbortController();\n\n decodeAudioPeaks(src, abortController.signal)\n .then((decodedPeaks) => {\n if (!cancelled) setPeaks(decodedPeaks);\n })\n .catch(() => {\n if (!cancelled) setPeaks(generateFallbackPeaks(src, RAW_PEAK_COUNT));\n });\n\n return () => {\n cancelled = true;\n abortController.abort();\n };\n }, [src]);\n\n // Sync the controlled/uncontrolled `playing` state to the media element.\n React.useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n if (playing) {\n audio.play().catch(() => {\n if (!isControlled) setInternalPlaying(false);\n onPauseRef.current?.();\n });\n } else {\n audio.pause();\n }\n }, [playing, isControlled]);\n\n const handleToggle = () => {\n const next = !playing;\n if (!isControlled) setInternalPlaying(next);\n if (next) onPlay?.();\n else onPause?.();\n };\n\n const seekTo = React.useCallback(\n (time: number) => {\n if (displayDuration === undefined) return;\n const clamped = Math.min(Math.max(time, 0), displayDuration);\n setCurrentTime(clamped);\n const audio = audioRef.current;\n if (audio) audio.currentTime = clamped;\n },\n [displayDuration],\n );\n\n const seekFromClientX = React.useCallback(\n (clientX: number) => {\n const track = trackRef.current;\n if (!track || displayDuration === undefined) return;\n const rect = track.getBoundingClientRect();\n if (rect.width <= 0) return;\n const fraction = Math.min(Math.max((clientX - rect.left) / rect.width, 0), 1);\n seekTo(fraction * displayDuration);\n },\n [displayDuration, seekTo],\n );\n\n // Track drag outside the element via window listeners rather than pointer\n // capture, which some environments (and jsdom) don't fully implement.\n React.useEffect(() => {\n if (!isDragging) return;\n const handleWindowPointerMove = (event: PointerEvent) => seekFromClientX(event.clientX);\n const handleWindowPointerUp = () => setIsDragging(false);\n window.addEventListener(\"pointermove\", handleWindowPointerMove);\n window.addEventListener(\"pointerup\", handleWindowPointerUp);\n return () => {\n window.removeEventListener(\"pointermove\", handleWindowPointerMove);\n window.removeEventListener(\"pointerup\", handleWindowPointerUp);\n };\n }, [isDragging, seekFromClientX]);\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n seekFromClientX(event.clientX);\n setIsDragging(true);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (displayDuration === undefined) return;\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowUp\":\n event.preventDefault();\n seekTo(currentTime + SEEK_STEP_SECONDS);\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n event.preventDefault();\n seekTo(currentTime - SEEK_STEP_SECONDS);\n break;\n case \"PageUp\":\n event.preventDefault();\n seekTo(currentTime + SEEK_STEP_LARGE_SECONDS);\n break;\n case \"PageDown\":\n event.preventDefault();\n seekTo(currentTime - SEEK_STEP_LARGE_SECONDS);\n break;\n case \"Home\":\n event.preventDefault();\n seekTo(0);\n break;\n case \"End\":\n event.preventDefault();\n seekTo(displayDuration);\n break;\n default:\n break;\n }\n };\n\n const bars = resamplePeaks(peaks, barCount);\n const progressFraction =\n displayDuration && displayDuration > 0\n ? Math.min(Math.max(currentTime / displayDuration, 0), 1)\n : 0;\n const playedBarCount = hasStarted ? Math.round(progressFraction * bars.length) : bars.length;\n const barData = bars.map((amplitude, index) => {\n const isPlayed = index < playedBarCount;\n return {\n heightPx: MIN_BAR_HEIGHT_PX + amplitude * (MAX_BAR_HEIGHT_PX - MIN_BAR_HEIGHT_PX),\n className: cn(\n \"w-1 shrink-0 rounded-3xs bg-messages-waveform-default\",\n \"motion-safe:transition-opacity motion-safe:duration-150 motion-safe:ease-in-out\",\n isPlayed ? \"opacity-100\" : \"opacity-50\",\n ),\n };\n });\n\n return (\n <div\n ref={ref}\n data-size={size}\n className={cn(\"flex w-full items-center gap-3\", className)}\n {...props}\n >\n <button\n type=\"button\"\n onClick={handleToggle}\n aria-label={playing ? \"Pause\" : \"Play\"}\n className={cn(\n \"flex size-8 shrink-0 items-center justify-center rounded-full\",\n \"bg-buttons-secondary-default text-icons-primary backdrop-blur-[40px]\",\n \"motion-safe:transition-colors motion-safe:duration-150 motion-safe:ease-in-out\",\n \"hover:bg-buttons-secondary-hover\",\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n )}\n >\n {playing ? <PauseIcon size={16} filled /> : <PlayIcon size={16} filled />}\n </button>\n\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <div\n ref={trackRef}\n role=\"slider\"\n tabIndex={0}\n aria-label=\"Seek\"\n aria-orientation=\"horizontal\"\n aria-valuemin={0}\n aria-valuemax={displayDuration}\n aria-valuenow={Math.round(currentTime)}\n aria-valuetext={\n displayDuration !== undefined\n ? `${formatTime(currentTime)} of ${formatTime(displayDuration)}`\n : formatTime(currentTime)\n }\n onPointerDown={handlePointerDown}\n onKeyDown={handleKeyDown}\n className={cn(\n \"flex h-10 min-w-0 flex-1 cursor-pointer touch-none select-none items-center gap-1 overflow-hidden\",\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n )}\n >\n {barData.map((bar, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: bars are a fixed-count, non-reorderable list\n <span key={index} className={bar.className} style={{ height: bar.heightPx }} />\n ))}\n </div>\n\n <span className=\"typography-body-small-14px-semibold flex shrink-0 items-center gap-0.5 whitespace-nowrap\">\n {hasStarted ? (\n <>\n <span className=\"text-content-primary\">{formatTime(currentTime)}</span>\n <span className=\"text-content-secondary\">/{formatTime(displayDuration)}</span>\n </>\n ) : (\n <span className=\"text-content-primary\">{formatTime(displayDuration)}</span>\n )}\n </span>\n </div>\n\n {/* biome-ignore lint/a11y/useMediaCaption: this is a UI sound clip (voice note / short recording), not spoken/narrated content requiring captions. */}\n <audio\n ref={audioRef}\n src={src}\n preload=\"metadata\"\n className=\"hidden\"\n onLoadedMetadata={(event) => {\n const { duration: nativeDuration } = event.currentTarget;\n setMediaDuration(Number.isFinite(nativeDuration) ? nativeDuration : undefined);\n }}\n onTimeUpdate={(event) => {\n if (isDragging) return;\n setCurrentTime(event.currentTarget.currentTime);\n }}\n onEnded={() => {\n setCurrentTime(0);\n if (!isControlled) setInternalPlaying(false);\n onEnded?.();\n }}\n />\n </div>\n );\n },\n);\n\nAudioPlayer.displayName = \"AudioPlayer\";\n"],"names":["React","useFittedBarCount","generateFallbackPeaks","RAW_PEAK_COUNT","decodeAudioPeaks","resamplePeaks","cn","jsxs","jsx","PauseIcon","PlayIcon","formatTime","Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const React = require("react");
|
|
6
|
+
const BaseIcon = require("./BaseIcon.cjs");
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
9
|
+
if (e) {
|
|
10
|
+
for (const k in e) {
|
|
11
|
+
if (k !== "default") {
|
|
12
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: () => e[k]
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
24
|
+
const VARIANTS = {
|
|
25
|
+
16: {
|
|
26
|
+
outlined: [
|
|
27
|
+
{
|
|
28
|
+
d: "M11.713 2.573a.504.504 0 0 1-.5-.5V1.34c0-.273.227-.5.5-.5s.5.227.5.5v.733c0 .274-.227.5-.5.5m0 5.127a.504.504 0 0 1-.5-.5v-.733c0-.274.227-.5.5-.5s.5.226.5.5V7.2c0 .273-.227.5-.5.5"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
d: "M12.153 6.973h-.806c-.554 0-1.06-.3-1.34-.773a.501.501 0 1 1 .866-.507c.1.167.28.273.48.28h.8a.532.532 0 0 0 .134-1.047l-1.374-.346a1.535 1.535 0 0 1-1.146-1.674 1.526 1.526 0 0 1 1.513-1.34h.807c.553 0 1.06.3 1.333.774a.501.501 0 1 1-.867.506.56.56 0 0 0-.473-.273h-.8a.532.532 0 0 0-.133 1.047l1.373.346a1.526 1.526 0 0 1-.367 3.007m-8.48 8.187H2.227a1.22 1.22 0 0 1-1.22-1.22V9.613c0-.673.546-1.22 1.22-1.22h1.44c.673 0 1.22.547 1.22 1.22v4.327a1.22 1.22 0 0 1-1.22 1.22zM2.227 9.393c-.12 0-.22.1-.22.22v4.327c0 .12.1.22.22.22h1.44c.12 0 .22-.1.22-.22V9.613c0-.12-.1-.22-.22-.22z"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
d: "M8.527 15.087a3.4 3.4 0 0 1-.82-.1l-1.914-.48a2.4 2.4 0 0 0-.58-.074h-.82a.504.504 0 0 1-.5-.5c0-.273.227-.5.5-.5h.82c.274 0 .554.034.82.1l1.914.48c.34.087.7.094 1.046.027l2.114-.42c.46-.093.886-.32 1.22-.653l1.493-1.494a.58.58 0 0 0 .173-.42.59.59 0 0 0-.947-.473l-1.74 1.307a1.93 1.93 0 0 1-1.166.386H8.727a.504.504 0 0 1-.5-.5c0-.273.226-.5.5-.5h1.413c.2 0 .4-.066.567-.186l1.74-1.307a1.6 1.6 0 0 1 2.08.147c.3.3.466.7.466 1.126a1.6 1.6 0 0 1-.466 1.127l-1.494 1.493a3.4 3.4 0 0 1-1.726.927l-2.114.42q-.33.069-.66.067z"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
d: "M9.793 12.28H8.72a.504.504 0 0 1-.5-.5c0-.273.227-.5.5-.5h1.073c.16 0 .307-.06.42-.173a.6.6 0 0 0 .174-.42v-.22a.59.59 0 0 0-.447-.573L8.287 9.48a2.92 2.92 0 0 0-2.3.4l-1.314.874a.496.496 0 0 1-.693-.14.496.496 0 0 1 .14-.694l1.313-.873c.907-.6 2.047-.8 3.1-.54l1.654.413a1.59 1.59 0 0 1 1.206 1.547v.22c0 .427-.166.827-.466 1.127s-.7.466-1.127.466z"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
24: {
|
|
42
|
+
outlined: [
|
|
43
|
+
{
|
|
44
|
+
d: "M17.57 3.86c-.41 0-.75-.34-.75-.75v-1.1c0-.41.34-.75.75-.75s.75.34.75.75v1.1c0 .41-.34.75-.75.75m0 7.69c-.41 0-.75-.34-.75-.75V9.7c0-.41.34-.75.75-.75s.75.34.75.75v1.1c0 .41-.34.75-.75.75"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
d: "M18.23 10.46h-1.21c-.83 0-1.59-.45-2.01-1.16a.752.752 0 1 1 1.3-.76c.15.25.42.41.72.42h1.2a.798.798 0 0 0 .2-1.57l-2.06-.52a2.3 2.3 0 0 1-1.72-2.51 2.29 2.29 0 0 1 2.27-2.01h1.21c.83 0 1.59.45 2 1.16a.752.752 0 1 1-1.3.76.84.84 0 0 0-.71-.41h-1.2a.798.798 0 0 0-.2 1.57l2.06.52c1.12.28 1.86 1.36 1.72 2.5a2.29 2.29 0 0 1-2.27 2.01M5.51 22.74H3.34a1.83 1.83 0 0 1-1.83-1.83v-6.49c0-1.01.82-1.83 1.83-1.83H5.5c1.01 0 1.83.82 1.83 1.83v6.49c0 1.01-.82 1.83-1.83 1.83zm-2.17-8.65c-.18 0-.33.15-.33.33v6.49c0 .18.15.33.33.33H5.5c.18 0 .33-.15.33-.33v-6.49c0-.18-.15-.33-.33-.33z"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
d: "M12.79 22.63q-.63 0-1.23-.15l-2.87-.72c-.28-.07-.58-.11-.87-.11H6.59c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h1.23c.41 0 .83.05 1.23.15l2.87.72c.51.13 1.05.14 1.57.04l3.17-.63c.69-.14 1.33-.48 1.83-.98l2.24-2.24c.17-.17.26-.39.26-.63s-.09-.46-.26-.63a.884.884 0 0 0-1.16-.08l-2.61 1.96c-.5.38-1.12.58-1.75.58h-2.12c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h2.12c.3 0 .6-.1.85-.28l2.61-1.96c.94-.71 2.29-.61 3.12.22.45.45.7 1.05.7 1.69a2.4 2.4 0 0 1-.7 1.69l-2.24 2.24a5.1 5.1 0 0 1-2.59 1.39l-3.17.63c-.33.07-.66.1-.99.1z"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
d: "M14.69 18.42h-1.61c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h1.61c.24 0 .46-.09.63-.26s.26-.39.26-.63v-.33c0-.41-.28-.76-.67-.86l-2.48-.62a4.38 4.38 0 0 0-3.45.6l-1.97 1.31c-.35.23-.81.14-1.04-.21a.745.745 0 0 1 .21-1.04l1.97-1.31a5.92 5.92 0 0 1 4.65-.81l2.48.62c1.07.27 1.81 1.22 1.81 2.32v.33c0 .64-.25 1.24-.7 1.69s-1.05.7-1.69.7z"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
32: {
|
|
58
|
+
outlined: [
|
|
59
|
+
{
|
|
60
|
+
d: "M23.426 5.146c-.547 0-1-.453-1-1V2.68c0-.547.453-1 1-1s1 .453 1 1v1.466c0 .547-.454 1-1 1m0 10.254c-.547 0-1-.453-1-1v-1.466c0-.547.453-1 1-1s1 .453 1 1V14.4c0 .547-.454 1-1 1"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
d: "M24.307 13.946h-1.613c-1.107 0-2.12-.6-2.68-1.547-.28-.48-.12-1.093.36-1.373s1.093-.12 1.373.36c.2.333.56.547.96.56h1.6a1.064 1.064 0 0 0 .267-2.093l-2.747-.694a3.07 3.07 0 0 1-2.293-3.346 3.05 3.05 0 0 1 3.026-2.68h1.614c1.106 0 2.12.6 2.666 1.546a1.003 1.003 0 1 1-1.733 1.014c-.2-.334-.56-.547-.947-.547h-1.6a1.065 1.065 0 0 0-.266 2.093l2.746.694a3.064 3.064 0 0 1 2.294 3.333 3.05 3.05 0 0 1-3.027 2.68M7.347 30.32H4.453a2.44 2.44 0 0 1-2.44-2.44v-8.653a2.44 2.44 0 0 1 2.44-2.44h2.88a2.44 2.44 0 0 1 2.44 2.44v8.653a2.44 2.44 0 0 1-2.44 2.44zM4.453 18.787c-.24 0-.44.2-.44.44v8.653c0 .24.2.44.44.44h2.88c.24 0 .44-.2.44-.44v-8.653c0-.24-.2-.44-.44-.44z"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
d: "M17.053 30.173q-.84 0-1.64-.2l-3.826-.96a5 5 0 0 0-1.16-.147h-1.64c-.547 0-1-.453-1-1s.453-1 1-1h1.64a6.8 6.8 0 0 1 1.64.2l3.826.96c.68.174 1.4.187 2.094.054l4.226-.84a4.8 4.8 0 0 0 2.44-1.307l2.987-2.987c.227-.226.347-.52.347-.84s-.12-.613-.347-.84a1.18 1.18 0 0 0-1.547-.106l-3.48 2.613a3.86 3.86 0 0 1-2.333.773h-2.827c-.546 0-1-.453-1-1s.454-1 1-1h2.827c.4 0 .8-.133 1.133-.373l3.48-2.613c1.254-.947 3.054-.814 4.16.293.6.6.934 1.4.934 2.253s-.347 1.667-.934 2.254l-2.986 2.986a6.8 6.8 0 0 1-3.454 1.854l-4.226.84c-.44.093-.88.133-1.32.133z"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
d: "M19.587 24.56H17.44c-.547 0-1-.453-1-1s.453-1 1-1h2.147c.32 0 .613-.12.84-.346a1.17 1.17 0 0 0 .346-.84v-.44c0-.547-.373-1.014-.893-1.147l-3.307-.827a5.84 5.84 0 0 0-4.6.8l-2.626 1.747a.993.993 0 0 1-1.387-.28.993.993 0 0 1 .28-1.387l2.627-1.746a7.9 7.9 0 0 1 6.2-1.08l3.306.826a3.18 3.18 0 0 1 2.414 3.094v.44c0 .853-.334 1.653-.934 2.253s-1.4.933-2.253.933z"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const ReceiveMoneyIcon = React__namespace.forwardRef(
|
|
75
|
+
(props, ref) => /* @__PURE__ */ jsxRuntime.jsx(BaseIcon.BaseIcon, { ref, variants: VARIANTS, ...props })
|
|
76
|
+
);
|
|
77
|
+
ReceiveMoneyIcon.displayName = "ReceiveMoneyIcon";
|
|
78
|
+
exports.ReceiveMoneyIcon = ReceiveMoneyIcon;
|
|
79
|
+
//# sourceMappingURL=ReceiveMoneyIcon.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReceiveMoneyIcon.cjs","sources":["../../../../src/components/Icons/ReceiveMoneyIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { BaseIcon } from \"./BaseIcon\";\nimport type { BaseIconProps, IconVariants } from \"./types\";\n\nconst VARIANTS: IconVariants = {\n 16: {\n outlined: [\n {\n d: \"M11.713 2.573a.504.504 0 0 1-.5-.5V1.34c0-.273.227-.5.5-.5s.5.227.5.5v.733c0 .274-.227.5-.5.5m0 5.127a.504.504 0 0 1-.5-.5v-.733c0-.274.227-.5.5-.5s.5.226.5.5V7.2c0 .273-.227.5-.5.5\",\n },\n {\n d: \"M12.153 6.973h-.806c-.554 0-1.06-.3-1.34-.773a.501.501 0 1 1 .866-.507c.1.167.28.273.48.28h.8a.532.532 0 0 0 .134-1.047l-1.374-.346a1.535 1.535 0 0 1-1.146-1.674 1.526 1.526 0 0 1 1.513-1.34h.807c.553 0 1.06.3 1.333.774a.501.501 0 1 1-.867.506.56.56 0 0 0-.473-.273h-.8a.532.532 0 0 0-.133 1.047l1.373.346a1.526 1.526 0 0 1-.367 3.007m-8.48 8.187H2.227a1.22 1.22 0 0 1-1.22-1.22V9.613c0-.673.546-1.22 1.22-1.22h1.44c.673 0 1.22.547 1.22 1.22v4.327a1.22 1.22 0 0 1-1.22 1.22zM2.227 9.393c-.12 0-.22.1-.22.22v4.327c0 .12.1.22.22.22h1.44c.12 0 .22-.1.22-.22V9.613c0-.12-.1-.22-.22-.22z\",\n },\n {\n d: \"M8.527 15.087a3.4 3.4 0 0 1-.82-.1l-1.914-.48a2.4 2.4 0 0 0-.58-.074h-.82a.504.504 0 0 1-.5-.5c0-.273.227-.5.5-.5h.82c.274 0 .554.034.82.1l1.914.48c.34.087.7.094 1.046.027l2.114-.42c.46-.093.886-.32 1.22-.653l1.493-1.494a.58.58 0 0 0 .173-.42.59.59 0 0 0-.947-.473l-1.74 1.307a1.93 1.93 0 0 1-1.166.386H8.727a.504.504 0 0 1-.5-.5c0-.273.226-.5.5-.5h1.413c.2 0 .4-.066.567-.186l1.74-1.307a1.6 1.6 0 0 1 2.08.147c.3.3.466.7.466 1.126a1.6 1.6 0 0 1-.466 1.127l-1.494 1.493a3.4 3.4 0 0 1-1.726.927l-2.114.42q-.33.069-.66.067z\",\n },\n {\n d: \"M9.793 12.28H8.72a.504.504 0 0 1-.5-.5c0-.273.227-.5.5-.5h1.073c.16 0 .307-.06.42-.173a.6.6 0 0 0 .174-.42v-.22a.59.59 0 0 0-.447-.573L8.287 9.48a2.92 2.92 0 0 0-2.3.4l-1.314.874a.496.496 0 0 1-.693-.14.496.496 0 0 1 .14-.694l1.313-.873c.907-.6 2.047-.8 3.1-.54l1.654.413a1.59 1.59 0 0 1 1.206 1.547v.22c0 .427-.166.827-.466 1.127s-.7.466-1.127.466z\",\n },\n ],\n },\n 24: {\n outlined: [\n {\n d: \"M17.57 3.86c-.41 0-.75-.34-.75-.75v-1.1c0-.41.34-.75.75-.75s.75.34.75.75v1.1c0 .41-.34.75-.75.75m0 7.69c-.41 0-.75-.34-.75-.75V9.7c0-.41.34-.75.75-.75s.75.34.75.75v1.1c0 .41-.34.75-.75.75\",\n },\n {\n d: \"M18.23 10.46h-1.21c-.83 0-1.59-.45-2.01-1.16a.752.752 0 1 1 1.3-.76c.15.25.42.41.72.42h1.2a.798.798 0 0 0 .2-1.57l-2.06-.52a2.3 2.3 0 0 1-1.72-2.51 2.29 2.29 0 0 1 2.27-2.01h1.21c.83 0 1.59.45 2 1.16a.752.752 0 1 1-1.3.76.84.84 0 0 0-.71-.41h-1.2a.798.798 0 0 0-.2 1.57l2.06.52c1.12.28 1.86 1.36 1.72 2.5a2.29 2.29 0 0 1-2.27 2.01M5.51 22.74H3.34a1.83 1.83 0 0 1-1.83-1.83v-6.49c0-1.01.82-1.83 1.83-1.83H5.5c1.01 0 1.83.82 1.83 1.83v6.49c0 1.01-.82 1.83-1.83 1.83zm-2.17-8.65c-.18 0-.33.15-.33.33v6.49c0 .18.15.33.33.33H5.5c.18 0 .33-.15.33-.33v-6.49c0-.18-.15-.33-.33-.33z\",\n },\n {\n d: \"M12.79 22.63q-.63 0-1.23-.15l-2.87-.72c-.28-.07-.58-.11-.87-.11H6.59c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h1.23c.41 0 .83.05 1.23.15l2.87.72c.51.13 1.05.14 1.57.04l3.17-.63c.69-.14 1.33-.48 1.83-.98l2.24-2.24c.17-.17.26-.39.26-.63s-.09-.46-.26-.63a.884.884 0 0 0-1.16-.08l-2.61 1.96c-.5.38-1.12.58-1.75.58h-2.12c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h2.12c.3 0 .6-.1.85-.28l2.61-1.96c.94-.71 2.29-.61 3.12.22.45.45.7 1.05.7 1.69a2.4 2.4 0 0 1-.7 1.69l-2.24 2.24a5.1 5.1 0 0 1-2.59 1.39l-3.17.63c-.33.07-.66.1-.99.1z\",\n },\n {\n d: \"M14.69 18.42h-1.61c-.41 0-.75-.34-.75-.75s.34-.75.75-.75h1.61c.24 0 .46-.09.63-.26s.26-.39.26-.63v-.33c0-.41-.28-.76-.67-.86l-2.48-.62a4.38 4.38 0 0 0-3.45.6l-1.97 1.31c-.35.23-.81.14-1.04-.21a.745.745 0 0 1 .21-1.04l1.97-1.31a5.92 5.92 0 0 1 4.65-.81l2.48.62c1.07.27 1.81 1.22 1.81 2.32v.33c0 .64-.25 1.24-.7 1.69s-1.05.7-1.69.7z\",\n },\n ],\n },\n 32: {\n outlined: [\n {\n d: \"M23.426 5.146c-.547 0-1-.453-1-1V2.68c0-.547.453-1 1-1s1 .453 1 1v1.466c0 .547-.454 1-1 1m0 10.254c-.547 0-1-.453-1-1v-1.466c0-.547.453-1 1-1s1 .453 1 1V14.4c0 .547-.454 1-1 1\",\n },\n {\n d: \"M24.307 13.946h-1.613c-1.107 0-2.12-.6-2.68-1.547-.28-.48-.12-1.093.36-1.373s1.093-.12 1.373.36c.2.333.56.547.96.56h1.6a1.064 1.064 0 0 0 .267-2.093l-2.747-.694a3.07 3.07 0 0 1-2.293-3.346 3.05 3.05 0 0 1 3.026-2.68h1.614c1.106 0 2.12.6 2.666 1.546a1.003 1.003 0 1 1-1.733 1.014c-.2-.334-.56-.547-.947-.547h-1.6a1.065 1.065 0 0 0-.266 2.093l2.746.694a3.064 3.064 0 0 1 2.294 3.333 3.05 3.05 0 0 1-3.027 2.68M7.347 30.32H4.453a2.44 2.44 0 0 1-2.44-2.44v-8.653a2.44 2.44 0 0 1 2.44-2.44h2.88a2.44 2.44 0 0 1 2.44 2.44v8.653a2.44 2.44 0 0 1-2.44 2.44zM4.453 18.787c-.24 0-.44.2-.44.44v8.653c0 .24.2.44.44.44h2.88c.24 0 .44-.2.44-.44v-8.653c0-.24-.2-.44-.44-.44z\",\n },\n {\n d: \"M17.053 30.173q-.84 0-1.64-.2l-3.826-.96a5 5 0 0 0-1.16-.147h-1.64c-.547 0-1-.453-1-1s.453-1 1-1h1.64a6.8 6.8 0 0 1 1.64.2l3.826.96c.68.174 1.4.187 2.094.054l4.226-.84a4.8 4.8 0 0 0 2.44-1.307l2.987-2.987c.227-.226.347-.52.347-.84s-.12-.613-.347-.84a1.18 1.18 0 0 0-1.547-.106l-3.48 2.613a3.86 3.86 0 0 1-2.333.773h-2.827c-.546 0-1-.453-1-1s.454-1 1-1h2.827c.4 0 .8-.133 1.133-.373l3.48-2.613c1.254-.947 3.054-.814 4.16.293.6.6.934 1.4.934 2.253s-.347 1.667-.934 2.254l-2.986 2.986a6.8 6.8 0 0 1-3.454 1.854l-4.226.84c-.44.093-.88.133-1.32.133z\",\n },\n {\n d: \"M19.587 24.56H17.44c-.547 0-1-.453-1-1s.453-1 1-1h2.147c.32 0 .613-.12.84-.346a1.17 1.17 0 0 0 .346-.84v-.44c0-.547-.373-1.014-.893-1.147l-3.307-.827a5.84 5.84 0 0 0-4.6.8l-2.626 1.747a.993.993 0 0 1-1.387-.28.993.993 0 0 1 .28-1.387l2.627-1.746a7.9 7.9 0 0 1 6.2-1.08l3.306.826a3.18 3.18 0 0 1 2.414 3.094v.44c0 .853-.334 1.653-.934 2.253s-1.4.933-2.253.933z\",\n },\n ],\n },\n};\n\n/** Props for {@link ReceiveMoneyIcon}. See {@link BaseIconProps} for the shared shape. */\nexport type ReceiveMoneyIconProps = BaseIconProps;\n\n/**\n * Receive Money icon. Renders at sizes 16, 24, or 32 px.\n *\n * @example\n * ```tsx\n * <ReceiveMoneyIcon size={24} />\n * ```\n */\nexport const ReceiveMoneyIcon = React.forwardRef<SVGSVGElement, ReceiveMoneyIconProps>(\n (props, ref) => <BaseIcon ref={ref} variants={VARIANTS} {...props} />,\n);\n\nReceiveMoneyIcon.displayName = \"ReceiveMoneyIcon\";\n"],"names":["React","jsx","BaseIcon"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAIA,MAAM,WAAyB;AAAA,EAC7B,IAAI;AAAA,IACF,UAAU;AAAA,MACR;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,IACL;AAAA,EACF;AAAA,EAEF,IAAI;AAAA,IACF,UAAU;AAAA,MACR;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,IACL;AAAA,EACF;AAAA,EAEF,IAAI;AAAA,IACF,UAAU;AAAA,MACR;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,MAEL;AAAA,QACE,GAAG;AAAA,MAAA;AAAA,IACL;AAAA,EACF;AAEJ;AAaO,MAAM,mBAAmBA,iBAAM;AAAA,EACpC,CAAC,OAAO,QAAQC,2BAAAA,IAACC,SAAAA,YAAS,KAAU,UAAU,UAAW,GAAG,MAAA,CAAO;AACrE;AAEA,iBAAiB,cAAc;;"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const React = require("react");
|
|
6
|
+
const cn = require("../../utils/cn.cjs");
|
|
7
|
+
const ChevronDownIcon = require("../Icons/ChevronDownIcon.cjs");
|
|
8
|
+
function _interopNamespaceDefault(e) {
|
|
9
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
10
|
+
if (e) {
|
|
11
|
+
for (const k in e) {
|
|
12
|
+
if (k !== "default") {
|
|
13
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: () => e[k]
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
25
|
+
const CONTAINER_HEIGHT = {
|
|
26
|
+
"48": "h-12",
|
|
27
|
+
"40": "h-10",
|
|
28
|
+
"32": "h-8"
|
|
29
|
+
};
|
|
30
|
+
const CONTAINER_PADDING_X = {
|
|
31
|
+
"48": "px-4",
|
|
32
|
+
"40": "px-4",
|
|
33
|
+
"32": "px-3"
|
|
34
|
+
};
|
|
35
|
+
const INPUT_TYPOGRAPHY = {
|
|
36
|
+
"48": "typography-body-default-16px-regular autofill-body-lg",
|
|
37
|
+
"40": "typography-body-default-16px-regular autofill-body-lg",
|
|
38
|
+
"32": "typography-body-small-14px-regular autofill-body-md"
|
|
39
|
+
};
|
|
40
|
+
const PREFIX_TYPOGRAPHY = {
|
|
41
|
+
"48": "typography-body-default-16px-regular",
|
|
42
|
+
"40": "typography-body-default-16px-regular",
|
|
43
|
+
"32": "typography-body-small-14px-regular"
|
|
44
|
+
};
|
|
45
|
+
function getContainerClassName(size, error, disabled) {
|
|
46
|
+
return cn.cn(
|
|
47
|
+
"relative flex items-center gap-2 overflow-hidden rounded-sm border bg-inputs-inputs-primary has-focus-visible:shadow-focus-ring has-focus-visible:outline-none motion-safe:transition-colors",
|
|
48
|
+
CONTAINER_PADDING_X[size],
|
|
49
|
+
CONTAINER_HEIGHT[size],
|
|
50
|
+
error ? "border-error-content" : "border-border-primary",
|
|
51
|
+
!disabled && !error && "hover:border-neutral-alphas-400",
|
|
52
|
+
disabled && "opacity-50"
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function warnMissingAccessibleName(label, ariaLabel, ariaLabelledBy) {
|
|
56
|
+
if (process.env.NODE_ENV !== "production") {
|
|
57
|
+
if (!label && !ariaLabel && !ariaLabelledBy) {
|
|
58
|
+
console.warn(
|
|
59
|
+
"PhoneField: no accessible name provided. Pass a `label`, `aria-label`, or `aria-labelledby` prop."
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function PhoneFieldHelperText({
|
|
65
|
+
id,
|
|
66
|
+
error,
|
|
67
|
+
children
|
|
68
|
+
}) {
|
|
69
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
70
|
+
"p",
|
|
71
|
+
{
|
|
72
|
+
id,
|
|
73
|
+
className: cn.cn(
|
|
74
|
+
"typography-description-12px-regular pt-2",
|
|
75
|
+
error ? "text-error-content" : "text-content-tertiary"
|
|
76
|
+
),
|
|
77
|
+
children
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const PhoneField = React__namespace.forwardRef(
|
|
82
|
+
({
|
|
83
|
+
label,
|
|
84
|
+
helperText,
|
|
85
|
+
size = "48",
|
|
86
|
+
error = false,
|
|
87
|
+
errorMessage,
|
|
88
|
+
dialCode,
|
|
89
|
+
flag,
|
|
90
|
+
onCountrySelect,
|
|
91
|
+
countryButtonLabel = "Select country",
|
|
92
|
+
className,
|
|
93
|
+
id,
|
|
94
|
+
disabled,
|
|
95
|
+
fullWidth = false,
|
|
96
|
+
type = "tel",
|
|
97
|
+
...props
|
|
98
|
+
}, ref) => {
|
|
99
|
+
const generatedId = React__namespace.useId();
|
|
100
|
+
const inputId = id || generatedId;
|
|
101
|
+
const helperTextId = `${inputId}-helper`;
|
|
102
|
+
const dialCodeId = `${inputId}-dial-code`;
|
|
103
|
+
const bottomText = error && errorMessage ? errorMessage : helperText;
|
|
104
|
+
const describedBy = [dialCode != null ? dialCodeId : null, bottomText ? helperTextId : null].filter(Boolean).join(" ") || void 0;
|
|
105
|
+
const innerRef = React__namespace.useRef(null);
|
|
106
|
+
const setRefs = React__namespace.useCallback(
|
|
107
|
+
(node) => {
|
|
108
|
+
innerRef.current = node;
|
|
109
|
+
if (typeof ref === "function") ref(node);
|
|
110
|
+
else if (ref) ref.current = node;
|
|
111
|
+
},
|
|
112
|
+
[ref]
|
|
113
|
+
);
|
|
114
|
+
const handleContainerMouseDown = (event) => {
|
|
115
|
+
if (disabled) return;
|
|
116
|
+
const target = event.target;
|
|
117
|
+
if (target === innerRef.current) return;
|
|
118
|
+
if (target.closest("[data-pf-interactive]")) return;
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
innerRef.current?.focus();
|
|
121
|
+
};
|
|
122
|
+
warnMissingAccessibleName(label, props["aria-label"], props["aria-labelledby"]);
|
|
123
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
124
|
+
"div",
|
|
125
|
+
{
|
|
126
|
+
className: cn.cn("flex flex-col", fullWidth && "w-full", className),
|
|
127
|
+
"data-disabled": disabled ? "" : void 0,
|
|
128
|
+
"data-error": error ? "" : void 0,
|
|
129
|
+
children: [
|
|
130
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(
|
|
131
|
+
"label",
|
|
132
|
+
{
|
|
133
|
+
htmlFor: inputId,
|
|
134
|
+
className: "typography-description-12px-semibold pb-2 text-content-primary",
|
|
135
|
+
children: label
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
139
|
+
"div",
|
|
140
|
+
{
|
|
141
|
+
className: getContainerClassName(size, error, disabled),
|
|
142
|
+
onMouseDown: handleContainerMouseDown,
|
|
143
|
+
children: [
|
|
144
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
145
|
+
"button",
|
|
146
|
+
{
|
|
147
|
+
type: "button",
|
|
148
|
+
"data-pf-interactive": "",
|
|
149
|
+
onClick: onCountrySelect,
|
|
150
|
+
disabled,
|
|
151
|
+
"aria-label": countryButtonLabel,
|
|
152
|
+
className: "flex shrink-0 items-center gap-1 rounded-2xs focus-visible:shadow-focus-ring focus-visible:outline-none disabled:cursor-not-allowed",
|
|
153
|
+
children: [
|
|
154
|
+
flag != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-6 shrink-0 items-center justify-center overflow-hidden rounded-full", children: flag }),
|
|
155
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon.ChevronDownIcon, { size: 16, className: "shrink-0 text-content-secondary" })
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
dialCode != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
160
|
+
"span",
|
|
161
|
+
{
|
|
162
|
+
id: dialCodeId,
|
|
163
|
+
className: cn.cn(
|
|
164
|
+
"shrink-0 select-none whitespace-nowrap text-content-primary",
|
|
165
|
+
PREFIX_TYPOGRAPHY[size]
|
|
166
|
+
),
|
|
167
|
+
children: dialCode
|
|
168
|
+
}
|
|
169
|
+
),
|
|
170
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
171
|
+
"input",
|
|
172
|
+
{
|
|
173
|
+
ref: setRefs,
|
|
174
|
+
id: inputId,
|
|
175
|
+
type,
|
|
176
|
+
inputMode: "tel",
|
|
177
|
+
disabled,
|
|
178
|
+
"aria-describedby": describedBy,
|
|
179
|
+
"aria-invalid": error || void 0,
|
|
180
|
+
className: cn.cn(
|
|
181
|
+
"h-full min-w-0 flex-1 bg-transparent text-content-primary no-underline placeholder:text-content-tertiary focus:outline-none disabled:cursor-not-allowed",
|
|
182
|
+
INPUT_TYPOGRAPHY[size]
|
|
183
|
+
),
|
|
184
|
+
...props
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
bottomText && /* @__PURE__ */ jsxRuntime.jsx(PhoneFieldHelperText, { id: helperTextId, error, children: bottomText })
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
PhoneField.displayName = "PhoneField";
|
|
197
|
+
exports.PhoneField = PhoneField;
|
|
198
|
+
//# sourceMappingURL=PhoneField.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PhoneField.cjs","sources":["../../../../src/components/PhoneField/PhoneField.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { ChevronDownIcon } from \"../Icons/ChevronDownIcon\";\n\n/** Phone field height in pixels. */\nexport type PhoneFieldSize = \"48\" | \"40\" | \"32\";\n\nexport interface PhoneFieldProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n /** Label text displayed above the input. Also used as the accessible name. */\n label?: string;\n /** Helper text displayed below the input. Replaced by `errorMessage` when `error` is `true`. */\n helperText?: string;\n /** Height of the phone field in pixels. @default \"48\" */\n size?: PhoneFieldSize;\n /** Whether the field is in an error state. @default false */\n error?: boolean;\n /** Error message displayed below the input. Shown instead of `helperText` when `error` is `true`. */\n errorMessage?: string;\n /** Dial code of the selected country, shown before the number (e.g. `\"+39\"`). */\n dialCode?: React.ReactNode;\n /** Flag of the selected country, rendered in the country selector (e.g. an image or flag icon). */\n flag?: React.ReactNode;\n /** Fired when the country selector (flag + chevron) is activated. Open the country picker here. */\n onCountrySelect?: () => void;\n /** Accessible name for the country selector button. @default \"Select country\" */\n countryButtonLabel?: string;\n /** Whether the field stretches to fill its container width. @default false */\n fullWidth?: boolean;\n}\n\nconst CONTAINER_HEIGHT: Record<PhoneFieldSize, string> = {\n \"48\": \"h-12\",\n \"40\": \"h-10\",\n \"32\": \"h-8\",\n};\n\nconst CONTAINER_PADDING_X: Record<PhoneFieldSize, string> = {\n \"48\": \"px-4\",\n \"40\": \"px-4\",\n \"32\": \"px-3\",\n};\n\nconst INPUT_TYPOGRAPHY: Record<PhoneFieldSize, string> = {\n \"48\": \"typography-body-default-16px-regular autofill-body-lg\",\n \"40\": \"typography-body-default-16px-regular autofill-body-lg\",\n \"32\": \"typography-body-small-14px-regular autofill-body-md\",\n};\n\nconst PREFIX_TYPOGRAPHY: Record<PhoneFieldSize, string> = {\n \"48\": \"typography-body-default-16px-regular\",\n \"40\": \"typography-body-default-16px-regular\",\n \"32\": \"typography-body-small-14px-regular\",\n};\n\nfunction getContainerClassName(size: PhoneFieldSize, error: boolean, disabled?: boolean) {\n return cn(\n \"relative flex items-center gap-2 overflow-hidden rounded-sm border bg-inputs-inputs-primary has-focus-visible:shadow-focus-ring has-focus-visible:outline-none motion-safe:transition-colors\",\n CONTAINER_PADDING_X[size],\n CONTAINER_HEIGHT[size],\n error ? \"border-error-content\" : \"border-border-primary\",\n !disabled && !error && \"hover:border-neutral-alphas-400\",\n disabled && \"opacity-50\",\n );\n}\n\nfunction warnMissingAccessibleName(label?: string, ariaLabel?: string, ariaLabelledBy?: string) {\n if (process.env.NODE_ENV !== \"production\") {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n \"PhoneField: no accessible name provided. Pass a `label`, `aria-label`, or `aria-labelledby` prop.\",\n );\n }\n }\n}\n\nfunction PhoneFieldHelperText({\n id,\n error,\n children,\n}: {\n id: string;\n error: boolean;\n children: React.ReactNode;\n}) {\n return (\n <p\n id={id}\n className={cn(\n \"typography-description-12px-regular pt-2\",\n error ? \"text-error-content\" : \"text-content-tertiary\",\n )}\n >\n {children}\n </p>\n );\n}\n\n/**\n * A phone number input with a country selector (flag + chevron), a fixed dial\n * code prefix, and a `tel` input. The country picker itself is owned by the\n * consumer: pass the selected country's `flag` and `dialCode`, and open your\n * picker from `onCountrySelect`.\n *\n * Provide at least one of `label`, `aria-label`, or `aria-labelledby` for\n * accessibility — a console warning is emitted in development if none are set.\n *\n * @example\n * ```tsx\n * <PhoneField\n * label=\"Phone number\"\n * flag={<img src={italyFlag} alt=\"\" />}\n * dialCode=\"+39\"\n * onCountrySelect={openCountryPicker}\n * value={number}\n * onChange={(e) => setNumber(e.target.value)}\n * />\n * ```\n */\nexport const PhoneField = React.forwardRef<HTMLInputElement, PhoneFieldProps>(\n (\n {\n label,\n helperText,\n size = \"48\",\n error = false,\n errorMessage,\n dialCode,\n flag,\n onCountrySelect,\n countryButtonLabel = \"Select country\",\n className,\n id,\n disabled,\n fullWidth = false,\n type = \"tel\",\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const inputId = id || generatedId;\n const helperTextId = `${inputId}-helper`;\n const dialCodeId = `${inputId}-dial-code`;\n const bottomText = error && errorMessage ? errorMessage : helperText;\n\n const describedBy =\n [dialCode != null ? dialCodeId : null, bottomText ? helperTextId : null]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const innerRef = React.useRef<HTMLInputElement>(null);\n const setRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.RefObject<HTMLInputElement | null>).current = node;\n },\n [ref],\n );\n\n const handleContainerMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return;\n const target = event.target as HTMLElement;\n if (target === innerRef.current) return;\n if (target.closest(\"[data-pf-interactive]\")) return;\n event.preventDefault();\n innerRef.current?.focus();\n };\n\n warnMissingAccessibleName(label, props[\"aria-label\"], props[\"aria-labelledby\"]);\n\n return (\n <div\n className={cn(\"flex flex-col\", fullWidth && \"w-full\", className)}\n data-disabled={disabled ? \"\" : undefined}\n data-error={error ? \"\" : undefined}\n >\n {label && (\n <label\n htmlFor={inputId}\n className=\"typography-description-12px-semibold pb-2 text-content-primary\"\n >\n {label}\n </label>\n )}\n\n {/* biome-ignore lint/a11y/noStaticElementInteractions: focus bridge delegates pointer clicks on the padding to the input */}\n <div\n className={getContainerClassName(size, error, disabled)}\n onMouseDown={handleContainerMouseDown}\n >\n <button\n type=\"button\"\n data-pf-interactive=\"\"\n onClick={onCountrySelect}\n disabled={disabled}\n aria-label={countryButtonLabel}\n className=\"flex shrink-0 items-center gap-1 rounded-2xs focus-visible:shadow-focus-ring focus-visible:outline-none disabled:cursor-not-allowed\"\n >\n {flag != null && (\n <span className=\"flex size-6 shrink-0 items-center justify-center overflow-hidden rounded-full\">\n {flag}\n </span>\n )}\n <ChevronDownIcon size={16} className=\"shrink-0 text-content-secondary\" />\n </button>\n\n {dialCode != null && (\n <span\n id={dialCodeId}\n className={cn(\n \"shrink-0 select-none whitespace-nowrap text-content-primary\",\n PREFIX_TYPOGRAPHY[size],\n )}\n >\n {dialCode}\n </span>\n )}\n\n <input\n ref={setRefs}\n id={inputId}\n type={type}\n inputMode=\"tel\"\n disabled={disabled}\n aria-describedby={describedBy}\n aria-invalid={error || undefined}\n className={cn(\n \"h-full min-w-0 flex-1 bg-transparent text-content-primary no-underline placeholder:text-content-tertiary focus:outline-none disabled:cursor-not-allowed\",\n INPUT_TYPOGRAPHY[size],\n )}\n {...props}\n />\n </div>\n\n {bottomText && (\n <PhoneFieldHelperText id={helperTextId} error={error}>\n {bottomText}\n </PhoneFieldHelperText>\n )}\n </div>\n );\n },\n);\n\nPhoneField.displayName = \"PhoneField\";\n"],"names":["cn","jsx","React","jsxs","ChevronDownIcon"],"mappings":"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"}
|