@revikornmann/muka-ui 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/cjs/components/ChatComposer/ChatComposer.js +12 -4
  2. package/dist/cjs/components/ChatComposer/ChatComposer.js.map +1 -1
  3. package/dist/cjs/components/EmojiPicker/EmojiPicker.css +19 -0
  4. package/dist/cjs/components/EmojiPicker/EmojiPicker.js +54 -0
  5. package/dist/cjs/components/EmojiPicker/EmojiPicker.js.map +1 -0
  6. package/dist/cjs/components/EmojiPicker/index.js +12 -0
  7. package/dist/cjs/components/EmojiPicker/index.js.map +1 -0
  8. package/dist/cjs/components/PhotoDraftStrip/PhotoDraftStrip.css +27 -0
  9. package/dist/cjs/components/PhotoDraftStrip/PhotoDraftStrip.js +36 -0
  10. package/dist/cjs/components/PhotoDraftStrip/PhotoDraftStrip.js.map +1 -0
  11. package/dist/cjs/components/PhotoDraftStrip/index.js +11 -0
  12. package/dist/cjs/components/PhotoDraftStrip/index.js.map +1 -0
  13. package/dist/cjs/components/RecordingBar/RecordingBar.css +47 -0
  14. package/dist/cjs/components/RecordingBar/RecordingBar.js +22 -0
  15. package/dist/cjs/components/RecordingBar/RecordingBar.js.map +1 -0
  16. package/dist/cjs/components/RecordingBar/index.js +11 -0
  17. package/dist/cjs/components/RecordingBar/index.js.map +1 -0
  18. package/dist/cjs/components/VoiceMessage/VoiceMessage.css +29 -0
  19. package/dist/cjs/components/VoiceMessage/VoiceMessage.js +85 -0
  20. package/dist/cjs/components/VoiceMessage/VoiceMessage.js.map +1 -0
  21. package/dist/cjs/components/VoiceMessage/index.js +11 -0
  22. package/dist/cjs/components/VoiceMessage/index.js.map +1 -0
  23. package/dist/cjs/components/VoiceRecorder/audio.js +61 -0
  24. package/dist/cjs/components/VoiceRecorder/audio.js.map +1 -0
  25. package/dist/cjs/components/VoiceRecorder/index.js +16 -0
  26. package/dist/cjs/components/VoiceRecorder/index.js.map +1 -0
  27. package/dist/cjs/components/VoiceRecorder/useVoiceRecorder.js +213 -0
  28. package/dist/cjs/components/VoiceRecorder/useVoiceRecorder.js.map +1 -0
  29. package/dist/cjs/components/Waveform/Waveform.css +23 -0
  30. package/dist/cjs/components/Waveform/Waveform.js +36 -0
  31. package/dist/cjs/components/Waveform/Waveform.js.map +1 -0
  32. package/dist/cjs/components/Waveform/index.js +11 -0
  33. package/dist/cjs/components/Waveform/index.js.map +1 -0
  34. package/dist/cjs/components/index.js +18 -1
  35. package/dist/cjs/components/index.js.map +1 -1
  36. package/dist/esm/components/ChatComposer/ChatComposer.js +12 -4
  37. package/dist/esm/components/ChatComposer/ChatComposer.js.map +1 -1
  38. package/dist/esm/components/EmojiPicker/EmojiPicker.css +19 -0
  39. package/dist/esm/components/EmojiPicker/EmojiPicker.js +50 -0
  40. package/dist/esm/components/EmojiPicker/EmojiPicker.js.map +1 -0
  41. package/dist/esm/components/EmojiPicker/index.js +3 -0
  42. package/dist/esm/components/EmojiPicker/index.js.map +1 -0
  43. package/dist/esm/components/PhotoDraftStrip/PhotoDraftStrip.css +27 -0
  44. package/dist/esm/components/PhotoDraftStrip/PhotoDraftStrip.js +32 -0
  45. package/dist/esm/components/PhotoDraftStrip/PhotoDraftStrip.js.map +1 -0
  46. package/dist/esm/components/PhotoDraftStrip/index.js +3 -0
  47. package/dist/esm/components/PhotoDraftStrip/index.js.map +1 -0
  48. package/dist/esm/components/RecordingBar/RecordingBar.css +47 -0
  49. package/dist/esm/components/RecordingBar/RecordingBar.js +18 -0
  50. package/dist/esm/components/RecordingBar/RecordingBar.js.map +1 -0
  51. package/dist/esm/components/RecordingBar/index.js +3 -0
  52. package/dist/esm/components/RecordingBar/index.js.map +1 -0
  53. package/dist/esm/components/VoiceMessage/VoiceMessage.css +29 -0
  54. package/dist/esm/components/VoiceMessage/VoiceMessage.js +81 -0
  55. package/dist/esm/components/VoiceMessage/VoiceMessage.js.map +1 -0
  56. package/dist/esm/components/VoiceMessage/index.js +3 -0
  57. package/dist/esm/components/VoiceMessage/index.js.map +1 -0
  58. package/dist/esm/components/VoiceRecorder/audio.js +55 -0
  59. package/dist/esm/components/VoiceRecorder/audio.js.map +1 -0
  60. package/dist/esm/components/VoiceRecorder/index.js +4 -0
  61. package/dist/esm/components/VoiceRecorder/index.js.map +1 -0
  62. package/dist/esm/components/VoiceRecorder/useVoiceRecorder.js +210 -0
  63. package/dist/esm/components/VoiceRecorder/useVoiceRecorder.js.map +1 -0
  64. package/dist/esm/components/Waveform/Waveform.css +23 -0
  65. package/dist/esm/components/Waveform/Waveform.js +32 -0
  66. package/dist/esm/components/Waveform/Waveform.js.map +1 -0
  67. package/dist/esm/components/Waveform/index.js +3 -0
  68. package/dist/esm/components/Waveform/index.js.map +1 -0
  69. package/dist/esm/components/index.js +6 -0
  70. package/dist/esm/components/index.js.map +1 -1
  71. package/dist/styles/components/EmojiPicker.css +19 -0
  72. package/dist/styles/components/PhotoDraftStrip.css +27 -0
  73. package/dist/styles/components/RecordingBar.css +47 -0
  74. package/dist/styles/components/VoiceMessage.css +29 -0
  75. package/dist/styles/components/Waveform.css +23 -0
  76. package/dist/styles/index.css +516 -356
  77. package/dist/styles/muka-dark.css +516 -356
  78. package/dist/styles/muka-light.css +516 -356
  79. package/dist/styles/wireframe-dark.css +516 -356
  80. package/dist/styles/wireframe-light.css +516 -356
  81. package/dist/types/components/ChatComposer/ChatComposer.d.ts +7 -0
  82. package/dist/types/components/ChatComposer/ChatComposer.d.ts.map +1 -1
  83. package/dist/types/components/EmojiPicker/EmojiPicker.d.ts +28 -0
  84. package/dist/types/components/EmojiPicker/EmojiPicker.d.ts.map +1 -0
  85. package/dist/types/components/EmojiPicker/index.d.ts +3 -0
  86. package/dist/types/components/EmojiPicker/index.d.ts.map +1 -0
  87. package/dist/types/components/PhotoDraftStrip/PhotoDraftStrip.d.ts +51 -0
  88. package/dist/types/components/PhotoDraftStrip/PhotoDraftStrip.d.ts.map +1 -0
  89. package/dist/types/components/PhotoDraftStrip/index.d.ts +3 -0
  90. package/dist/types/components/PhotoDraftStrip/index.d.ts.map +1 -0
  91. package/dist/types/components/RecordingBar/RecordingBar.d.ts +22 -0
  92. package/dist/types/components/RecordingBar/RecordingBar.d.ts.map +1 -0
  93. package/dist/types/components/RecordingBar/index.d.ts +3 -0
  94. package/dist/types/components/RecordingBar/index.d.ts.map +1 -0
  95. package/dist/types/components/VoiceMessage/VoiceMessage.d.ts +34 -0
  96. package/dist/types/components/VoiceMessage/VoiceMessage.d.ts.map +1 -0
  97. package/dist/types/components/VoiceMessage/index.d.ts +3 -0
  98. package/dist/types/components/VoiceMessage/index.d.ts.map +1 -0
  99. package/dist/types/components/VoiceRecorder/audio.d.ts +20 -0
  100. package/dist/types/components/VoiceRecorder/audio.d.ts.map +1 -0
  101. package/dist/types/components/VoiceRecorder/index.d.ts +4 -0
  102. package/dist/types/components/VoiceRecorder/index.d.ts.map +1 -0
  103. package/dist/types/components/VoiceRecorder/useVoiceRecorder.d.ts +48 -0
  104. package/dist/types/components/VoiceRecorder/useVoiceRecorder.d.ts.map +1 -0
  105. package/dist/types/components/Waveform/Waveform.d.ts +31 -0
  106. package/dist/types/components/Waveform/Waveform.d.ts.map +1 -0
  107. package/dist/types/components/Waveform/index.d.ts +3 -0
  108. package/dist/types/components/Waveform/index.d.ts.map +1 -0
  109. package/dist/types/components/index.d.ts +6 -0
  110. package/dist/types/components/index.d.ts.map +1 -1
  111. package/package.json +1 -1
@@ -17,7 +17,7 @@ require("./ChatComposer.css");
17
17
  * strip. Submits on Enter (Shift+Enter for a newline). Designed to live in a
18
18
  * `BottomBar`.
19
19
  */
20
- exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, placeholder = 'Reply...', onLeadingClick, leadingIcon = 'add', leadingLabel = 'Add attachment', onEmoji, showEmoji = true, emojiLabel = 'Add emoji', onRecordStart, micLabel = 'Record voice message', sendLabel = 'Send message', recording = false, recordingSlot, onRecordPause, onRecordDiscard, pauseLabel = 'Pause recording', discardLabel = 'Discard recording', attachments, attachmentsOverflowLabel = 'Show more attachments', loading = false, disabled = false, maxLines = 10, autoFocus = false, className = '', }, forwardedRef) => {
20
+ exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, placeholder = 'Reply...', onLeadingClick, leadingIcon = 'add', leadingLabel = 'Add attachment', onEmoji, showEmoji = true, emojiLabel = 'Add emoji', onRecordStart, micLabel = 'Record voice message', sendLabel = 'Send message', canSubmit: canSubmitProp, recording = false, recordingSlot, onRecordPause, onRecordDiscard, pauseLabel = 'Pause recording', discardLabel = 'Discard recording', attachments, attachmentsOverflowLabel = 'Show more attachments', loading = false, disabled = false, maxLines = 10, autoFocus = false, className = '', }, forwardedRef) => {
21
21
  const textareaRef = (0, react_1.useRef)(null);
22
22
  const attachmentsRef = (0, react_1.useRef)(null);
23
23
  (0, react_1.useImperativeHandle)(forwardedRef, () => textareaRef.current);
@@ -33,9 +33,12 @@ exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, pla
33
33
  el.style.height = `${next}px`;
34
34
  el.style.overflowY = el.scrollHeight > maxHeight ? 'auto' : 'hidden';
35
35
  }, [value, maxLines, recording]);
36
+ // `canSubmit` overrides the default "text is non-empty" rule when provided,
37
+ // so a caption-less gallery send can be enabled from staged attachments.
38
+ const textEnabled = canSubmitProp ?? value.trim().length > 0;
36
39
  const canSubmit = recording
37
40
  ? !disabled && !loading
38
- : !disabled && !loading && value.trim().length > 0;
41
+ : !disabled && !loading && textEnabled;
39
42
  const handleSubmit = () => {
40
43
  if (!canSubmit)
41
44
  return;
@@ -54,8 +57,13 @@ exports.ChatComposer = (0, react_1.forwardRef)(({ value, onChange, onSubmit, pla
54
57
  el.scrollBy({ left: el.clientWidth * 0.8, behavior: 'smooth' });
55
58
  };
56
59
  // Trailing button is a mic only when the field is empty, not recording, and
57
- // a record handler is supplied; otherwise it is the send button.
58
- const showMic = !recording && onRecordStart && value.trim().length === 0;
60
+ // a record handler is supplied; otherwise it is the send button. When send
61
+ // enablement is controlled (`canSubmit`), always show send so a caption-less
62
+ // gallery can be sent from an empty field.
63
+ const showMic = !recording &&
64
+ onRecordStart &&
65
+ canSubmitProp === undefined &&
66
+ value.trim().length === 0;
59
67
  const classes = [
60
68
  'muka-chat-composer',
61
69
  recording && 'muka-chat-composer--recording',
@@ -1 +1 @@
1
- {"version":3,"file":"ChatComposer.js","sourceRoot":"","sources":["../../../../components/ChatComposer/ChatComposer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatComposer.js","sourceRoot":"","sources":["../../../../components/ChatComposer/ChatComposer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /* EmojiPicker Component Styles */
2
+
3
+ .muka-emoji-picker {
4
+ display: grid;
5
+ grid-template-columns: repeat(8, 1fr);
6
+ gap: var(--spacing-1);
7
+ padding: var(--spacing-2);
8
+ max-height: 12rem;
9
+ overflow-y: auto;
10
+ background: var(--color-surface-level2);
11
+ border: var(--border-width-regular, 1px) solid var(--color-border-default);
12
+ border-radius: var(--radius-lg);
13
+ box-shadow: var(--menu-content-shadow, 0 4px 12px rgba(0, 0, 0, 0.12));
14
+ }
15
+
16
+ .muka-emoji-picker__glyph {
17
+ font-size: 1.25rem;
18
+ line-height: 1;
19
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.EmojiPicker = exports.DEFAULT_EMOJI = void 0;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const Button_1 = require("../Button");
8
+ require("./EmojiPicker.css");
9
+ /** A small default set of common Unicode emoji. Override via the `emoji` prop. */
10
+ exports.DEFAULT_EMOJI = [
11
+ '😀', '😄', '😉', '😊', '😍', '😘', '😎', '🤔',
12
+ '😅', '😂', '🙃', '😴', '😇', '🥳', '😢', '😡',
13
+ '👍', '👎', '👌', '🙏', '👏', '💪', '🤝', '✌️',
14
+ '👋', '🫡', '🔥', '✅', '❌', '⚠️', '❗', '❓',
15
+ '💯', '🎉', '⭐', '❤️', '💥', '👀', '💡', '⏰',
16
+ ];
17
+ /**
18
+ * EmojiPicker — a minimal panel of Unicode emoji that inserts into a composer.
19
+ *
20
+ * Optional and dependency-free: apps may ignore it and wire only
21
+ * `ChatComposer.onEmoji`. Emoji are plain text, so once inserted they render in
22
+ * sent bubbles for free. Closes on Escape or an outside click.
23
+ */
24
+ const EmojiPicker = ({ open, onClose, onSelect, title = 'Emoji', emoji = exports.DEFAULT_EMOJI, className = '', }) => {
25
+ const panelRef = (0, react_1.useRef)(null);
26
+ (0, react_1.useEffect)(() => {
27
+ if (!open)
28
+ return;
29
+ const onKey = (e) => {
30
+ if (e.key === 'Escape')
31
+ onClose();
32
+ };
33
+ const onPointer = (e) => {
34
+ if (panelRef.current && !panelRef.current.contains(e.target)) {
35
+ onClose();
36
+ }
37
+ };
38
+ document.addEventListener('keydown', onKey);
39
+ // Defer so the opening click doesn't immediately close the panel.
40
+ const id = window.setTimeout(() => document.addEventListener('pointerdown', onPointer), 0);
41
+ return () => {
42
+ document.removeEventListener('keydown', onKey);
43
+ window.clearTimeout(id);
44
+ document.removeEventListener('pointerdown', onPointer);
45
+ };
46
+ }, [open, onClose]);
47
+ if (!open)
48
+ return null;
49
+ const classes = ['muka-emoji-picker', className].filter(Boolean).join(' ');
50
+ return ((0, jsx_runtime_1.jsx)("div", { ref: panelRef, className: classes, role: "dialog", "aria-label": title, children: emoji.map((char) => ((0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "ghost", size: "sm", iconOnly: true, "aria-label": char, onClick: () => onSelect(char), children: (0, jsx_runtime_1.jsx)("span", { className: "muka-emoji-picker__glyph", children: char }) }, char))) }));
51
+ };
52
+ exports.EmojiPicker = EmojiPicker;
53
+ exports.default = exports.EmojiPicker;
54
+ //# sourceMappingURL=EmojiPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmojiPicker.js","sourceRoot":"","sources":["../../../../components/EmojiPicker/EmojiPicker.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = exports.DEFAULT_EMOJI = exports.EmojiPicker = void 0;
7
+ var EmojiPicker_1 = require("./EmojiPicker");
8
+ Object.defineProperty(exports, "EmojiPicker", { enumerable: true, get: function () { return EmojiPicker_1.EmojiPicker; } });
9
+ Object.defineProperty(exports, "DEFAULT_EMOJI", { enumerable: true, get: function () { return EmojiPicker_1.DEFAULT_EMOJI; } });
10
+ var EmojiPicker_2 = require("./EmojiPicker");
11
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(EmojiPicker_2).default; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/EmojiPicker/index.ts"],"names":[],"mappings":";;;;;;AAAA,6CAIuB;AAHrB,0GAAA,WAAW,OAAA;AAEX,4GAAA,aAAa,OAAA;AAEf,6CAAwC;AAA/B,uHAAA,OAAO,OAAA"}
@@ -0,0 +1,27 @@
1
+ /* PhotoDraftStrip Component Styles */
2
+
3
+ .muka-photo-draft-strip {
4
+ display: flex;
5
+ align-items: center;
6
+ gap: var(--spacing-3);
7
+ width: 100%;
8
+ padding: var(--spacing-2) 0;
9
+ }
10
+
11
+ .muka-photo-draft-strip__track {
12
+ display: flex;
13
+ gap: var(--spacing-2);
14
+ flex: 1 1 auto;
15
+ min-width: 0;
16
+ overflow-x: auto;
17
+ scroll-behavior: smooth;
18
+ scrollbar-width: none;
19
+ }
20
+
21
+ .muka-photo-draft-strip__track::-webkit-scrollbar {
22
+ display: none;
23
+ }
24
+
25
+ .muka-photo-draft-strip__item {
26
+ flex: 0 0 auto;
27
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PhotoDraftStrip = void 0;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const Button_1 = require("../Button");
7
+ const Icon_1 = require("../Icon");
8
+ const Spinner_1 = require("../Spinner");
9
+ const Thumbnail_1 = require("../Thumbnail");
10
+ require("./PhotoDraftStrip.css");
11
+ /**
12
+ * PhotoDraftStrip — a controlled, horizontally-scrolling strip of staged photos
13
+ * shown above the composer while they upload. Each tile is a Muka `Thumbnail`
14
+ * carrying its own upload progress / error and a remove (×) control, so a
15
+ * per-item failure never blocks sending the rest.
16
+ *
17
+ * Controlled and network-free: the app owns upload, object URLs and the cap on
18
+ * how many photos may be staged. The optional send button lives here because
19
+ * the composer only enables its own send once text is non-empty — it can't send
20
+ * a caption-less gallery. Sending is enabled once every tile has settled and at
21
+ * least one uploaded successfully.
22
+ */
23
+ const PhotoDraftStrip = ({ photos, onRemove, onSend, sending = false, showSend = true, sendLabel = 'Send photos', removeLabel = 'Remove photo', viewLabel = 'View photo', errorCaption = 'Upload failed', className = '', }) => {
24
+ if (photos.length === 0)
25
+ return null;
26
+ // Allow sending once every tile settled (uploaded or failed) and at least one
27
+ // uploaded successfully — a failed tile shouldn't block the rest.
28
+ const anyUploading = photos.some((p) => p.status === 'uploading');
29
+ const anyReady = photos.some((p) => p.status === 'ready');
30
+ const canSend = !sending && !anyUploading && anyReady;
31
+ const classes = ['muka-photo-draft-strip', className].filter(Boolean).join(' ');
32
+ return ((0, jsx_runtime_1.jsxs)("div", { className: classes, children: [(0, jsx_runtime_1.jsx)("div", { className: "muka-photo-draft-strip__track", children: photos.map((photo) => ((0, jsx_runtime_1.jsx)("div", { className: "muka-photo-draft-strip__item", children: (0, jsx_runtime_1.jsx)(Thumbnail_1.Thumbnail, { src: photo.previewUrl, alt: photo.fileName, shape: "1:1", processing: photo.status === 'uploading' && photo.progress <= 0, loading: photo.status === 'uploading' && photo.progress > 0, progress: photo.progress, error: photo.status === 'error', caption: photo.status === 'error' ? errorCaption : undefined, onRemove: () => onRemove(photo.id), removeLabel: removeLabel, viewLabel: viewLabel }) }, photo.id))) }), showSend && ((0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "primary", size: "lg", iconOnly: true, "aria-label": sendLabel, onClick: onSend, disabled: !canSend, children: sending ? ((0, jsx_runtime_1.jsx)(Spinner_1.Spinner, { size: "sm", variant: "inverse" })) : ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "send-plane2", size: "md" })) }))] }));
33
+ };
34
+ exports.PhotoDraftStrip = PhotoDraftStrip;
35
+ exports.default = exports.PhotoDraftStrip;
36
+ //# sourceMappingURL=PhotoDraftStrip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PhotoDraftStrip.js","sourceRoot":"","sources":["../../../../components/PhotoDraftStrip/PhotoDraftStrip.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AAGb,sCAAmC;AACnC,kCAA+B;AAC/B,wCAAqC;AACrC,4CAAyC;AACzC,iCAA+B;AA+C/B;;;;;;;;;;;GAWG;AACI,MAAM,eAAe,GAAmC,CAAC,EAC9D,MAAM,EACN,QAAQ,EACR,MAAM,EACN,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,aAAa,EACzB,WAAW,GAAG,cAAc,EAC5B,SAAS,GAAG,YAAY,EACxB,YAAY,GAAG,eAAe,EAC9B,SAAS,GAAG,EAAE,GACf,EAAE,EAAE;IACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,8EAA8E;IAC9E,kEAAkE;IAClE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;IAEtD,MAAM,OAAO,GAAG,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhF,OAAO,CACL,iCAAK,SAAS,EAAE,OAAO,aACrB,gCAAK,SAAS,EAAC,+BAA+B,YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACrB,gCAAoB,SAAS,EAAC,8BAA8B,YAC1D,uBAAC,qBAAS,IACR,GAAG,EAAE,KAAK,CAAC,UAAU,EACrB,GAAG,EAAE,KAAK,CAAC,QAAQ,EACnB,KAAK,EAAC,KAAK,EACX,UAAU,EAAE,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,EAC/D,OAAO,EAAE,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAC3D,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,KAAK,CAAC,MAAM,KAAK,OAAO,EAC/B,OAAO,EAAE,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAC5D,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAClC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,GACpB,IAbM,KAAK,CAAC,EAAE,CAcZ,CACP,CAAC,GACE,EAEL,QAAQ,IAAI,CACX,uBAAC,eAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,QAAQ,sBACI,SAAS,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,OAAO,YAEjB,OAAO,CAAC,CAAC,CAAC,CACT,uBAAC,iBAAO,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,GAAG,CACxC,CAAC,CAAC,CAAC,CACF,uBAAC,WAAI,IAAC,IAAI,EAAC,aAAa,EAAC,IAAI,EAAC,IAAI,GAAG,CACtC,GACM,CACV,IACG,CACP,CAAC;AACJ,CAAC,CAAC;AA9DW,QAAA,eAAe,mBA8D1B;AAEF,kBAAe,uBAAe,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = exports.PhotoDraftStrip = void 0;
7
+ var PhotoDraftStrip_1 = require("./PhotoDraftStrip");
8
+ Object.defineProperty(exports, "PhotoDraftStrip", { enumerable: true, get: function () { return PhotoDraftStrip_1.PhotoDraftStrip; } });
9
+ var PhotoDraftStrip_2 = require("./PhotoDraftStrip");
10
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(PhotoDraftStrip_2).default; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/PhotoDraftStrip/index.ts"],"names":[],"mappings":";;;;;;AAAA,qDAI2B;AAHzB,kHAAA,eAAe,OAAA;AAIjB,qDAA4C;AAAnC,2HAAA,OAAO,OAAA"}
@@ -0,0 +1,47 @@
1
+ /* RecordingBar Component Styles */
2
+
3
+ .muka-recording-bar {
4
+ display: flex;
5
+ align-items: center;
6
+ gap: var(--spacing-3);
7
+ width: 100%;
8
+ min-width: 0;
9
+ }
10
+
11
+ .muka-recording-bar__dot {
12
+ flex: 0 0 auto;
13
+ width: 0.625rem;
14
+ height: 0.625rem;
15
+ border-radius: var(--radius-full, 9999px);
16
+ background: var(--alert-color-error-accent, var(--color-text-default-default));
17
+ animation: muka-recording-bar-pulse 1s ease-in-out infinite;
18
+ }
19
+
20
+ .muka-recording-bar__time {
21
+ flex: 0 0 auto;
22
+ font-size: var(--text-label-sm-fontSize, 0.75rem);
23
+ line-height: var(--text-label-sm-lineHeight, 1);
24
+ font-variant-numeric: tabular-nums;
25
+ color: var(--color-text-default-default);
26
+ }
27
+
28
+ .muka-recording-bar__wave {
29
+ flex: 1 1 auto;
30
+ min-width: 0;
31
+ }
32
+
33
+ @keyframes muka-recording-bar-pulse {
34
+ 0%,
35
+ 100% {
36
+ opacity: 1;
37
+ }
38
+ 50% {
39
+ opacity: 0.3;
40
+ }
41
+ }
42
+
43
+ @media (prefers-reduced-motion: reduce) {
44
+ .muka-recording-bar__dot {
45
+ animation: none;
46
+ }
47
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.RecordingBar = void 0;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const Waveform_1 = require("../Waveform");
7
+ const VoiceRecorder_1 = require("../VoiceRecorder");
8
+ require("./RecordingBar.css");
9
+ /**
10
+ * RecordingBar — drop-in content for `ChatComposer.recordingSlot` while a voice
11
+ * note is being recorded. A pulsing record dot, an elapsed timer, and the live
12
+ * `Waveform`. Muka delegates this slot to the app, but ships this default so
13
+ * consumers don't rebuild it. Feed it straight from `useVoiceRecorder`
14
+ * (`elapsedMs`, `livePeaks`). Tokens only; the label comes via props.
15
+ */
16
+ const RecordingBar = ({ elapsedMs, livePeaks, recordingLabel = 'Recording', className = '', }) => {
17
+ const classes = ['muka-recording-bar', className].filter(Boolean).join(' ');
18
+ return ((0, jsx_runtime_1.jsxs)("div", { className: classes, role: "status", "aria-label": recordingLabel, children: [(0, jsx_runtime_1.jsx)("span", { className: "muka-recording-bar__dot", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("span", { className: "muka-recording-bar__time", children: (0, VoiceRecorder_1.formatClock)(elapsedMs / 1000) }), (0, jsx_runtime_1.jsx)("div", { className: "muka-recording-bar__wave", children: (0, jsx_runtime_1.jsx)(Waveform_1.Waveform, { peaks: livePeaks, progress: 1 }) })] }));
19
+ };
20
+ exports.RecordingBar = RecordingBar;
21
+ exports.default = exports.RecordingBar;
22
+ //# sourceMappingURL=RecordingBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordingBar.js","sourceRoot":"","sources":["../../../../components/RecordingBar/RecordingBar.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AAGb,0CAAuC;AACvC,oDAA+C;AAC/C,8BAA4B;AAgB5B;;;;;;GAMG;AACI,MAAM,YAAY,GAAgC,CAAC,EACxD,SAAS,EACT,SAAS,EACT,cAAc,GAAG,WAAW,EAC5B,SAAS,GAAG,EAAE,GACf,EAAE,EAAE;IACH,MAAM,OAAO,GAAG,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE5E,OAAO,CACL,iCAAK,SAAS,EAAE,OAAO,EAAE,IAAI,EAAC,QAAQ,gBAAa,cAAc,aAC/D,iCAAM,SAAS,EAAC,yBAAyB,iBAAa,MAAM,GAAG,EAC/D,iCAAM,SAAS,EAAC,0BAA0B,YAAE,IAAA,2BAAW,EAAC,SAAS,GAAG,IAAI,CAAC,GAAQ,EACjF,gCAAK,SAAS,EAAC,0BAA0B,YACvC,uBAAC,mBAAQ,IAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,GAAI,GACvC,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAjBW,QAAA,YAAY,gBAiBvB;AAEF,kBAAe,oBAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = exports.RecordingBar = void 0;
7
+ var RecordingBar_1 = require("./RecordingBar");
8
+ Object.defineProperty(exports, "RecordingBar", { enumerable: true, get: function () { return RecordingBar_1.RecordingBar; } });
9
+ var RecordingBar_2 = require("./RecordingBar");
10
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(RecordingBar_2).default; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/RecordingBar/index.ts"],"names":[],"mappings":";;;;;;AAAA,+CAAsE;AAA7D,4GAAA,YAAY,OAAA;AACrB,+CAAyC;AAAhC,wHAAA,OAAO,OAAA"}
@@ -0,0 +1,29 @@
1
+ /* VoiceMessage Component Styles */
2
+
3
+ .muka-voice-message {
4
+ display: flex;
5
+ align-items: center;
6
+ gap: var(--spacing-3);
7
+ width: 100%;
8
+ min-width: min(16rem, 60vw);
9
+ }
10
+
11
+ .muka-voice-message__wave {
12
+ flex: 1 1 auto;
13
+ min-width: 0;
14
+ }
15
+
16
+ .muka-voice-message__time {
17
+ flex: 0 0 auto;
18
+ white-space: nowrap;
19
+ font-size: var(--text-label-sm-fontSize, 0.75rem);
20
+ line-height: var(--text-label-sm-lineHeight, 1);
21
+ font-variant-numeric: tabular-nums;
22
+ color: var(--color-text-subtle-default);
23
+ }
24
+
25
+ /* On the tinted own bubble the surface is the action color, so the timer flips
26
+ * to the inverse text token for contrast. */
27
+ .muka-voice-message--own .muka-voice-message__time {
28
+ color: var(--color-text-default-inverse);
29
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.VoiceMessage = void 0;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const Button_1 = require("../Button");
8
+ const Icon_1 = require("../Icon");
9
+ const Waveform_1 = require("../Waveform");
10
+ const VoiceRecorder_1 = require("../VoiceRecorder");
11
+ require("./VoiceMessage.css");
12
+ /**
13
+ * VoiceMessage — inline play/pause player for a sent voice note.
14
+ *
15
+ * Composes a Muka `Button` with the shared token-based `Waveform`; the media
16
+ * stays with the app (`src` is whatever URL it hands over — Muka never fetches
17
+ * or signs it). Play/pause only: there is no transcription/speech-to-text.
18
+ */
19
+ const VoiceMessage = ({ src, durationSec, peaks, variant, playLabel = 'Play voice message', pauseLabel = 'Pause voice message', unavailableLabel = 'Voice message unavailable', className = '', }) => {
20
+ const audioRef = (0, react_1.useRef)(null);
21
+ const [playing, setPlaying] = (0, react_1.useState)(false);
22
+ const [currentSec, setCurrentSec] = (0, react_1.useState)(0);
23
+ const [totalSec, setTotalSec] = (0, react_1.useState)(durationSec);
24
+ (0, react_1.useEffect)(() => {
25
+ const audio = audioRef.current;
26
+ if (!audio)
27
+ return;
28
+ const onTime = () => setCurrentSec(audio.currentTime);
29
+ const onLoaded = () => {
30
+ if (Number.isFinite(audio.duration) && audio.duration > 0) {
31
+ setTotalSec(audio.duration);
32
+ }
33
+ };
34
+ const onEnded = () => {
35
+ setPlaying(false);
36
+ setCurrentSec(0);
37
+ };
38
+ audio.addEventListener('timeupdate', onTime);
39
+ audio.addEventListener('loadedmetadata', onLoaded);
40
+ audio.addEventListener('ended', onEnded);
41
+ return () => {
42
+ audio.removeEventListener('timeupdate', onTime);
43
+ audio.removeEventListener('loadedmetadata', onLoaded);
44
+ audio.removeEventListener('ended', onEnded);
45
+ };
46
+ }, [src]);
47
+ const toggle = () => {
48
+ const audio = audioRef.current;
49
+ if (!audio)
50
+ return;
51
+ if (playing) {
52
+ audio.pause();
53
+ setPlaying(false);
54
+ }
55
+ else {
56
+ void audio
57
+ .play()
58
+ .then(() => setPlaying(true))
59
+ .catch(() => setPlaying(false));
60
+ }
61
+ };
62
+ const effectiveTotal = totalSec || durationSec;
63
+ const progress = effectiveTotal > 0 ? Math.min(1, currentSec / effectiveTotal) : 0;
64
+ const remaining = playing || currentSec > 0 ? effectiveTotal - currentSec : effectiveTotal;
65
+ // On own (tinted) bubbles the surface is the action color, so the played bars
66
+ // use the inverse text token for contrast; elsewhere the action color reads
67
+ // well against the light card.
68
+ const activeColor = variant === 'own'
69
+ ? 'var(--color-text-default-inverse)'
70
+ : 'var(--color-action-default)';
71
+ const inactiveColor = variant === 'own'
72
+ ? 'var(--color-black-alpha-3, rgba(0, 0, 0, 0.25))'
73
+ : 'var(--color-border-contrast)';
74
+ const classes = [
75
+ 'muka-voice-message',
76
+ `muka-voice-message--${variant}`,
77
+ className,
78
+ ]
79
+ .filter(Boolean)
80
+ .join(' ');
81
+ return ((0, jsx_runtime_1.jsxs)("div", { className: classes, children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { variant: variant === 'own' ? 'secondary' : 'primary', size: "md", iconOnly: true, "aria-label": playing ? pauseLabel : playLabel, onClick: toggle, disabled: !src, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: playing ? 'pause' : 'play', variant: "fill", size: "sm" }) }), (0, jsx_runtime_1.jsx)("div", { className: "muka-voice-message__wave", children: (0, jsx_runtime_1.jsx)(Waveform_1.Waveform, { peaks: peaks, progress: progress, activeColor: activeColor, inactiveColor: inactiveColor, "aria-label": src ? undefined : unavailableLabel }) }), (0, jsx_runtime_1.jsx)("span", { className: "muka-voice-message__time", children: (0, VoiceRecorder_1.formatClock)(remaining) }), src && (0, jsx_runtime_1.jsx)("audio", { ref: audioRef, src: src, preload: "metadata" })] }));
82
+ };
83
+ exports.VoiceMessage = VoiceMessage;
84
+ exports.default = exports.VoiceMessage;
85
+ //# sourceMappingURL=VoiceMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VoiceMessage.js","sourceRoot":"","sources":["../../../../components/VoiceMessage/VoiceMessage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = exports.VoiceMessage = void 0;
7
+ var VoiceMessage_1 = require("./VoiceMessage");
8
+ Object.defineProperty(exports, "VoiceMessage", { enumerable: true, get: function () { return VoiceMessage_1.VoiceMessage; } });
9
+ var VoiceMessage_2 = require("./VoiceMessage");
10
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(VoiceMessage_2).default; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/VoiceMessage/index.ts"],"names":[],"mappings":";;;;;;AAAA,+CAIwB;AAHtB,4GAAA,YAAY,OAAA;AAId,+CAAyC;AAAhC,wHAAA,OAAO,OAAA"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.VOICE_PEAK_COUNT = void 0;
5
+ exports.downsamplePeaks = downsamplePeaks;
6
+ exports.formatClock = formatClock;
7
+ exports.isVoiceRecordingSupported = isVoiceRecordingSupported;
8
+ /**
9
+ * Audio helpers shared by the voice-recording hook and the players.
10
+ *
11
+ * Pure, DOM-light utilities: peak downsampling for a compact persisted waveform
12
+ * and a clock formatter for the recorder timer / player countdown. No upload,
13
+ * no network, no speech-to-text.
14
+ */
15
+ /** Default number of persisted waveform bars. Apps may override per clip. */
16
+ exports.VOICE_PEAK_COUNT = 48;
17
+ /**
18
+ * Downsample a stream of amplitude samples (each already 0..1) into exactly
19
+ * `count` normalized peaks by taking the max of each bucket, then scaling so the
20
+ * loudest bar reaches 1. Pure — unit-testable independently of the DOM.
21
+ */
22
+ function downsamplePeaks(samples, count = exports.VOICE_PEAK_COUNT) {
23
+ if (samples.length === 0 || count <= 0)
24
+ return [];
25
+ const buckets = new Array(count).fill(0);
26
+ const size = samples.length / count;
27
+ for (let i = 0; i < count; i += 1) {
28
+ const start = Math.floor(i * size);
29
+ const end = Math.min(samples.length, Math.max(start + 1, Math.floor((i + 1) * size)));
30
+ let peak = 0;
31
+ for (let j = start; j < end; j += 1) {
32
+ const v = Math.abs(samples[j]);
33
+ if (v > peak)
34
+ peak = v;
35
+ }
36
+ buckets[i] = peak;
37
+ }
38
+ const max = buckets.reduce((m, v) => (v > m ? v : m), 0);
39
+ if (max <= 0)
40
+ return buckets;
41
+ return buckets.map((v) => Math.min(1, v / max));
42
+ }
43
+ /** Format a number of seconds as `m:ss` for the recorder timer / player. */
44
+ function formatClock(totalSeconds) {
45
+ const safe = Number.isFinite(totalSeconds) && totalSeconds > 0
46
+ ? Math.floor(totalSeconds)
47
+ : 0;
48
+ const minutes = Math.floor(safe / 60);
49
+ const seconds = safe % 60;
50
+ const paddedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
51
+ return `${minutes}:${paddedSeconds}`;
52
+ }
53
+ /** True when this browser can record audio at all (SSR-safe). */
54
+ function isVoiceRecordingSupported() {
55
+ return (typeof window !== 'undefined' &&
56
+ typeof navigator !== 'undefined' &&
57
+ !!navigator.mediaDevices &&
58
+ typeof navigator.mediaDevices.getUserMedia === 'function' &&
59
+ typeof MediaRecorder !== 'undefined');
60
+ }
61
+ //# sourceMappingURL=audio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio.js","sourceRoot":"","sources":["../../../../components/VoiceRecorder/audio.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;AAkBb,0CAuBC;AAGD,kCASC;AAGD,8DAQC;AA9DD;;;;;;GAMG;AAEH,6EAA6E;AAChE,QAAA,gBAAgB,GAAG,EAAE,CAAC;AAEnC;;;;GAIG;AACH,SAAgB,eAAe,CAC7B,OAAiB,EACjB,QAAgB,wBAAgB;IAEhC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAClD,MAAM,OAAO,GAAa,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAClB,OAAO,CAAC,MAAM,EACd,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAChD,CAAC;QACF,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,GAAG,IAAI;gBAAE,IAAI,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,4EAA4E;AAC5E,SAAgB,WAAW,CAAC,YAAoB;IAC9C,MAAM,IAAI,GACR,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC;QAC/C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IAC1B,MAAM,aAAa,GAAG,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC;IAClE,OAAO,GAAG,OAAO,IAAI,aAAa,EAAE,CAAC;AACvC,CAAC;AAED,iEAAiE;AACjE,SAAgB,yBAAyB;IACvC,OAAO,CACL,OAAO,MAAM,KAAK,WAAW;QAC7B,OAAO,SAAS,KAAK,WAAW;QAChC,CAAC,CAAC,SAAS,CAAC,YAAY;QACxB,OAAO,SAAS,CAAC,YAAY,CAAC,YAAY,KAAK,UAAU;QACzD,OAAO,aAAa,KAAK,WAAW,CACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = exports.VOICE_PEAK_COUNT = exports.isVoiceRecordingSupported = exports.formatClock = exports.downsamplePeaks = exports.useVoiceRecorder = void 0;
7
+ var useVoiceRecorder_1 = require("./useVoiceRecorder");
8
+ Object.defineProperty(exports, "useVoiceRecorder", { enumerable: true, get: function () { return useVoiceRecorder_1.useVoiceRecorder; } });
9
+ var audio_1 = require("./audio");
10
+ Object.defineProperty(exports, "downsamplePeaks", { enumerable: true, get: function () { return audio_1.downsamplePeaks; } });
11
+ Object.defineProperty(exports, "formatClock", { enumerable: true, get: function () { return audio_1.formatClock; } });
12
+ Object.defineProperty(exports, "isVoiceRecordingSupported", { enumerable: true, get: function () { return audio_1.isVoiceRecordingSupported; } });
13
+ Object.defineProperty(exports, "VOICE_PEAK_COUNT", { enumerable: true, get: function () { return audio_1.VOICE_PEAK_COUNT; } });
14
+ var useVoiceRecorder_2 = require("./useVoiceRecorder");
15
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(useVoiceRecorder_2).default; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/VoiceRecorder/index.ts"],"names":[],"mappings":";;;;;;AAAA,uDAK4B;AAJ1B,oHAAA,gBAAgB,OAAA;AAKlB,iCAKiB;AAJf,wGAAA,eAAe,OAAA;AACf,oGAAA,WAAW,OAAA;AACX,kHAAA,yBAAyB,OAAA;AACzB,yGAAA,gBAAgB,OAAA;AAElB,uDAA6C;AAApC,4HAAA,OAAO,OAAA"}