@mieweb/ui 0.9.0-dev.3 → 0.9.0-dev.5

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 (44) hide show
  1. package/dist/{chunk-5VXRKOPR.cjs → chunk-H3GRO43Z.cjs} +2 -2
  2. package/dist/{chunk-5VXRKOPR.cjs.map → chunk-H3GRO43Z.cjs.map} +1 -1
  3. package/dist/{chunk-IF3X2WZP.js → chunk-MD3ZY4UO.js} +2 -2
  4. package/dist/{chunk-IF3X2WZP.js.map → chunk-MD3ZY4UO.js.map} +1 -1
  5. package/dist/{chunk-RPG2ZP2T.js → chunk-PL6TFCYR.js} +900 -899
  6. package/dist/chunk-PL6TFCYR.js.map +1 -0
  7. package/dist/{chunk-NPHZUCF3.cjs → chunk-PY7XAG4D.cjs} +4 -4
  8. package/dist/chunk-PY7XAG4D.cjs.map +1 -0
  9. package/dist/{chunk-VMQZAOFM.js → chunk-QWJGEDHV.js} +51 -5
  10. package/dist/chunk-QWJGEDHV.js.map +1 -0
  11. package/dist/{chunk-UHHYJ42E.js → chunk-X5YM3KXY.js} +4 -4
  12. package/dist/chunk-X5YM3KXY.js.map +1 -0
  13. package/dist/{chunk-B67VPJCZ.cjs → chunk-XJUIZA4G.cjs} +58 -12
  14. package/dist/chunk-XJUIZA4G.cjs.map +1 -0
  15. package/dist/{chunk-O425FKDI.cjs → chunk-ZXRVVNT5.cjs} +903 -902
  16. package/dist/chunk-ZXRVVNT5.cjs.map +1 -0
  17. package/dist/components/SuperChat/index.cjs +8 -8
  18. package/dist/components/SuperChat/index.d.cts +4 -4
  19. package/dist/components/SuperChat/index.d.ts +4 -4
  20. package/dist/components/SuperChat/index.js +2 -2
  21. package/dist/components/SuperChat/plugins/index.cjs +3 -3
  22. package/dist/components/SuperChat/plugins/index.d.cts +3 -3
  23. package/dist/components/SuperChat/plugins/index.d.ts +3 -3
  24. package/dist/components/SuperChat/plugins/index.js +2 -2
  25. package/dist/index.cjs +190 -105
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +471 -426
  28. package/dist/index.d.ts +471 -426
  29. package/dist/index.js +123 -38
  30. package/dist/index.js.map +1 -1
  31. package/dist/styles.css +1 -1
  32. package/dist/tailwind-preset.cjs +4 -4
  33. package/dist/tailwind-preset.js +1 -1
  34. package/dist/{types-DZDroUW8.d.cts → types-B97JNRNQ.d.cts} +1 -1
  35. package/dist/{types-B2RLmdVd.d.cts → types-CnPEwzlp.d.cts} +6 -2
  36. package/dist/{types-B2RLmdVd.d.ts → types-CnPEwzlp.d.ts} +6 -2
  37. package/dist/{types-9vK_YdEb.d.ts → types-gZXrfLj6.d.ts} +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-B67VPJCZ.cjs.map +0 -1
  40. package/dist/chunk-NPHZUCF3.cjs.map +0 -1
  41. package/dist/chunk-O425FKDI.cjs.map +0 -1
  42. package/dist/chunk-RPG2ZP2T.js.map +0 -1
  43. package/dist/chunk-UHHYJ42E.js.map +0 -1
  44. package/dist/chunk-VMQZAOFM.js.map +0 -1
package/dist/index.js CHANGED
@@ -25,11 +25,11 @@ export { SourceTip } from './chunk-PHK4XBO5.js';
25
25
  export { Sparkline } from './chunk-CG4ZKJLE.js';
26
26
  import { Spinner, SpinnerWithLabel } from './chunk-UA7E7PDS.js';
27
27
  export { FullPageSpinner, Spinner, SpinnerWithLabel, spinnerVariants } from './chunk-UA7E7PDS.js';
28
- import { SparklesIcon, RefreshIcon, CloseIcon, AIMessageDisplay, ComposerModelSelector } from './chunk-VMQZAOFM.js';
29
- export { AILogoIcon, AIMessageDisplay, AITypingIndicator, ChatBubble, ChatComposer, ChevronIcon, CloseIcon, CollapsiblePill, ComposerModelSelector, MCPToolCallDisplay, MessageAvatar, RefreshIcon, ResourceLink, SendIcon, SparklesIcon, SpinnerIcon, ToolStatusIcon, getToolIcon } from './chunk-VMQZAOFM.js';
30
- import { MessageComposer, EmptyState } from './chunk-RPG2ZP2T.js';
31
- export { AttachmentPreview, CharacterCounter, ConversationHeader, ConversationListItem, ConversationListSkeleton, DateSeparator, EmptyState, LightboxModal, LoadMoreButton, MessageBubble, MessageComposer, MessageList, MessageStatusIcon, MessageThread, MessagingSplitView, ReadReceiptIndicator, SendButton, SkeletonMessage, TypingIndicator, bubbleVariants, formatDateLabel, formatFileSize, formatLastSeen, getConversationSubtitle, getConversationTitle, groupMessagesByDate, headerVariants, isSameSenderGroup, sendButtonVariants, useMessageScroll, useMessages, useReadReceipts, useTypingIndicator } from './chunk-RPG2ZP2T.js';
32
- export { AttachmentPicker, AttachmentPreviewItem, CameraButton, DragDropZone, generateAttachmentId, getFileType, validateFile } from './chunk-IF3X2WZP.js';
28
+ import { SparklesIcon, RefreshIcon, CloseIcon, AIMessageDisplay, ChatComposer } from './chunk-QWJGEDHV.js';
29
+ export { AILogoIcon, AIMessageDisplay, AITypingIndicator, ChatBubble, ChatComposer, ChevronIcon, CloseIcon, CollapsiblePill, ComposerModelSelector, MCPToolCallDisplay, MessageAvatar, RefreshIcon, ResourceLink, SendIcon, SparklesIcon, SpinnerIcon, ToolStatusIcon, getToolIcon } from './chunk-QWJGEDHV.js';
30
+ import { EmptyState } from './chunk-PL6TFCYR.js';
31
+ export { AttachmentPreview, CharacterCounter, ConversationHeader, ConversationListItem, ConversationListSkeleton, DateSeparator, EmptyState, LightboxModal, LoadMoreButton, MessageBubble, MessageComposer, MessageList, MessageStatusIcon, MessageThread, MessagingSplitView, ReadReceiptIndicator, SendButton, SkeletonMessage, TypingIndicator, bubbleVariants, formatDateLabel, formatFileSize, formatLastSeen, getConversationSubtitle, getConversationTitle, groupMessagesByDate, headerVariants, isSameSenderGroup, sendButtonVariants, useMessageScroll, useMessages, useReadReceipts, useTypingIndicator } from './chunk-PL6TFCYR.js';
32
+ export { AttachmentPicker, AttachmentPreviewItem, CameraButton, DragDropZone, generateAttachmentId, getFileType, validateFile } from './chunk-MD3ZY4UO.js';
33
33
  import { RecordButton } from './chunk-VNWJTCBQ.js';
34
34
  export { RecordButton, formatDuration, recordButtonVariants } from './chunk-VNWJTCBQ.js';
35
35
  export { RichTextEditor, convertAngleBracketsToMustache, processDictation } from './chunk-QKFJDQEK.js';
@@ -80,7 +80,7 @@ export { CollabStatus, defaultCollabStatusLabels, useYjsCollabStatus } from './c
80
80
  import './chunk-7XUN3OQT.js';
81
81
  export { isHtmlEmpty, stripHtmlTags } from './chunk-ERLPVXOV.js';
82
82
  export { formatPhoneNumber, isPhoneNumberEmpty, isValidPhoneNumber, unformatPhoneNumber } from './chunk-ZVPJ2MH6.js';
83
- export { miewebUIPreset, miewebUISafelist } from './chunk-UHHYJ42E.js';
83
+ export { miewebUIPreset, miewebUISafelist } from './chunk-X5YM3KXY.js';
84
84
  export { Accordion } from './chunk-KRU6IGV7.js';
85
85
  import { Alert, AlertTitle, AlertDescription } from './chunk-3JWAABYI.js';
86
86
  export { Alert, AlertDescription, AlertTitle, alertVariants } from './chunk-3JWAABYI.js';
@@ -1463,6 +1463,15 @@ var chatVariants = cva("flex flex-col", {
1463
1463
  size: "full"
1464
1464
  }
1465
1465
  });
1466
+ var LEGACY_ACCEPTED_FILE_TYPES = [
1467
+ "image/*",
1468
+ "video/*",
1469
+ ".pdf",
1470
+ ".doc",
1471
+ ".docx"
1472
+ ];
1473
+ var LEGACY_MAX_FILE_SIZE = 25 * 1024 * 1024;
1474
+ var normalizeLegacySlot = (node) => node || void 0;
1466
1475
  function AIChat({
1467
1476
  session,
1468
1477
  messages: messagesProp,
@@ -1501,11 +1510,88 @@ function AIChat({
1501
1510
  const container = messagesContainerRef.current;
1502
1511
  if (container) container.scrollTop = container.scrollHeight;
1503
1512
  }, [messages]);
1504
- const handleSend = async (message) => {
1505
- if (message.content.trim() && onSendMessage) {
1506
- onSendMessage(message.content.trim());
1513
+ const {
1514
+ showAttachmentPicker,
1515
+ inputTrailing,
1516
+ onTypingStart,
1517
+ onTypingStop,
1518
+ value: hostValue,
1519
+ onValueChange: hostOnValueChange,
1520
+ onSend: hostOnSend,
1521
+ micSlot: hostMicSlot,
1522
+ ...composerRest
1523
+ } = composerProps ?? {};
1524
+ delete composerRest.showCameraButton;
1525
+ delete composerRest.variant;
1526
+ const hasInputTrailing = !!composerProps && "inputTrailing" in composerProps;
1527
+ const legacyAttachments = !!composerProps && "showAttachmentPicker" in composerProps ? showAttachmentPicker ?? true : false;
1528
+ const [draft, setDraft] = React13.useState("");
1529
+ const draftEpochRef = React13.useRef(0);
1530
+ const composerValue = hostValue ?? draft;
1531
+ const isHostControlled = hostValue !== void 0;
1532
+ const handleComposerValueChange = React13.useCallback(
1533
+ (value) => {
1534
+ draftEpochRef.current += 1;
1535
+ setDraft(value);
1536
+ if (isHostControlled) hostOnValueChange?.(value);
1537
+ },
1538
+ [isHostControlled, hostOnValueChange]
1539
+ );
1540
+ const [isTyping, setIsTyping] = React13.useState(false);
1541
+ const typingTimeoutRef = React13.useRef(
1542
+ null
1543
+ );
1544
+ React13.useEffect(() => {
1545
+ if (!onTypingStart && !onTypingStop) return;
1546
+ if (composerValue.length > 0 && !isTyping) {
1547
+ setIsTyping(true);
1548
+ onTypingStart?.();
1549
+ }
1550
+ if (typingTimeoutRef.current) {
1551
+ clearTimeout(typingTimeoutRef.current);
1552
+ }
1553
+ typingTimeoutRef.current = setTimeout(() => {
1554
+ if (isTyping) {
1555
+ setIsTyping(false);
1556
+ onTypingStop?.();
1557
+ }
1558
+ }, 2e3);
1559
+ return () => {
1560
+ if (typingTimeoutRef.current) {
1561
+ clearTimeout(typingTimeoutRef.current);
1562
+ }
1563
+ };
1564
+ }, [composerValue, isTyping, onTypingStart, onTypingStop]);
1565
+ const stopTypingOnSend = () => {
1566
+ setIsTyping(false);
1567
+ onTypingStop?.();
1568
+ };
1569
+ const sendWithRestore = async (message, send) => {
1570
+ stopTypingOnSend();
1571
+ const epoch = draftEpochRef.current;
1572
+ try {
1573
+ await Promise.resolve(send(message));
1574
+ } catch (error) {
1575
+ if (draftEpochRef.current === epoch) {
1576
+ setDraft(message.content);
1577
+ if (isHostControlled) hostOnValueChange?.(message.content);
1578
+ }
1579
+ throw error;
1507
1580
  }
1508
1581
  };
1582
+ const handleSend = async (message) => {
1583
+ if (!onSendMessage) return;
1584
+ const content = message.content.trim();
1585
+ const attachments = message.attachments?.length ? message.attachments : void 0;
1586
+ if (!content && !attachments) return;
1587
+ await sendWithRestore(
1588
+ message,
1589
+ () => (
1590
+ // Keep the exact legacy call shape for text-only sends.
1591
+ attachments ? onSendMessage(content, attachments) : onSendMessage(content)
1592
+ )
1593
+ );
1594
+ };
1509
1595
  const handleSuggestionSelect = (action) => {
1510
1596
  if (onSuggestedAction) {
1511
1597
  onSuggestedAction(action);
@@ -1624,18 +1710,14 @@ function AIChat({
1624
1710
  onSelect: handleSuggestionSelect
1625
1711
  }
1626
1712
  ) }),
1627
- /* @__PURE__ */ jsx(
1628
- MessageComposer,
1713
+ /* @__PURE__ */ jsx("div", { "data-slot": "ai-chat-composer", className: "p-3", children: /* @__PURE__ */ jsx(
1714
+ ChatComposer,
1629
1715
  {
1630
- onSend: handleSend,
1716
+ onSend: hostOnSend ? (message) => sendWithRestore(message, hostOnSend) : handleSend,
1631
1717
  placeholder: inputPlaceholder,
1632
1718
  disabled: isGenerating,
1633
1719
  isSending: isGenerating,
1634
- showAttachmentPicker: false,
1635
- showCameraButton: false,
1636
- showCharacterCount: false,
1637
- variant: "minimal",
1638
- inputTrailing: talkToText ? /* @__PURE__ */ jsx(
1720
+ micSlot: hostMicSlot !== void 0 ? hostMicSlot : hasInputTrailing ? normalizeLegacySlot(inputTrailing) : talkToText ? /* @__PURE__ */ jsx(
1639
1721
  RecordButton,
1640
1722
  {
1641
1723
  variant: "ghost",
@@ -1647,9 +1729,16 @@ function AIChat({
1647
1729
  onRecordingComplete
1648
1730
  }
1649
1731
  ) : void 0,
1650
- ...composerProps
1732
+ ...composerRest,
1733
+ allowAttachments: composerRest.allowAttachments ?? legacyAttachments,
1734
+ maxLength: composerRest.maxLength ?? 1600,
1735
+ inputLabel: composerRest.inputLabel ?? "Message",
1736
+ acceptedFileTypes: composerRest.acceptedFileTypes ?? (legacyAttachments ? LEGACY_ACCEPTED_FILE_TYPES : void 0),
1737
+ maxFileSize: composerRest.maxFileSize ?? (legacyAttachments ? LEGACY_MAX_FILE_SIZE : void 0),
1738
+ value: composerValue,
1739
+ onValueChange: handleComposerValueChange
1651
1740
  }
1652
- )
1741
+ ) })
1653
1742
  ]
1654
1743
  }
1655
1744
  )
@@ -2115,20 +2204,17 @@ function OzwellChat({
2115
2204
  });
2116
2205
  setMessagesMenuOpen(false);
2117
2206
  };
2118
- const modelSelector = showModelSelector && models ? /* @__PURE__ */ jsx(
2119
- ComposerModelSelector,
2120
- {
2121
- models: models.options,
2122
- value: models.value,
2123
- onChange: models.onChange,
2124
- ...models.providerFilter !== void 0 ? {
2125
- providerFilter: models.providerFilter,
2126
- onProviderFilterChange: models.onProviderFilterChange
2127
- } : { onProviderFilterChange: models.onProviderFilterChange },
2128
- boundaryRef: shellRef,
2129
- className: "border-border bg-card text-foreground max-w-[min(142px,38vw)] shadow-sm"
2130
- }
2131
- ) : void 0;
2207
+ const modelSelectorProps = showModelSelector && models ? {
2208
+ models: models.options,
2209
+ value: models.value,
2210
+ onChange: models.onChange,
2211
+ ...models.providerFilter !== void 0 ? {
2212
+ providerFilter: models.providerFilter,
2213
+ onProviderFilterChange: models.onProviderFilterChange
2214
+ } : { onProviderFilterChange: models.onProviderFilterChange },
2215
+ boundaryRef: shellRef,
2216
+ className: "max-w-[min(160px,44vw)]"
2217
+ } : void 0;
2132
2218
  const startQueuedMessageEdit = () => {
2133
2219
  setQueuedMessageDraft(queuedMessage ?? "");
2134
2220
  setIsEditingQueuedMessage(true);
@@ -2342,7 +2428,6 @@ function OzwellChat({
2342
2428
  {
2343
2429
  messages: chatMessages,
2344
2430
  isGenerating,
2345
- className: showModelSelector ? '[&_[data-slot="composer-input"]]:pe-[min(160px,44vw)]' : void 0,
2346
2431
  showHeader: false,
2347
2432
  height: "100%",
2348
2433
  variant: "embedded",
@@ -2352,9 +2437,9 @@ function OzwellChat({
2352
2437
  renderTextContent: renderMessageTextContent,
2353
2438
  renderMessageFooter: renderQueuedMessageFooter,
2354
2439
  composerProps: {
2355
- inputTrailing: modelSelector,
2356
2440
  disabled: false,
2357
- isSending: false
2441
+ isSending: false,
2442
+ ...modelSelectorProps ? { showModelSelector: true, modelSelectorProps } : {}
2358
2443
  }
2359
2444
  }
2360
2445
  ),
@@ -5741,9 +5826,9 @@ function HandsFreeChat({
5741
5826
  // Controlled input (value/onValueChange) comes from the hook — it fills the box with the live
5742
5827
  // caption while dictating, else the typed text. We only add the mic button here.
5743
5828
  ...oz.chatProps.composerProps,
5744
- // The composer's OWN mic button, driven by our shared stream (controlled mode disables its
5829
+ // The composer's OWN mic slot, driven by our shared stream (controlled mode disables its
5745
5830
  // internal recorder). So the built-in mic and "hey ozwell" both do the same thing — one mic.
5746
- inputTrailing: /* @__PURE__ */ jsx(
5831
+ micSlot: /* @__PURE__ */ jsx(
5747
5832
  "span",
5748
5833
  {
5749
5834
  onClickCapture: () => {