@mantine-vue/whatsapp-inbox 3.2.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 +88 -0
- package/cjs/index.cjs +11842 -0
- package/cjs/index.cjs.map +1 -0
- package/esm/index.mjs +11704 -0
- package/esm/index.mjs.map +1 -0
- package/lib/WhatsAppInbox.context.d.ts +70 -0
- package/lib/component-props.d.ts +138 -0
- package/lib/components/WhatsAppAttachmentPreview/WhatsAppAttachmentPreview.d.ts +8 -0
- package/lib/components/WhatsAppAttachmentPreview/WhatsAppAttachmentPreview.types.d.ts +33 -0
- package/lib/components/WhatsAppAttachmentPreview/WhatsAppAttachmentPreview.vue.d.ts +19 -0
- package/lib/components/WhatsAppAttachmentPreview/index.d.ts +1 -0
- package/lib/components/WhatsAppComposer/WhatsAppComposer.d.ts +10 -0
- package/lib/components/WhatsAppComposer/WhatsAppComposer.types.d.ts +173 -0
- package/lib/components/WhatsAppComposer/WhatsAppComposer.vue.d.ts +52 -0
- package/lib/components/WhatsAppComposer/index.d.ts +1 -0
- package/lib/components/WhatsAppContactPanel/WhatsAppContactPanel.d.ts +9 -0
- package/lib/components/WhatsAppContactPanel/WhatsAppContactPanel.types.d.ts +40 -0
- package/lib/components/WhatsAppContactPanel/WhatsAppContactPanel.vue.d.ts +19 -0
- package/lib/components/WhatsAppContactPanel/index.d.ts +1 -0
- package/lib/components/WhatsAppConversation/WhatsAppConversation.d.ts +10 -0
- package/lib/components/WhatsAppConversation/WhatsAppConversation.types.d.ts +163 -0
- package/lib/components/WhatsAppConversation/WhatsAppConversation.vue.d.ts +69 -0
- package/lib/components/WhatsAppConversation/index.d.ts +1 -0
- package/lib/components/WhatsAppConversationHeader/WhatsAppConversationHeader.d.ts +9 -0
- package/lib/components/WhatsAppConversationHeader/WhatsAppConversationHeader.types.d.ts +57 -0
- package/lib/components/WhatsAppConversationHeader/WhatsAppConversationHeader.vue.d.ts +23 -0
- package/lib/components/WhatsAppConversationHeader/index.d.ts +1 -0
- package/lib/components/WhatsAppConversationList/WhatsAppConversationList.d.ts +9 -0
- package/lib/components/WhatsAppConversationList/WhatsAppConversationList.types.d.ts +113 -0
- package/lib/components/WhatsAppConversationList/WhatsAppConversationList.vue.d.ts +35 -0
- package/lib/components/WhatsAppConversationList/index.d.ts +1 -0
- package/lib/components/WhatsAppConversationListItem/WhatsAppConversationListItem.d.ts +9 -0
- package/lib/components/WhatsAppConversationListItem/WhatsAppConversationListItem.types.d.ts +56 -0
- package/lib/components/WhatsAppConversationListItem/WhatsAppConversationListItem.vue.d.ts +21 -0
- package/lib/components/WhatsAppConversationListItem/index.d.ts +1 -0
- package/lib/components/WhatsAppEmojiPicker/WhatsAppEmojiPicker.d.ts +9 -0
- package/lib/components/WhatsAppEmojiPicker/WhatsAppEmojiPicker.types.d.ts +91 -0
- package/lib/components/WhatsAppEmojiPicker/WhatsAppEmojiPicker.vue.d.ts +31 -0
- package/lib/components/WhatsAppEmojiPicker/index.d.ts +1 -0
- package/lib/components/WhatsAppInbox/WhatsAppInbox.d.ts +10 -0
- package/lib/components/WhatsAppInbox/WhatsAppInbox.types.d.ts +135 -0
- package/lib/components/WhatsAppInbox/WhatsAppInbox.vue.d.ts +84 -0
- package/lib/components/WhatsAppInbox/index.d.ts +1 -0
- package/lib/components/WhatsAppInboxDrawer/WhatsAppInboxDrawer.d.ts +9 -0
- package/lib/components/WhatsAppInboxDrawer/WhatsAppInboxDrawer.types.d.ts +52 -0
- package/lib/components/WhatsAppInboxDrawer/WhatsAppInboxDrawer.vue.d.ts +24 -0
- package/lib/components/WhatsAppInboxDrawer/index.d.ts +1 -0
- package/lib/components/WhatsAppInboxModal/WhatsAppInboxModal.d.ts +9 -0
- package/lib/components/WhatsAppInboxModal/WhatsAppInboxModal.types.d.ts +52 -0
- package/lib/components/WhatsAppInboxModal/WhatsAppInboxModal.vue.d.ts +28 -0
- package/lib/components/WhatsAppInboxModal/index.d.ts +1 -0
- package/lib/components/WhatsAppInboxProvider/WhatsAppInboxProvider.d.ts +16 -0
- package/lib/components/WhatsAppInboxProvider/WhatsAppInboxProvider.types.d.ts +16 -0
- package/lib/components/WhatsAppInboxProvider/WhatsAppInboxProvider.vue.d.ts +11 -0
- package/lib/components/WhatsAppInboxProvider/index.d.ts +1 -0
- package/lib/components/WhatsAppInteractiveMessageEditor/WhatsAppInteractiveMessageEditor.d.ts +8 -0
- package/lib/components/WhatsAppInteractiveMessageEditor/WhatsAppInteractiveMessageEditor.types.d.ts +49 -0
- package/lib/components/WhatsAppInteractiveMessageEditor/WhatsAppInteractiveMessageEditor.vue.d.ts +27 -0
- package/lib/components/WhatsAppInteractiveMessageEditor/index.d.ts +1 -0
- package/lib/components/WhatsAppMediaAttachment/WhatsAppMediaAttachment.d.ts +8 -0
- package/lib/components/WhatsAppMediaAttachment/WhatsAppMediaAttachment.types.d.ts +41 -0
- package/lib/components/WhatsAppMediaAttachment/WhatsAppMediaAttachment.vue.d.ts +19 -0
- package/lib/components/WhatsAppMediaAttachment/index.d.ts +1 -0
- package/lib/components/WhatsAppMessage/WhatsAppMessage.d.ts +9 -0
- package/lib/components/WhatsAppMessage/WhatsAppMessage.types.d.ts +46 -0
- package/lib/components/WhatsAppMessage/WhatsAppMessage.vue.d.ts +25 -0
- package/lib/components/WhatsAppMessage/index.d.ts +1 -0
- package/lib/components/WhatsAppMessageBubble/WhatsAppMessageBubble.d.ts +9 -0
- package/lib/components/WhatsAppMessageBubble/WhatsAppMessageBubble.types.d.ts +77 -0
- package/lib/components/WhatsAppMessageBubble/WhatsAppMessageBubble.vue.d.ts +22 -0
- package/lib/components/WhatsAppMessageBubble/index.d.ts +1 -0
- package/lib/components/WhatsAppMessageList/WhatsAppMessageList.d.ts +10 -0
- package/lib/components/WhatsAppMessageList/WhatsAppMessageList.types.d.ts +94 -0
- package/lib/components/WhatsAppMessageList/WhatsAppMessageList.vue.d.ts +39 -0
- package/lib/components/WhatsAppMessageList/index.d.ts +1 -0
- package/lib/components/WhatsAppMessageStatus/WhatsAppMessageStatus.d.ts +7 -0
- package/lib/components/WhatsAppMessageStatus/WhatsAppMessageStatus.types.d.ts +30 -0
- package/lib/components/WhatsAppMessageStatus/WhatsAppMessageStatus.vue.d.ts +24 -0
- package/lib/components/WhatsAppMessageStatus/index.d.ts +1 -0
- package/lib/components/WhatsAppMessagingWindowNotice/WhatsAppMessagingWindowNotice.d.ts +9 -0
- package/lib/components/WhatsAppMessagingWindowNotice/WhatsAppMessagingWindowNotice.types.d.ts +55 -0
- package/lib/components/WhatsAppMessagingWindowNotice/WhatsAppMessagingWindowNotice.vue.d.ts +18 -0
- package/lib/components/WhatsAppMessagingWindowNotice/index.d.ts +1 -0
- package/lib/components/WhatsAppTemplatePreview/WhatsAppTemplatePreview.d.ts +7 -0
- package/lib/components/WhatsAppTemplatePreview/WhatsAppTemplatePreview.types.d.ts +36 -0
- package/lib/components/WhatsAppTemplatePreview/WhatsAppTemplatePreview.vue.d.ts +12 -0
- package/lib/components/WhatsAppTemplatePreview/index.d.ts +1 -0
- package/lib/components/WhatsAppTemplateSelector/WhatsAppTemplateSelector.d.ts +9 -0
- package/lib/components/WhatsAppTemplateSelector/WhatsAppTemplateSelector.types.d.ts +106 -0
- package/lib/components/WhatsAppTemplateSelector/WhatsAppTemplateSelector.vue.d.ts +33 -0
- package/lib/components/WhatsAppTemplateSelector/index.d.ts +1 -0
- package/lib/emoji/emoji-data.d.ts +27 -0
- package/lib/emoji/emoji-filter.d.ts +49 -0
- package/lib/emoji/index.d.ts +4 -0
- package/lib/icons/WhatsAppIcon.vue.d.ts +14 -0
- package/lib/icons/icon-paths.d.ts +43 -0
- package/lib/icons/index.d.ts +3 -0
- package/lib/index.d.mts +29 -0
- package/lib/index.d.ts +29 -0
- package/lib/labels.d.ts +184 -0
- package/lib/types.d.ts +777 -0
- package/lib/utils/capabilities.d.ts +14 -0
- package/lib/utils/format.d.ts +27 -0
- package/lib/utils/index.d.ts +9 -0
- package/lib/utils/media.d.ts +45 -0
- package/lib/utils/messages.d.ts +48 -0
- package/lib/utils/phone.d.ts +18 -0
- package/lib/utils/templates.d.ts +65 -0
- package/package.json +46 -0
- package/styles.css +1504 -0
- package/styles.layer.css +1506 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/component-props.ts","../src/utils/format.ts","../src/utils/capabilities.ts","../src/labels.ts","../src/utils/messages.ts","../src/utils/templates.ts","../src/utils/phone.ts","../src/utils/media.ts","../src/emoji/emoji-data.ts","../src/emoji/emoji-filter.ts","../src/WhatsAppInbox.context.ts","../src/components/WhatsAppInboxProvider/WhatsAppInboxProvider.vue","../src/components/WhatsAppInboxProvider/WhatsAppInboxProvider.vue","../src/components/WhatsAppInboxProvider/WhatsAppInboxProvider.ts","../src/components/WhatsAppContactPanel/WhatsAppContactPanel.module.css","../src/components/WhatsAppContactPanel/WhatsAppContactPanel.vue","../src/components/WhatsAppContactPanel/WhatsAppContactPanel.vue","../src/components/WhatsAppContactPanel/WhatsAppContactPanel.ts","../src/icons/icon-paths.ts","../src/icons/WhatsAppIcon.vue","../src/icons/WhatsAppIcon.vue","../src/components/WhatsAppAttachmentPreview/WhatsAppAttachmentPreview.module.css","../src/components/WhatsAppAttachmentPreview/WhatsAppAttachmentPreview.vue","../src/components/WhatsAppAttachmentPreview/WhatsAppAttachmentPreview.vue","../src/components/WhatsAppAttachmentPreview/WhatsAppAttachmentPreview.ts","../src/components/WhatsAppEmojiPicker/WhatsAppEmojiPicker.module.css","../src/components/WhatsAppEmojiPicker/WhatsAppEmojiPicker.vue","../src/components/WhatsAppEmojiPicker/WhatsAppEmojiPicker.vue","../src/components/WhatsAppEmojiPicker/WhatsAppEmojiPicker.ts","../src/components/WhatsAppInteractiveMessageEditor/WhatsAppInteractiveMessageEditor.module.css","../src/components/WhatsAppInteractiveMessageEditor/WhatsAppInteractiveMessageEditor.vue","../src/components/WhatsAppInteractiveMessageEditor/WhatsAppInteractiveMessageEditor.vue","../src/components/WhatsAppInteractiveMessageEditor/WhatsAppInteractiveMessageEditor.ts","../src/components/WhatsAppMessagingWindowNotice/WhatsAppMessagingWindowNotice.module.css","../src/components/WhatsAppMessagingWindowNotice/WhatsAppMessagingWindowNotice.vue","../src/components/WhatsAppMessagingWindowNotice/WhatsAppMessagingWindowNotice.vue","../src/components/WhatsAppMessagingWindowNotice/WhatsAppMessagingWindowNotice.ts","../src/components/WhatsAppTemplatePreview/WhatsAppTemplatePreview.module.css","../src/components/WhatsAppTemplatePreview/WhatsAppTemplatePreview.vue","../src/components/WhatsAppTemplatePreview/WhatsAppTemplatePreview.vue","../src/components/WhatsAppTemplatePreview/WhatsAppTemplatePreview.ts","../src/components/WhatsAppTemplateSelector/WhatsAppTemplateSelector.module.css","../src/components/WhatsAppTemplateSelector/WhatsAppTemplateSelector.vue","../src/components/WhatsAppTemplateSelector/WhatsAppTemplateSelector.vue","../src/components/WhatsAppTemplateSelector/WhatsAppTemplateSelector.ts","../src/components/WhatsAppComposer/WhatsAppComposer.module.css","../src/components/WhatsAppComposer/WhatsAppComposer.vue","../src/components/WhatsAppComposer/WhatsAppComposer.vue","../src/components/WhatsAppComposer/WhatsAppComposer.ts","../src/components/WhatsAppConversationHeader/WhatsAppConversationHeader.module.css","../src/components/WhatsAppConversationHeader/WhatsAppConversationHeader.vue","../src/components/WhatsAppConversationHeader/WhatsAppConversationHeader.vue","../src/components/WhatsAppConversationHeader/WhatsAppConversationHeader.ts","../src/components/WhatsAppMediaAttachment/WhatsAppMediaAttachment.module.css","../src/components/WhatsAppMediaAttachment/WhatsAppMediaAttachment.vue","../src/components/WhatsAppMediaAttachment/WhatsAppMediaAttachment.vue","../src/components/WhatsAppMediaAttachment/WhatsAppMediaAttachment.ts","../src/components/WhatsAppMessageStatus/WhatsAppMessageStatus.module.css","../src/components/WhatsAppMessageStatus/WhatsAppMessageStatus.vue","../src/components/WhatsAppMessageStatus/WhatsAppMessageStatus.vue","../src/components/WhatsAppMessageStatus/WhatsAppMessageStatus.ts","../src/components/WhatsAppMessageBubble/WhatsAppMessageBubble.module.css","../src/components/WhatsAppMessageBubble/WhatsAppMessageBubble.vue","../src/components/WhatsAppMessageBubble/WhatsAppMessageBubble.vue","../src/components/WhatsAppMessageBubble/WhatsAppMessageBubble.ts","../src/components/WhatsAppMessage/WhatsAppMessage.module.css","../src/components/WhatsAppMessage/WhatsAppMessage.vue","../src/components/WhatsAppMessage/WhatsAppMessage.vue","../src/components/WhatsAppMessage/WhatsAppMessage.ts","../src/components/WhatsAppMessageList/WhatsAppMessageList.module.css","../src/components/WhatsAppMessageList/WhatsAppMessageList.vue","../src/components/WhatsAppMessageList/WhatsAppMessageList.vue","../src/components/WhatsAppMessageList/WhatsAppMessageList.ts","../src/components/WhatsAppConversation/WhatsAppConversation.module.css","../src/components/WhatsAppConversation/WhatsAppConversation.vue","../src/components/WhatsAppConversation/WhatsAppConversation.vue","../src/components/WhatsAppConversation/WhatsAppConversation.ts","../src/components/WhatsAppConversationListItem/WhatsAppConversationListItem.module.css","../src/components/WhatsAppConversationListItem/WhatsAppConversationListItem.vue","../src/components/WhatsAppConversationListItem/WhatsAppConversationListItem.vue","../src/components/WhatsAppConversationListItem/WhatsAppConversationListItem.ts","../src/components/WhatsAppConversationList/WhatsAppConversationList.module.css","../src/components/WhatsAppConversationList/WhatsAppConversationList.vue","../src/components/WhatsAppConversationList/WhatsAppConversationList.vue","../src/components/WhatsAppConversationList/WhatsAppConversationList.ts","../src/components/WhatsAppInbox/WhatsAppInbox.module.css","../src/components/WhatsAppInbox/WhatsAppInbox.vue","../src/components/WhatsAppInbox/WhatsAppInbox.vue","../src/components/WhatsAppInbox/WhatsAppInbox.ts","../src/components/WhatsAppInboxModal/WhatsAppInboxModal.module.css","../src/components/WhatsAppInboxModal/WhatsAppInboxModal.vue","../src/components/WhatsAppInboxModal/WhatsAppInboxModal.vue","../src/components/WhatsAppInboxModal/WhatsAppInboxModal.ts","../src/components/WhatsAppInboxDrawer/WhatsAppInboxDrawer.module.css","../src/components/WhatsAppInboxDrawer/WhatsAppInboxDrawer.vue","../src/components/WhatsAppInboxDrawer/WhatsAppInboxDrawer.vue","../src/components/WhatsAppInboxDrawer/WhatsAppInboxDrawer.ts"],"sourcesContent":["import type { VNodeChild } from 'vue'\nimport type { EmitsToProps } from '@mantine-vue/core'\nimport type {\n WhatsAppAttachment,\n WhatsAppContact,\n WhatsAppConversationSummary,\n WhatsAppMessageData,\n WhatsAppTemplate,\n WhatsAppUpload,\n} from './types'\n\n/**\n * Props forwarded to a component the inbox renders internally, plus the `on*` listeners for its\n * events so a nested object can subscribe to them.\n *\n * `rootRef` is dropped because it only makes sense on an element the consumer owns, and because\n * the factory narrows it to a concrete element type a `Partial<…Props>` cannot satisfy.\n */\nexport type ForwardedProps<Props, Emits = Record<never, never>> = Partial<Omit<Props, 'rootRef'>> &\n EmitsToProps<Emits>\n\n/**\n * Replaces the rendering of one message.\n *\n * The counterpart of the `message` slot. Returning `undefined` uses the built-in renderer.\n */\nexport type RenderMessage = (message: WhatsAppMessageData) => VNodeChild | undefined\n\n/** Replaces the content of one message bubble, keeping the bubble, footer and status. */\nexport type RenderMessageContent = (message: WhatsAppMessageData) => VNodeChild | undefined\n\n/** Scoped slots that mirror the message render props. Slots take precedence over the props. */\nexport interface WhatsAppMessageSlots {\n /** Replaces a message entirely, bubble included. Takes precedence over `renderMessage`. */\n message?: (props: { message: WhatsAppMessageData }) => VNodeChild\n\n /** Replaces the content inside a bubble. Takes precedence over `renderMessageContent`. */\n messageContent?: (props: { message: WhatsAppMessageData }) => VNodeChild\n\n /** Appended inside the bubble, under the content and before the timestamp row. */\n messageFooter?: (props: { message: WhatsAppMessageData }) => VNodeChild\n\n /** Replaces the media renderer of a received attachment. */\n mediaAttachment?: (props: {\n attachment: WhatsAppAttachment\n message: WhatsAppMessageData\n }) => VNodeChild\n}\n\n/** The `renderMessage` / `renderMessageContent` pair passed down to each message. */\nexport interface MessageRenderers {\n /**\n * Replaces the rendering of a message, bubble included. Returning `undefined` falls back to the\n * built-in renderer. Can also be set with the `message` slot, which takes precedence.\n */\n renderMessage?: RenderMessage\n\n /**\n * Replaces the content inside a message bubble, keeping the bubble, timestamp and delivery\n * state. Can also be set with the `messageContent` slot, which takes precedence.\n */\n renderMessageContent?: RenderMessageContent\n}\n\n/**\n * Folds the message scoped slots into the equivalent render props, so a list forwards one object\n * to every message instead of re-declaring the slots at each call site.\n */\nexport function resolveMessageRenderers(\n props: MessageRenderers,\n slots: WhatsAppMessageSlots,\n): MessageRenderers {\n return {\n renderMessage: slots.message ? (message) => slots.message!({ message }) : props.renderMessage,\n renderMessageContent: slots.messageContent\n ? (message) => slots.messageContent!({ message })\n : props.renderMessageContent,\n }\n}\n\n/** Slot props of the conversation list item slots. */\nexport interface WhatsAppConversationItemSlotProps {\n conversation: WhatsAppConversationSummary\n selected: boolean\n}\n\n/** Slots shared by the conversation list and the full inbox. */\nexport interface WhatsAppConversationListSlots {\n /** Replaces a whole conversation list item. */\n conversationItem?: (props: WhatsAppConversationItemSlotProps) => VNodeChild\n\n /** Replaces the avatar of a list item. */\n conversationAvatar?: (props: WhatsAppConversationItemSlotProps) => VNodeChild\n\n /** Replaces the last-message preview of a list item. */\n conversationPreview?: (props: WhatsAppConversationItemSlotProps) => VNodeChild\n\n /** Rendered above the search field. */\n listHeader?: () => VNodeChild\n\n /** Rendered under the list, after the load-more control. */\n listFooter?: () => VNodeChild\n\n /** Replaces the empty state of the list. */\n emptyInbox?: () => VNodeChild\n\n /** Replaces the loading state of the list. */\n loadingInbox?: () => VNodeChild\n\n /** Replaces the error state of the list. */\n errorInbox?: (props: { error: string }) => VNodeChild\n\n /** Rendered next to the search field, for custom filter controls. */\n filters?: () => VNodeChild\n}\n\n/** Slots of the conversation view, shared with the inbox, modal and drawer. */\nexport interface WhatsAppConversationSlots extends WhatsAppMessageSlots {\n /** Replaces the conversation header. */\n conversationHeader?: (props: {\n conversation: WhatsAppConversationSummary | undefined\n }) => VNodeChild\n\n /** Rendered at the end of the conversation header, before the contact panel toggle. */\n headerActions?: (props: { conversation: WhatsAppConversationSummary | undefined }) => VNodeChild\n\n /** Replaces the empty state shown when the conversation has no messages. */\n emptyConversation?: () => VNodeChild\n\n /** Replaces the loading state of the message history. */\n loadingMessages?: () => VNodeChild\n\n /** Replaces the error state of the message history. */\n errorMessages?: (props: { error: string }) => VNodeChild\n\n /** Rendered before the composer input, after the attachment control. */\n composerPrefix?: () => VNodeChild\n\n /** Rendered after the composer input, before the send control. */\n composerSuffix?: () => VNodeChild\n\n /** Replaces the composer action row. */\n composerActions?: () => VNodeChild\n\n /** Emoji picker rendered in the composer emoji popover. */\n emojiPicker?: (props: { insert: (emoji: string) => void; close: () => void }) => VNodeChild\n\n /** Replaces the preview of one staged attachment. */\n attachmentPreview?: (props: { upload: WhatsAppUpload }) => VNodeChild\n\n /** Replaces the preview of a template inside the template selector. */\n templatePreview?: (props: { template: WhatsAppTemplate }) => VNodeChild\n}\n\n/** Slots of the contact panel. */\nexport interface WhatsAppContactPanelSlots {\n /** Rendered above the built-in contact fields. */\n contactPanelHeader?: (props: { contact: WhatsAppContact }) => VNodeChild\n\n /** Replaces the whole contact panel body. */\n contactPanel?: (props: { contact: WhatsAppContact }) => VNodeChild\n\n /** Rendered under the built-in contact fields. */\n contactPanelFooter?: (props: { contact: WhatsAppContact }) => VNodeChild\n}\n","import type { WhatsAppInboxLabels } from '../labels'\nimport type { WhatsAppTimestamp } from '../types'\n\n/**\n * Converts any accepted timestamp to a `Date`, or `null` when it cannot be parsed.\n *\n * Invalid values return `null` so callers do not render `Invalid Date` or `NaN`.\n */\nexport function toDate(value: WhatsAppTimestamp | undefined | null): Date | null {\n if (value === undefined || value === null || value === '') {\n return null\n }\n\n const date = value instanceof Date ? value : new Date(value)\n\n return Number.isNaN(date.getTime()) ? null : date\n}\n\n/** Whether two dates fall on the same calendar day in the local timezone. */\nexport function isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n )\n}\n\n/** Start of the calendar day, used as the grouping key of the message list. */\nexport function startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate())\n}\n\n/**\n * Builds an `Intl.DateTimeFormat` and falls back to the default locale when the supplied one is\n * not recognized, so a bad locale string cannot throw inside a render.\n */\nfunction createFormatter(locale: string | undefined, options: Intl.DateTimeFormatOptions) {\n try {\n return new Intl.DateTimeFormat(locale, options)\n } catch {\n return new Intl.DateTimeFormat(undefined, options)\n }\n}\n\n/** Time of day, as shown under a message bubble. */\nexport function formatMessageTime(value: WhatsAppTimestamp, locale?: string): string {\n const date = toDate(value)\n\n if (!date) {\n return ''\n }\n\n return createFormatter(locale, { hour: 'numeric', minute: '2-digit' }).format(date)\n}\n\n/** Full date and time, used as the `title` and screen-reader text of a message timestamp. */\nexport function formatFullTimestamp(value: WhatsAppTimestamp, locale?: string): string {\n const date = toDate(value)\n\n if (!date) {\n return ''\n }\n\n return createFormatter(locale, { dateStyle: 'long', timeStyle: 'short' }).format(date)\n}\n\n/** Day divider label: `Today`, `Yesterday`, a weekday within the last week, or a full date. */\nexport function formatDayLabel(\n value: WhatsAppTimestamp,\n locale?: string,\n labels?: Pick<WhatsAppInboxLabels, 'today' | 'yesterday'>,\n now: Date = new Date(),\n): string {\n const date = toDate(value)\n\n if (!date) {\n return ''\n }\n\n if (isSameDay(date, now)) {\n return labels?.today ?? 'Today'\n }\n\n const yesterday = new Date(now)\n yesterday.setDate(now.getDate() - 1)\n\n if (isSameDay(date, yesterday)) {\n return labels?.yesterday ?? 'Yesterday'\n }\n\n const daysApart = Math.round(\n (startOfDay(now).getTime() - startOfDay(date).getTime()) / 86_400_000,\n )\n\n if (daysApart > 0 && daysApart < 7) {\n return createFormatter(locale, { weekday: 'long' }).format(date)\n }\n\n return createFormatter(locale, { dateStyle: 'medium' }).format(date)\n}\n\n/**\n * Timestamp of a conversation list item: the time for today, `Yesterday`, a weekday within the\n * last week, and a short date beyond that. This is what keeps the column narrow.\n */\nexport function formatConversationTime(\n value: WhatsAppTimestamp | undefined,\n locale?: string,\n labels?: Pick<WhatsAppInboxLabels, 'today' | 'yesterday'>,\n now: Date = new Date(),\n): string {\n const date = toDate(value)\n\n if (!date) {\n return ''\n }\n\n if (isSameDay(date, now)) {\n return formatMessageTime(date, locale)\n }\n\n const yesterday = new Date(now)\n yesterday.setDate(now.getDate() - 1)\n\n if (isSameDay(date, yesterday)) {\n return labels?.yesterday ?? 'Yesterday'\n }\n\n const daysApart = Math.round(\n (startOfDay(now).getTime() - startOfDay(date).getTime()) / 86_400_000,\n )\n\n if (daysApart > 0 && daysApart < 7) {\n return createFormatter(locale, { weekday: 'short' }).format(date)\n }\n\n return createFormatter(locale, { year: '2-digit', month: 'numeric', day: 'numeric' }).format(date)\n}\n\nconst FILE_SIZE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const\n\n/** Human readable file size. Used by the attachment previews and by the size validation copy. */\nexport function formatFileSize(bytes: number | undefined): string {\n if (bytes === undefined || !Number.isFinite(bytes) || bytes < 0) {\n return ''\n }\n\n if (bytes < 1024) {\n return `${bytes} ${FILE_SIZE_UNITS[0]}`\n }\n\n const exponent = Math.min(\n Math.floor(Math.log(bytes) / Math.log(1024)),\n FILE_SIZE_UNITS.length - 1,\n )\n const value = bytes / 1024 ** exponent\n const rounded = value >= 100 ? Math.round(value) : Math.round(value * 10) / 10\n\n return `${rounded} ${FILE_SIZE_UNITS[exponent]}`\n}\n\n/** `m:ss` duration, as shown on audio and video attachments. */\nexport function formatDuration(seconds: number | undefined): string {\n if (seconds === undefined || !Number.isFinite(seconds) || seconds < 0) {\n return ''\n }\n\n const total = Math.round(seconds)\n const hours = Math.floor(total / 3600)\n const minutes = Math.floor((total % 3600) / 60)\n const remaining = total % 60\n const paddedSeconds = String(remaining).padStart(2, '0')\n\n if (hours > 0) {\n return `${hours}:${String(minutes).padStart(2, '0')}:${paddedSeconds}`\n }\n\n return `${minutes}:${paddedSeconds}`\n}\n","import type {\n WhatsAppConversationCapabilities,\n WhatsAppMediaType,\n WhatsAppMessagingWindow,\n WhatsAppResolvedCapabilities,\n} from '../types'\n\n/** Media types offered when `canSendMedia` is set but `allowedMediaTypes` is not. */\nexport const DEFAULT_ALLOWED_MEDIA_TYPES: WhatsAppMediaType[] = [\n 'image',\n 'video',\n 'audio',\n 'document',\n]\n\n/** Window state assumed when the backend did not report one. */\nexport const UNKNOWN_MESSAGING_WINDOW: WhatsAppMessagingWindow = { state: 'unknown' }\n\n/**\n * Fills in every capability default once, so no component repeats them.\n *\n * The only rule the frontend applies is the one it can apply safely: a *closed* window, as\n * reported by the backend, turns free-form messaging off. Whether the window is closed is never\n * derived from timestamps here — `state: 'unknown'` deliberately leaves the composer usable\n * rather than guessing at WhatsApp's 24-hour rule.\n */\nexport function resolveCapabilities(\n capabilities: WhatsAppConversationCapabilities | undefined,\n): WhatsAppResolvedCapabilities {\n const messagingWindow = capabilities?.messagingWindow ?? UNKNOWN_MESSAGING_WINDOW\n const windowClosed = messagingWindow.state === 'closed'\n\n const canSendMedia = capabilities?.canSendMedia ?? false\n const canSendFreeForm = (capabilities?.canSendFreeForm ?? true) && !windowClosed\n const canSendTemplates = capabilities?.canSendTemplates ?? false\n const canSendInteractive = (capabilities?.canSendInteractive ?? false) && !windowClosed\n\n return {\n canSendFreeForm,\n canSendTemplates,\n // Media is part of free-form messaging as far as the window is concerned.\n canSendMedia: canSendMedia && !windowClosed,\n canSendInteractive,\n canUseEmoji: capabilities?.canUseEmoji ?? false,\n canReplyToMessage: capabilities?.canReplyToMessage ?? false,\n canRetryFailed: capabilities?.canRetryFailed ?? true,\n allowedMediaTypes: capabilities?.allowedMediaTypes ?? DEFAULT_ALLOWED_MEDIA_TYPES,\n interactiveTypes: capabilities?.interactiveTypes ?? [],\n maxTextLength: capabilities?.maxTextLength,\n mediaConstraints: capabilities?.mediaConstraints ?? {},\n messagingWindow,\n disabledReason: capabilities?.disabledReason,\n windowClosed,\n canSendAnything:\n canSendFreeForm || canSendTemplates || (canSendMedia && !windowClosed) || canSendInteractive,\n }\n}\n","/**\n * Every user-visible string the extension renders on its own.\n *\n * Nothing is hard-coded inside a template: a consumer localizes the whole inbox by passing one\n * `labels` object to `WhatsAppInboxProvider`, and any component can still override a single key\n * without losing the rest.\n */\nexport interface WhatsAppInboxLabels {\n /* Conversation list */\n conversationsLabel: string\n searchPlaceholder: string\n searchLabel: string\n unreadFilterLabel: string\n statusFilterLabel: string\n statusFilterPlaceholder: string\n assigneeFilterLabel: string\n assigneeFilterPlaceholder: string\n unassigned: string\n clearFilters: string\n newConversation: string\n newConversationTitle: string\n newConversationDescription: string\n newConversationPhoneLabel: string\n newConversationPhonePlaceholder: string\n newConversationNameLabel: string\n newConversationNamePlaceholder: string\n newConversationSubmit: string\n newConversationInvalidPhone: string\n newConversationExists: string\n loadMoreConversations: string\n loadingConversations: string\n conversationsError: string\n emptyInbox: string\n emptySearch: string\n unreadCountLabel: (count: number) => string\n conversationItemLabel: (name: string) => string\n\n /* Conversation view */\n noConversationSelected: string\n noConversationSelectedDescription: string\n emptyConversation: string\n emptyConversationDescription: string\n conversationError: string\n messagesError: string\n loadingMessages: string\n loadOlderMessages: string\n loadingOlderMessages: string\n backToConversations: string\n scrollToBottom: string\n newMessages: (count: number) => string\n messageHistoryLabel: string\n\n /* Dates */\n today: string\n yesterday: string\n\n /* Delivery states */\n statusPending: string\n statusSent: string\n statusDelivered: string\n statusRead: string\n statusFailed: string\n messageStatusLabel: (status: string) => string\n inboundMessageLabel: string\n outboundMessageLabel: string\n forwarded: string\n retrySend: string\n sendFailed: string\n\n /* Composer */\n composerPlaceholder: string\n composerLabel: string\n send: string\n sending: string\n attachFile: string\n emoji: string\n templates: string\n interactiveMessage: string\n cancelReply: string\n replyingTo: string\n messageTooLong: (max: number) => string\n characterCount: (count: number, max: number) => string\n emptyMessage: string\n\n /* Emoji picker */\n emojiPickerLabel: string\n emojiPickerSearchPlaceholder: string\n emojiPickerNoResults: string\n emojiPickerSearchResults: string\n emojiGroupRecent: string\n emojiGroupSmileys: string\n emojiGroupPeople: string\n emojiGroupAnimals: string\n emojiGroupFood: string\n emojiGroupActivity: string\n emojiGroupTravel: string\n emojiGroupObjects: string\n emojiGroupSymbols: string\n emojiGroupFlags: string\n\n /* Messaging window */\n windowClosedTitle: string\n windowClosedDescription: string\n windowExpiresAt: (time: string) => string\n sendTemplateInstead: string\n composerDisabled: string\n\n /* Templates */\n templateSelectorTitle: string\n templateSearchPlaceholder: string\n templateCategoryLabel: string\n templateLanguageLabel: string\n templateStatusLabel: string\n templatesEmpty: string\n templatesError: string\n templatesLoading: string\n templateParameters: string\n templateHeaderVariables: string\n templateBodyVariables: string\n templateButtonVariables: string\n templatePreview: string\n templateRequiredField: string\n templateBack: string\n templateSubmit: string\n templateUnavailable: string\n templateHeaderMedia: string\n templateHeaderMediaRequired: string\n\n /* Interactive editor */\n interactiveTitle: string\n interactiveType: string\n interactiveTypeButton: string\n interactiveTypeCtaUrl: string\n interactiveTypeList: string\n interactiveBody: string\n interactiveFooter: string\n interactiveHeader: string\n interactiveButtons: string\n interactiveAddButton: string\n interactiveRemoveButton: string\n interactiveButtonText: string\n interactiveCtaDisplayText: string\n interactiveCtaUrl: string\n interactiveListButton: string\n interactiveListSections: string\n interactiveAddSection: string\n interactiveRemoveSection: string\n interactiveAddRow: string\n interactiveRemoveRow: string\n interactiveSectionTitle: string\n interactiveRowTitle: string\n interactiveRowDescription: string\n interactiveSubmit: string\n interactiveBodyRequired: string\n interactiveButtonsRequired: string\n interactiveUrlRequired: string\n interactiveRowsRequired: string\n\n /* Media */\n download: string\n openInNewTab: string\n removeAttachment: string\n retryUpload: string\n cancelUpload: string\n uploading: string\n uploadFailed: string\n attachmentsLabel: string\n playAudio: string\n fileTooLarge: (fileName: string, max: string) => string\n fileInvalidType: (fileName: string) => string\n tooManyFiles: (max: number) => string\n mediaUnavailable: string\n\n /* Contact panel */\n contactPanelTitle: string\n contactPanelToggle: string\n contactPhoneNumber: string\n contactEmail: string\n contactAbout: string\n contactTags: string\n contactStatus: string\n contactAssignee: string\n\n /* Message content fallbacks, also used for conversation previews */\n messageTypeImage: string\n messageTypeVideo: string\n messageTypeAudio: string\n messageTypeDocument: string\n messageTypeSticker: string\n messageTypeLocation: string\n messageTypeContacts: string\n messageTypeTemplate: string\n messageTypeInteractive: string\n messageTypeUnsupported: string\n\n /* Generic */\n retry: string\n close: string\n cancel: string\n loading: string\n}\n\n/** English defaults. Every key can be replaced through `labels`. */\nexport const DEFAULT_WHATSAPP_INBOX_LABELS: WhatsAppInboxLabels = {\n conversationsLabel: 'Conversations',\n searchPlaceholder: 'Search conversations',\n searchLabel: 'Search conversations',\n unreadFilterLabel: 'Unread only',\n statusFilterLabel: 'Status',\n statusFilterPlaceholder: 'All statuses',\n assigneeFilterLabel: 'Assignee',\n assigneeFilterPlaceholder: 'Anyone',\n unassigned: 'Unassigned',\n clearFilters: 'Clear filters',\n newConversation: 'New conversation',\n newConversationTitle: 'Start a new conversation',\n newConversationDescription:\n 'Enter the WhatsApp number of the person you want to message. Include the country code.',\n newConversationPhoneLabel: 'Phone number',\n newConversationPhonePlaceholder: '+973 3300 0000',\n newConversationNameLabel: 'Name (optional)',\n newConversationNamePlaceholder: 'How this contact should appear in the list',\n newConversationSubmit: 'Start conversation',\n newConversationInvalidPhone: 'Enter a valid phone number, including the country code',\n newConversationExists: 'You already have a conversation with this number',\n loadMoreConversations: 'Load more',\n loadingConversations: 'Loading conversations',\n conversationsError: 'Conversations could not be loaded',\n emptyInbox: 'No conversations yet',\n emptySearch: 'No conversations match your filters',\n unreadCountLabel: (count) => `${count} unread ${count === 1 ? 'message' : 'messages'}`,\n conversationItemLabel: (name) => `Conversation with ${name}`,\n\n noConversationSelected: 'No conversation selected',\n noConversationSelectedDescription: 'Pick a conversation from the list to start messaging.',\n emptyConversation: 'No messages yet',\n emptyConversationDescription: 'Messages in this conversation will appear here.',\n conversationError: 'Conversation could not be loaded',\n messagesError: 'Messages could not be loaded',\n loadingMessages: 'Loading messages',\n loadOlderMessages: 'Load older messages',\n loadingOlderMessages: 'Loading older messages',\n backToConversations: 'Back to conversations',\n scrollToBottom: 'Scroll to latest messages',\n newMessages: (count) => `${count} new ${count === 1 ? 'message' : 'messages'}`,\n messageHistoryLabel: 'Message history',\n\n today: 'Today',\n yesterday: 'Yesterday',\n\n statusPending: 'Sending',\n statusSent: 'Sent',\n statusDelivered: 'Delivered',\n statusRead: 'Read',\n statusFailed: 'Failed',\n messageStatusLabel: (status) => `Message ${status.toLowerCase()}`,\n inboundMessageLabel: 'Received message',\n outboundMessageLabel: 'Sent message',\n forwarded: 'Forwarded',\n retrySend: 'Try again',\n sendFailed: 'Message could not be sent',\n\n composerPlaceholder: 'Type a message',\n composerLabel: 'Message',\n send: 'Send',\n sending: 'Sending',\n attachFile: 'Attach file',\n emoji: 'Insert emoji',\n templates: 'Send template',\n interactiveMessage: 'Interactive message',\n cancelReply: 'Cancel reply',\n replyingTo: 'Replying to',\n messageTooLong: (max) => `Message must be ${max} characters or fewer`,\n characterCount: (count, max) => `${count} / ${max}`,\n emptyMessage: 'Enter a message before sending',\n\n emojiPickerLabel: 'Emoji',\n emojiPickerSearchPlaceholder: 'Search emoji',\n emojiPickerNoResults: 'No emoji found',\n emojiPickerSearchResults: 'Search results',\n emojiGroupRecent: 'Recently used',\n emojiGroupSmileys: 'Smileys and emotion',\n emojiGroupPeople: 'People and body',\n emojiGroupAnimals: 'Animals and nature',\n emojiGroupFood: 'Food and drink',\n emojiGroupActivity: 'Activity',\n emojiGroupTravel: 'Travel and places',\n emojiGroupObjects: 'Objects',\n emojiGroupSymbols: 'Symbols',\n emojiGroupFlags: 'Flags',\n\n windowClosedTitle: 'Free-form messaging is unavailable',\n windowClosedDescription:\n 'The customer service window for this conversation is closed. Send an approved template to reach this contact.',\n windowExpiresAt: (time) => `Free-form messaging available until ${time}`,\n sendTemplateInstead: 'Send a template',\n composerDisabled: 'You cannot send messages in this conversation',\n\n templateSelectorTitle: 'Templates',\n templateSearchPlaceholder: 'Search templates',\n templateCategoryLabel: 'Category',\n templateLanguageLabel: 'Language',\n templateStatusLabel: 'Status',\n templatesEmpty: 'No templates match your search',\n templatesError: 'Templates could not be loaded',\n templatesLoading: 'Loading templates',\n templateParameters: 'Template parameters',\n templateHeaderVariables: 'Header',\n templateBodyVariables: 'Body',\n templateButtonVariables: 'Buttons',\n templatePreview: 'Preview',\n templateRequiredField: 'This value is required',\n templateBack: 'Back to templates',\n templateSubmit: 'Send template',\n templateUnavailable: 'This template is not approved and cannot be sent',\n templateHeaderMedia: 'Header media',\n templateHeaderMediaRequired: 'Header media is required',\n\n interactiveTitle: 'Interactive message',\n interactiveType: 'Type',\n interactiveTypeButton: 'Reply buttons',\n interactiveTypeCtaUrl: 'Call to action',\n interactiveTypeList: 'List',\n interactiveBody: 'Body',\n interactiveFooter: 'Footer',\n interactiveHeader: 'Header',\n interactiveButtons: 'Buttons',\n interactiveAddButton: 'Add button',\n interactiveRemoveButton: 'Remove button',\n interactiveButtonText: 'Button text',\n interactiveCtaDisplayText: 'Button text',\n interactiveCtaUrl: 'URL',\n interactiveListButton: 'List button text',\n interactiveListSections: 'Sections',\n interactiveAddSection: 'Add section',\n interactiveRemoveSection: 'Remove section',\n interactiveAddRow: 'Add row',\n interactiveRemoveRow: 'Remove row',\n interactiveSectionTitle: 'Section title',\n interactiveRowTitle: 'Row title',\n interactiveRowDescription: 'Row description',\n interactiveSubmit: 'Send interactive message',\n interactiveBodyRequired: 'Body text is required',\n interactiveButtonsRequired: 'Add at least one button',\n interactiveUrlRequired: 'A valid URL is required',\n interactiveRowsRequired: 'Add at least one row',\n\n download: 'Download',\n openInNewTab: 'Open',\n removeAttachment: 'Remove attachment',\n retryUpload: 'Retry upload',\n cancelUpload: 'Cancel upload',\n uploading: 'Uploading',\n uploadFailed: 'Upload failed',\n attachmentsLabel: 'Attachments',\n playAudio: 'Play audio message',\n fileTooLarge: (fileName, max) => `${fileName} is larger than ${max}`,\n fileInvalidType: (fileName) => `${fileName} is not a supported file type`,\n tooManyFiles: (max) => `You can attach at most ${max} ${max === 1 ? 'file' : 'files'}`,\n mediaUnavailable: 'Media is unavailable',\n\n contactPanelTitle: 'Contact details',\n contactPanelToggle: 'Toggle contact details',\n contactPhoneNumber: 'Phone number',\n contactEmail: 'Email',\n contactAbout: 'About',\n contactTags: 'Tags',\n contactStatus: 'Status',\n contactAssignee: 'Assignee',\n\n messageTypeImage: 'Photo',\n messageTypeVideo: 'Video',\n messageTypeAudio: 'Audio',\n messageTypeDocument: 'Document',\n messageTypeSticker: 'Sticker',\n messageTypeLocation: 'Location',\n messageTypeContacts: 'Contact',\n messageTypeTemplate: 'Template',\n messageTypeInteractive: 'Interactive message',\n messageTypeUnsupported: 'Unsupported message',\n\n retry: 'Try again',\n close: 'Close',\n cancel: 'Cancel',\n loading: 'Loading',\n}\n\n/** Partial override of the built-in labels. */\nexport type WhatsAppInboxLabelsOverride = Partial<WhatsAppInboxLabels>\n\n/** Reads one label, applying an override on top of the defaults. */\nexport function getWhatsAppLabel<Key extends keyof WhatsAppInboxLabels>(\n key: Key,\n override?: WhatsAppInboxLabelsOverride,\n): WhatsAppInboxLabels[Key] {\n return (override?.[key] ?? DEFAULT_WHATSAPP_INBOX_LABELS[key]) as WhatsAppInboxLabels[Key]\n}\n\n/** Merges one or more overrides over the defaults, later sources winning. */\nexport function mergeWhatsAppLabels(\n ...overrides: (WhatsAppInboxLabelsOverride | undefined)[]\n): WhatsAppInboxLabels {\n return overrides.reduce<WhatsAppInboxLabels>(\n (acc, override) => (override ? { ...acc, ...override } : acc),\n DEFAULT_WHATSAPP_INBOX_LABELS,\n )\n}\n","import type { WhatsAppInboxLabels } from '../labels'\nimport { DEFAULT_WHATSAPP_INBOX_LABELS } from '../labels'\nimport type {\n WhatsAppConversationPreview,\n WhatsAppConversationSummary,\n WhatsAppMessageData,\n WhatsAppMessageType,\n} from '../types'\nimport { isSameDay, startOfDay, toDate } from './format'\n\n/** One calendar day of messages, as rendered between two day dividers. */\nexport interface WhatsAppMessageGroup {\n /** Stable key for the group, derived from the day. */\n key: string\n\n /** Start of the day the group covers. `null` for messages without a usable timestamp. */\n date: Date | null\n\n messages: WhatsAppMessageData[]\n}\n\n/**\n * Splits a message list into calendar days, preserving the order it was given in.\n *\n * The list is not sorted: the consumer owns ordering, and re-sorting here would fight a backend\n * that returns messages in its own sequence (for example threaded or cursor-paged results).\n */\nexport function groupMessagesByDay(messages: WhatsAppMessageData[]): WhatsAppMessageGroup[] {\n const groups: WhatsAppMessageGroup[] = []\n\n for (const message of messages) {\n const date = toDate(message.timestamp)\n const last = groups[groups.length - 1]\n\n if (\n last &&\n ((date === null && last.date === null) || (date && last.date && isSameDay(date, last.date)))\n ) {\n last.messages.push(message)\n continue\n }\n\n const day = date ? startOfDay(date) : null\n\n groups.push({\n key: day ? String(day.getTime()) : `unknown-${groups.length}`,\n date: day,\n messages: [message],\n })\n }\n\n return groups\n}\n\n/** Label used when a message type has no text of its own, for example a photo without caption. */\nexport function getMessageTypeLabel(\n type: WhatsAppMessageType | undefined,\n labels: WhatsAppInboxLabels = DEFAULT_WHATSAPP_INBOX_LABELS,\n): string {\n switch (type) {\n case 'image':\n return labels.messageTypeImage\n case 'video':\n return labels.messageTypeVideo\n case 'audio':\n return labels.messageTypeAudio\n case 'document':\n return labels.messageTypeDocument\n case 'sticker':\n return labels.messageTypeSticker\n case 'location':\n return labels.messageTypeLocation\n case 'contacts':\n return labels.messageTypeContacts\n case 'template':\n return labels.messageTypeTemplate\n case 'interactive':\n return labels.messageTypeInteractive\n case 'unsupported':\n return labels.messageTypeUnsupported\n default:\n return ''\n }\n}\n\n/**\n * Single-line text for a message, used by conversation previews and by accessible names.\n *\n * Exhaustive over the message union, so adding a message type is a compile error here rather\n * than an empty preview at runtime.\n */\nexport function getMessagePreviewText(\n message: WhatsAppMessageData,\n labels: WhatsAppInboxLabels = DEFAULT_WHATSAPP_INBOX_LABELS,\n): string {\n switch (message.type) {\n case 'text':\n case 'system':\n return message.text\n case 'image':\n case 'video':\n case 'audio':\n case 'document':\n case 'sticker':\n return (\n message.caption || message.attachment.fileName || getMessageTypeLabel(message.type, labels)\n )\n case 'template':\n return message.template.text || `${labels.messageTypeTemplate}: ${message.template.name}`\n case 'interactive':\n return message.reply?.title || message.interactive.body || labels.messageTypeInteractive\n case 'location':\n return message.location.name || message.location.address || labels.messageTypeLocation\n case 'contacts':\n return (\n message.contacts.map((contact) => contact.name).join(', ') || labels.messageTypeContacts\n )\n case 'unsupported':\n return message.text || labels.messageTypeUnsupported\n default:\n return ''\n }\n}\n\n/** Preview text of a conversation list item, falling back to a label derived from the type. */\nexport function getConversationPreviewText(\n preview: WhatsAppConversationPreview | undefined,\n labels: WhatsAppInboxLabels = DEFAULT_WHATSAPP_INBOX_LABELS,\n): string {\n if (!preview) {\n return ''\n }\n\n return preview.text || getMessageTypeLabel(preview.type, labels)\n}\n\n/** Display name of a contact, falling back to the phone number and then to the id. */\nexport function getContactDisplayName(conversation: WhatsAppConversationSummary): string {\n return conversation.contact.name || conversation.contact.phoneNumber || conversation.contact.id\n}\n\n/** Time a conversation is ordered by: its last activity, then its last message. */\nexport function getConversationActivityTime(conversation: WhatsAppConversationSummary): number {\n const updatedAt = toDate(conversation.updatedAt)\n\n if (updatedAt) {\n return updatedAt.getTime()\n }\n\n return toDate(conversation.lastMessage?.timestamp)?.getTime() ?? 0\n}\n\n/**\n * Copy of the list ordered by latest activity, pinned conversations first.\n *\n * Opt-in: `WhatsAppConversationList` renders the array it is given untouched unless `order` is\n * set, because a server-side ordering (relevance, priority, custom queues) must not be silently\n * overwritten by the UI.\n */\nexport function sortConversationsByActivity<T extends WhatsAppConversationSummary>(\n conversations: T[],\n): T[] {\n return [...conversations].sort((a, b) => {\n if (Boolean(a.pinned) !== Boolean(b.pinned)) {\n return a.pinned ? -1 : 1\n }\n\n return getConversationActivityTime(b) - getConversationActivityTime(a)\n })\n}\n\nlet clientIdCounter = 0\n\n/**\n * Identifier attached to every outgoing payload so the consumer can reconcile its optimistic\n * message with the one the backend echoes back.\n *\n * `crypto.randomUUID` when available, and a counter-plus-timestamp fallback for the environments\n * that do not expose it (older Safari, non-secure contexts, some test runners).\n */\nexport function createClientId(): string {\n const globalCrypto = typeof globalThis === 'undefined' ? undefined : globalThis.crypto\n\n if (globalCrypto && typeof globalCrypto.randomUUID === 'function') {\n return globalCrypto.randomUUID()\n }\n\n clientIdCounter += 1\n\n return `wa-${Date.now().toString(36)}-${clientIdCounter.toString(36)}`\n}\n","import type { WhatsAppInboxLabels } from '../labels'\nimport { DEFAULT_WHATSAPP_INBOX_LABELS } from '../labels'\nimport type {\n WhatsAppTemplate,\n WhatsAppTemplateBodyComponent,\n WhatsAppTemplateButton,\n WhatsAppTemplateButtonsComponent,\n WhatsAppTemplateFooterComponent,\n WhatsAppTemplateHeaderComponent,\n WhatsAppTemplateParameter,\n WhatsAppTemplateValues,\n} from '../types'\n\n/** Matches `{{1}}` and `{{customer_name}}` placeholders. */\nconst PLACEHOLDER_PATTERN = /\\{\\{\\s*([\\w.-]+)\\s*\\}\\}/g\n\n/** Placeholder keys used in a piece of template text, in order and without duplicates. */\nexport function extractPlaceholders(text: string | undefined): string[] {\n if (!text) {\n return []\n }\n\n const keys: string[] = []\n\n for (const match of text.matchAll(PLACEHOLDER_PATTERN)) {\n const key = match[1]\n\n if (!keys.includes(key)) {\n keys.push(key)\n }\n }\n\n return keys\n}\n\nexport function getTemplateHeader(\n template: WhatsAppTemplate | undefined,\n): WhatsAppTemplateHeaderComponent | undefined {\n return template?.components.find((component) => component.type === 'header')\n}\n\nexport function getTemplateBody(\n template: WhatsAppTemplate | undefined,\n): WhatsAppTemplateBodyComponent | undefined {\n return template?.components.find((component) => component.type === 'body')\n}\n\nexport function getTemplateFooter(\n template: WhatsAppTemplate | undefined,\n): WhatsAppTemplateFooterComponent | undefined {\n return template?.components.find((component) => component.type === 'footer')\n}\n\nexport function getTemplateButtons(\n template: WhatsAppTemplate | undefined,\n): WhatsAppTemplateButtonsComponent | undefined {\n return template?.components.find((component) => component.type === 'buttons')\n}\n\n/**\n * Declared parameters, or parameters derived from the placeholders in `text`.\n *\n * Backends normalize templates differently: some ship an explicit parameter list, others only\n * the raw text. Deriving the missing case means the parameter form works either way.\n */\nfunction resolveParameters(\n declared: WhatsAppTemplateParameter[] | undefined,\n text: string | undefined,\n): WhatsAppTemplateParameter[] {\n if (declared && declared.length > 0) {\n return declared\n }\n\n return extractPlaceholders(text).map((key) => ({ key, type: 'text', required: true }))\n}\n\n/** Placeholders of one template button, together with the button and its index. */\nexport interface WhatsAppTemplateButtonParameters {\n index: number\n button: WhatsAppTemplateButton\n parameters: WhatsAppTemplateParameter[]\n}\n\n/** Everything the parameter form needs to know about a template. */\nexport interface WhatsAppTemplateParameters {\n header: WhatsAppTemplateParameter[]\n body: WhatsAppTemplateParameter[]\n buttons: WhatsAppTemplateButtonParameters[]\n\n /** Header format, or `undefined` when the template has no header. */\n headerFormat: WhatsAppTemplateHeaderComponent['format'] | undefined\n\n /** Whether the header expects a media file rather than text. */\n requiresHeaderMedia: boolean\n\n /** Whether the template needs any input at all. */\n hasParameters: boolean\n}\n\n/** Collects every placeholder a template declares, grouped by the section it belongs to. */\nexport function getTemplateParameters(\n template: WhatsAppTemplate | undefined,\n): WhatsAppTemplateParameters {\n const header = getTemplateHeader(template)\n const body = getTemplateBody(template)\n const buttons = getTemplateButtons(template)\n\n const headerFormat = header ? (header.format ?? 'text') : undefined\n const requiresHeaderMedia =\n headerFormat === 'image' || headerFormat === 'video' || headerFormat === 'document'\n\n const headerParameters = requiresHeaderMedia\n ? []\n : resolveParameters(header?.parameters, header?.text)\n\n const buttonParameters: WhatsAppTemplateButtonParameters[] = (buttons?.buttons ?? [])\n .map((button, index) => ({\n index,\n button,\n parameters:\n button.type === 'url'\n ? resolveParameters(button.parameters, button.url)\n : button.type === 'copy_code'\n ? resolveParameters(button.parameters, undefined)\n : [],\n }))\n .filter((entry) => entry.parameters.length > 0)\n\n const bodyParameters = resolveParameters(body?.parameters, body?.text)\n\n return {\n header: headerParameters,\n body: bodyParameters,\n buttons: buttonParameters,\n headerFormat,\n requiresHeaderMedia,\n hasParameters:\n requiresHeaderMedia ||\n headerParameters.length > 0 ||\n bodyParameters.length > 0 ||\n buttonParameters.length > 0,\n }\n}\n\n/** Empty value object matching a template's shape, used to seed the parameter form. */\nexport function createEmptyTemplateValues(\n template: WhatsAppTemplate | undefined,\n): WhatsAppTemplateValues {\n const parameters = getTemplateParameters(template)\n const buttons: Record<string, Record<string, string>> = {}\n\n for (const entry of parameters.buttons) {\n buttons[String(entry.index)] = Object.fromEntries(\n entry.parameters.map((parameter) => [parameter.key, '']),\n )\n }\n\n return {\n header: Object.fromEntries(parameters.header.map((parameter) => [parameter.key, ''])),\n body: Object.fromEntries(parameters.body.map((parameter) => [parameter.key, ''])),\n buttons,\n headerMedia: null,\n }\n}\n\n/** Field-level validation errors of a template parameter form. */\nexport interface WhatsAppTemplateErrors {\n header: Record<string, string>\n body: Record<string, string>\n buttons: Record<string, Record<string, string>>\n headerMedia?: string\n}\n\n/** Result of validating a template parameter form. */\nexport interface WhatsAppTemplateValidation {\n valid: boolean\n errors: WhatsAppTemplateErrors\n}\n\nfunction validateSection(\n parameters: WhatsAppTemplateParameter[],\n values: Record<string, string> | undefined,\n labels: WhatsAppInboxLabels,\n): Record<string, string> {\n const errors: Record<string, string> = {}\n\n for (const parameter of parameters) {\n const value = values?.[parameter.key]?.trim() ?? ''\n const required = parameter.required ?? true\n\n if (required && value.length === 0) {\n errors[parameter.key] = labels.templateRequiredField\n }\n }\n\n return errors\n}\n\n/**\n * Validates entered template values against the template's own declaration.\n *\n * Only the shape of the template drives this: nothing here knows which templates a particular\n * provider accepts, which stays a backend decision surfaced through `WhatsAppTemplate.status`.\n */\nexport function validateTemplateValues(\n template: WhatsAppTemplate | undefined,\n values: WhatsAppTemplateValues,\n labels: WhatsAppInboxLabels = DEFAULT_WHATSAPP_INBOX_LABELS,\n): WhatsAppTemplateValidation {\n const parameters = getTemplateParameters(template)\n\n const errors: WhatsAppTemplateErrors = {\n header: validateSection(parameters.header, values.header, labels),\n body: validateSection(parameters.body, values.body, labels),\n buttons: {},\n }\n\n for (const entry of parameters.buttons) {\n const key = String(entry.index)\n const buttonErrors = validateSection(entry.parameters, values.buttons?.[key], labels)\n\n if (Object.keys(buttonErrors).length > 0) {\n errors.buttons[key] = buttonErrors\n }\n }\n\n if (parameters.requiresHeaderMedia && !values.headerMedia) {\n errors.headerMedia = labels.templateHeaderMediaRequired\n }\n\n const valid =\n Object.keys(errors.header).length === 0 &&\n Object.keys(errors.body).length === 0 &&\n Object.keys(errors.buttons).length === 0 &&\n errors.headerMedia === undefined\n\n return { valid, errors }\n}\n\n/**\n * Substitutes entered values into template text.\n *\n * Placeholders without a value keep their original form, so the preview shows the user exactly\n * which variables are still empty.\n */\nexport function renderTemplateText(\n text: string | undefined,\n values: Record<string, string> | undefined,\n): string {\n if (!text) {\n return ''\n }\n\n return text.replace(PLACEHOLDER_PATTERN, (match, key: string) => {\n const value = values?.[key]\n\n return value === undefined || value === '' ? match : value\n })\n}\n\n/** Whether a template may be sent, that is, whether the provider approved it. */\nexport function isTemplateSendable(template: WhatsAppTemplate): boolean {\n return template.status === undefined || template.status === 'approved'\n}\n\n/**\n * Filters templates by a free-text query across name, description, category and body text.\n *\n * Client-side filtering of an already-supplied list, not a data-fetching concern: a consumer\n * that searches server-side simply passes the filtered list and leaves the query empty.\n */\nexport function filterTemplates(templates: WhatsAppTemplate[], query: string): WhatsAppTemplate[] {\n const trimmed = query.trim().toLowerCase()\n\n if (trimmed.length === 0) {\n return templates\n }\n\n return templates.filter((template) => {\n const body = getTemplateBody(template)?.text ?? ''\n const haystack = [\n template.name,\n template.description ?? '',\n template.category ?? '',\n template.languageLabel ?? template.language,\n body,\n ]\n .join(' ')\n .toLowerCase()\n\n return haystack.includes(trimmed)\n })\n}\n","/**\n * Phone number handling for starting a conversation with a number that is not in the list yet.\n *\n * Deliberately permissive: the authoritative check is whichever provider the consumer uses, and\n * a frontend that guessed at national formats would reject numbers the backend accepts. All this\n * does is catch obvious typos before the payload is emitted.\n */\n\n/** Digits only, keeping a leading `+`. Handy as a lookup key for an existing conversation. */\nexport function normalizePhoneNumber(value: string): string {\n const trimmed = value.trim()\n const digits = trimmed.replace(/\\D/g, '')\n\n if (digits.length === 0) {\n return ''\n }\n\n return trimmed.startsWith('+') ? `+${digits}` : digits\n}\n\n/**\n * Shortest and longest number the default validation accepts.\n *\n * E.164 allows up to 15 digits; the lower bound is loose enough for short codes.\n */\nexport const MIN_PHONE_NUMBER_DIGITS = 6\nexport const MAX_PHONE_NUMBER_DIGITS = 15\n\n/** Whether a number is plausible enough to send to the backend. */\nexport function isValidPhoneNumber(value: string): boolean {\n const digits = normalizePhoneNumber(value).replace(/\\D/g, '')\n\n return digits.length >= MIN_PHONE_NUMBER_DIGITS && digits.length <= MAX_PHONE_NUMBER_DIGITS\n}\n","import type { WhatsAppInboxLabels } from '../labels'\nimport { DEFAULT_WHATSAPP_INBOX_LABELS } from '../labels'\nimport type { WhatsAppMediaConstraints, WhatsAppMediaType, WhatsAppRejectedFile } from '../types'\nimport { formatFileSize } from './format'\n\n/**\n * `accept` values offered per media type when the consumer does not configure its own.\n *\n * Deliberately broad: the authoritative list of what a provider accepts lives on the backend, and\n * a consumer narrows this through `capabilities.mediaConstraints`.\n */\nexport const DEFAULT_MEDIA_ACCEPT: Record<WhatsAppMediaType, string[]> = {\n image: ['image/*'],\n video: ['video/*'],\n audio: ['audio/*'],\n document: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'text/plain',\n 'text/csv',\n ],\n sticker: ['image/webp'],\n}\n\n/**\n * Maps a MIME type onto the media type that decides which renderer is used.\n *\n * Never returns `sticker`: stickers are classified by the backend, a picked `.webp` file is an\n * image. Anything unrecognized is a document, which is the renderer that degrades best.\n */\nexport function getMediaTypeFromMime(mimeType: string | undefined): WhatsAppMediaType {\n const mime = mimeType?.toLowerCase() ?? ''\n\n if (mime.startsWith('image/')) {\n return 'image'\n }\n\n if (mime.startsWith('video/')) {\n return 'video'\n }\n\n if (mime.startsWith('audio/')) {\n return 'audio'\n }\n\n return 'document'\n}\n\n/** Value for the `accept` attribute of the composer file input. */\nexport function getAcceptAttribute(\n allowedMediaTypes: WhatsAppMediaType[],\n constraints: Partial<Record<WhatsAppMediaType, WhatsAppMediaConstraints>> = {},\n): string {\n const accept = allowedMediaTypes.flatMap(\n (mediaType) => constraints[mediaType]?.accept ?? DEFAULT_MEDIA_ACCEPT[mediaType],\n )\n\n return [...new Set(accept)].join(',')\n}\n\n/** Whether a file matches one entry of an `accept` list, which may be a wildcard or extension. */\nfunction matchesAcceptEntry(file: File, entry: string): boolean {\n const normalized = entry.trim().toLowerCase()\n\n if (normalized.length === 0) {\n return false\n }\n\n if (normalized.startsWith('.')) {\n return file.name.toLowerCase().endsWith(normalized)\n }\n\n const mime = file.type.toLowerCase()\n\n if (normalized.endsWith('/*')) {\n return mime.startsWith(normalized.slice(0, -1))\n }\n\n return mime === normalized\n}\n\n/** Whether a file matches any entry of an `accept` list. An empty list accepts everything. */\nexport function matchesAccept(file: File, accept: string[] | undefined): boolean {\n if (!accept || accept.length === 0) {\n return true\n }\n\n return accept.some((entry) => matchesAcceptEntry(file, entry))\n}\n\n/** Input of {@link validateFiles}. */\nexport interface ValidateFilesInput {\n /** Files the user picked. */\n files: File[]\n\n /** Media types the conversation accepts. */\n allowedMediaTypes: WhatsAppMediaType[]\n\n /** Per media type constraints from the conversation capabilities. */\n constraints?: Partial<Record<WhatsAppMediaType, WhatsAppMediaConstraints>>\n\n /** Attachments already staged in the composer, counted against `maxFiles`. */\n existingCount?: number\n\n /** Labels used to build the rejection messages. */\n labels?: WhatsAppInboxLabels\n}\n\n/** Files split into the ones the composer forwards and the ones it refused. */\nexport interface ValidateFilesResult {\n accepted: File[]\n rejected: WhatsAppRejectedFile[]\n}\n\n/**\n * Applies the configured file constraints before any file reaches the consumer.\n *\n * This is the only validation the extension performs on media, and every limit comes from\n * `capabilities` rather than from a hard-coded provider table.\n */\nexport function validateFiles({\n files,\n allowedMediaTypes,\n constraints = {},\n existingCount = 0,\n labels = DEFAULT_WHATSAPP_INBOX_LABELS,\n}: ValidateFilesInput): ValidateFilesResult {\n const accepted: File[] = []\n const rejected: WhatsAppRejectedFile[] = []\n\n for (const file of files) {\n const mediaType = getMediaTypeFromMime(file.type)\n const isAllowedType = allowedMediaTypes.includes(mediaType)\n const constraint = constraints[mediaType]\n\n if (!isAllowedType || !matchesAccept(file, constraint?.accept)) {\n rejected.push({\n file,\n code: 'file-invalid-type',\n message: labels.fileInvalidType(file.name),\n })\n continue\n }\n\n if (constraint?.maxFileSize !== undefined && file.size > constraint.maxFileSize) {\n rejected.push({\n file,\n code: 'file-too-large',\n message: labels.fileTooLarge(file.name, formatFileSize(constraint.maxFileSize)),\n })\n continue\n }\n\n const maxFiles = constraint?.maxFiles\n\n if (maxFiles !== undefined && existingCount + accepted.length >= maxFiles) {\n rejected.push({\n file,\n code: 'too-many-files',\n message: labels.tooManyFiles(maxFiles),\n })\n continue\n }\n\n accepted.push(file)\n }\n\n return { accepted, rejected }\n}\n","/**\n * Emoji dataset for the built-in picker.\n *\n * This curated subset limits bundle size. Entries are stored as tuples and expanded at module\n * load.\n *\n * Use the `emojiPicker` slot for a complete catalogue, skin-tone variants, or localized names.\n */\n\n/** Category an emoji belongs to. Mirrors the tabs WhatsApp shows. */\nexport type WhatsAppEmojiGroupId =\n | 'recent'\n | 'smileys'\n | 'people'\n | 'animals'\n | 'food'\n | 'activity'\n | 'travel'\n | 'objects'\n | 'symbols'\n | 'flags'\n\n/** One entry of the dataset. */\nexport interface WhatsAppEmoji {\n /** Character inserted into the composer. */\n emoji: string\n\n /** Short name, used as the accessible name, the tooltip and the primary search term. */\n name: string\n\n /** Extra words the search matches on. */\n keywords: string[]\n\n /** Category the emoji is listed under. */\n group: WhatsAppEmojiGroupId\n}\n\n/** `[emoji, name, space separated keywords]`. */\ntype EmojiTuple = readonly [string, string, string?]\n\nconst SMILEYS: EmojiTuple[] = [\n ['😀', 'grinning face', 'smile happy joy'],\n ['😃', 'grinning face with big eyes', 'smile happy joy excited'],\n ['😄', 'grinning face with smiling eyes', 'smile happy laugh'],\n ['😁', 'beaming face with smiling eyes', 'grin smile'],\n ['😆', 'grinning squinting face', 'laugh haha satisfied'],\n ['😅', 'grinning face with sweat', 'laugh relief phew'],\n ['🤣', 'rolling on the floor laughing', 'rofl lol laugh'],\n ['😂', 'face with tears of joy', 'lol laugh cry funny'],\n ['🙂', 'slightly smiling face', 'smile'],\n ['🙃', 'upside down face', 'silly sarcasm'],\n ['😉', 'winking face', 'wink flirt'],\n ['😊', 'smiling face with smiling eyes', 'blush happy warm'],\n ['😇', 'smiling face with halo', 'angel innocent'],\n ['🥰', 'smiling face with hearts', 'love adore crush'],\n ['😍', 'smiling face with heart eyes', 'love crush'],\n ['🤩', 'star struck', 'starry eyes amazed excited'],\n ['😘', 'face blowing a kiss', 'kiss love'],\n ['😗', 'kissing face', 'kiss'],\n ['😚', 'kissing face with closed eyes', 'kiss'],\n ['😙', 'kissing face with smiling eyes', 'kiss'],\n ['😋', 'face savoring food', 'yum tasty delicious'],\n ['😛', 'face with tongue', 'tongue silly'],\n ['😜', 'winking face with tongue', 'tongue joke silly'],\n ['🤪', 'zany face', 'crazy goofy wild'],\n ['😝', 'squinting face with tongue', 'tongue prank'],\n ['🤑', 'money mouth face', 'rich dollar greedy'],\n ['🤗', 'hugging face', 'hug thanks'],\n ['🤭', 'face with hand over mouth', 'oops giggle whoops'],\n ['🤫', 'shushing face', 'quiet silence secret'],\n ['🤔', 'thinking face', 'hmm think consider'],\n ['🤐', 'zipper mouth face', 'quiet secret'],\n ['🤨', 'face with raised eyebrow', 'skeptic suspicious doubt'],\n ['😐', 'neutral face', 'meh blank'],\n ['😑', 'expressionless face', 'blank done'],\n ['😶', 'face without mouth', 'silent speechless'],\n ['😏', 'smirking face', 'smug flirt'],\n ['😒', 'unamused face', 'meh annoyed'],\n ['🙄', 'face with rolling eyes', 'eyeroll whatever'],\n ['😬', 'grimacing face', 'awkward eek'],\n ['🤥', 'lying face', 'liar pinocchio'],\n ['😌', 'relieved face', 'calm content'],\n ['😔', 'pensive face', 'sad dejected'],\n ['😪', 'sleepy face', 'tired'],\n ['🤤', 'drooling face', 'hungry want'],\n ['😴', 'sleeping face', 'sleep zzz tired'],\n ['😷', 'face with medical mask', 'sick mask ill'],\n ['🤒', 'face with thermometer', 'sick fever ill'],\n ['🤕', 'face with head bandage', 'hurt injured'],\n ['🤢', 'nauseated face', 'sick gross'],\n ['🤮', 'face vomiting', 'sick puke'],\n ['🤧', 'sneezing face', 'sick cold'],\n ['🥵', 'hot face', 'heat sweating'],\n ['🥶', 'cold face', 'freezing ice'],\n ['🥴', 'woozy face', 'dizzy tipsy'],\n ['😵', 'dizzy face', 'knocked out'],\n ['🤯', 'exploding head', 'mind blown shocked'],\n ['🤠', 'cowboy hat face', 'cowboy'],\n ['🥳', 'partying face', 'party celebrate birthday'],\n ['😎', 'smiling face with sunglasses', 'cool sunglasses'],\n ['🤓', 'nerd face', 'geek glasses'],\n ['🧐', 'face with monocle', 'inspect posh'],\n ['😕', 'confused face', 'unsure'],\n ['😟', 'worried face', 'concern'],\n ['🙁', 'slightly frowning face', 'sad'],\n ['😮', 'face with open mouth', 'surprise wow'],\n ['😯', 'hushed face', 'surprise'],\n ['😲', 'astonished face', 'shocked gasp'],\n ['😳', 'flushed face', 'embarrassed blush'],\n ['🥺', 'pleading face', 'begging puppy eyes'],\n ['😦', 'frowning face with open mouth', 'sad'],\n ['😨', 'fearful face', 'scared'],\n ['😰', 'anxious face with sweat', 'nervous'],\n ['😥', 'sad but relieved face', 'phew'],\n ['😢', 'crying face', 'sad tear'],\n ['😭', 'loudly crying face', 'sob cry sad'],\n ['😱', 'face screaming in fear', 'scream shocked'],\n ['😖', 'confounded face', 'frustrated'],\n ['😣', 'persevering face', 'struggling'],\n ['😞', 'disappointed face', 'sad'],\n ['😓', 'downcast face with sweat', 'tired sad'],\n ['😩', 'weary face', 'tired frustrated'],\n ['😫', 'tired face', 'exhausted'],\n ['🥱', 'yawning face', 'tired bored'],\n ['😤', 'face with steam from nose', 'triumph determined'],\n ['😡', 'enraged face', 'angry mad furious'],\n ['😠', 'angry face', 'mad'],\n ['🤬', 'face with symbols on mouth', 'swearing cursing'],\n ['😈', 'smiling face with horns', 'devil mischief'],\n ['💀', 'skull', 'dead'],\n ['💩', 'pile of poo', 'poop'],\n ['🤡', 'clown face', 'clown'],\n ['👻', 'ghost', 'halloween boo'],\n ['👽', 'alien', 'ufo space'],\n ['🤖', 'robot', 'bot machine'],\n ['😺', 'grinning cat', 'cat happy'],\n ['😸', 'grinning cat with smiling eyes', 'cat'],\n ['😹', 'cat with tears of joy', 'cat laugh'],\n ['😻', 'smiling cat with heart eyes', 'cat love'],\n ['😽', 'kissing cat', 'cat kiss'],\n ['🙀', 'weary cat', 'cat shocked'],\n ['😿', 'crying cat', 'cat sad'],\n ['😾', 'pouting cat', 'cat grumpy'],\n]\n\nconst PEOPLE: EmojiTuple[] = [\n ['👋', 'waving hand', 'hello bye wave'],\n ['🤚', 'raised back of hand', 'hand'],\n ['🖐️', 'hand with fingers splayed', 'hand five'],\n ['✋', 'raised hand', 'stop high five'],\n ['🖖', 'vulcan salute', 'spock'],\n ['👌', 'ok hand', 'ok perfect'],\n ['🤌', 'pinched fingers', 'italian'],\n ['🤏', 'pinching hand', 'small little'],\n ['✌️', 'victory hand', 'peace two'],\n ['🤞', 'crossed fingers', 'luck hopeful'],\n ['🤟', 'love you gesture', 'ily'],\n ['🤘', 'sign of the horns', 'rock'],\n ['🤙', 'call me hand', 'shaka hang loose'],\n ['👈', 'backhand index pointing left', 'point left'],\n ['👉', 'backhand index pointing right', 'point right'],\n ['👆', 'backhand index pointing up', 'point up'],\n ['👇', 'backhand index pointing down', 'point down'],\n ['☝️', 'index pointing up', 'point one'],\n ['👍', 'thumbs up', 'like yes approve ok'],\n ['👎', 'thumbs down', 'dislike no'],\n ['✊', 'raised fist', 'power solidarity'],\n ['👊', 'oncoming fist', 'punch bump'],\n ['🤛', 'left facing fist', 'bump'],\n ['🤜', 'right facing fist', 'bump'],\n ['👏', 'clapping hands', 'applause bravo'],\n ['🙌', 'raising hands', 'celebrate praise hooray'],\n ['👐', 'open hands', 'hug'],\n ['🤲', 'palms up together', 'pray dua'],\n ['🤝', 'handshake', 'deal agreement'],\n ['🙏', 'folded hands', 'please thanks pray'],\n ['✍️', 'writing hand', 'write sign'],\n ['💅', 'nail polish', 'manicure'],\n ['💪', 'flexed biceps', 'strong muscle'],\n ['🦾', 'mechanical arm', 'prosthetic'],\n ['🦵', 'leg', 'kick'],\n ['🦶', 'foot', 'stomp'],\n ['👂', 'ear', 'listen'],\n ['👃', 'nose', 'smell'],\n ['🧠', 'brain', 'smart think'],\n ['🦷', 'tooth', 'dentist'],\n ['👀', 'eyes', 'look see watch'],\n ['👁️', 'eye', 'look'],\n ['👅', 'tongue', 'taste'],\n ['👄', 'mouth', 'lips kiss'],\n ['👶', 'baby', 'infant child'],\n ['🧒', 'child', 'kid'],\n ['👦', 'boy', 'child'],\n ['👧', 'girl', 'child'],\n ['🧑', 'person', 'adult'],\n ['👨', 'man', 'adult'],\n ['👩', 'woman', 'adult'],\n ['🧓', 'older person', 'elderly'],\n ['👴', 'old man', 'elderly grandfather'],\n ['👵', 'old woman', 'elderly grandmother'],\n ['🙍', 'person frowning', 'sad'],\n ['🙎', 'person pouting', 'grumpy'],\n ['🙅', 'person gesturing no', 'no stop'],\n ['🙆', 'person gesturing ok', 'ok yes'],\n ['💁', 'person tipping hand', 'sassy information'],\n ['🙋', 'person raising hand', 'question volunteer'],\n ['🧏', 'deaf person', 'accessibility'],\n ['🙇', 'person bowing', 'sorry respect'],\n ['🤦', 'person facepalming', 'facepalm disbelief'],\n ['🤷', 'person shrugging', 'shrug dunno'],\n ['👮', 'police officer', 'cop'],\n ['🕵️', 'detective', 'spy investigate'],\n ['💂', 'guard', 'soldier'],\n ['👷', 'construction worker', 'builder'],\n ['🤴', 'prince', 'royalty'],\n ['👸', 'princess', 'royalty'],\n ['👳', 'person wearing turban', 'turban'],\n ['🧕', 'woman with headscarf', 'hijab'],\n ['👰', 'person with veil', 'bride wedding'],\n ['🤰', 'pregnant woman', 'pregnancy'],\n ['🎅', 'santa claus', 'christmas'],\n ['🦸', 'superhero', 'hero'],\n ['🦹', 'supervillain', 'villain'],\n ['🧙', 'mage', 'wizard magic'],\n ['🧚', 'fairy', 'magic'],\n ['🧛', 'vampire', 'dracula'],\n ['🧜', 'merperson', 'mermaid'],\n ['🧟', 'zombie', 'undead'],\n ['💆', 'person getting massage', 'spa relax'],\n ['💇', 'person getting haircut', 'salon'],\n ['🚶', 'person walking', 'walk'],\n ['🏃', 'person running', 'run exercise'],\n ['💃', 'woman dancing', 'dance'],\n ['🕺', 'man dancing', 'dance'],\n ['👪', 'family', 'parents children'],\n ['🗣️', 'speaking head', 'talk say'],\n ['👤', 'bust in silhouette', 'user person'],\n ['👥', 'busts in silhouette', 'users group'],\n]\n\nconst ANIMALS: EmojiTuple[] = [\n ['🐶', 'dog face', 'puppy pet'],\n ['🐱', 'cat face', 'kitten pet'],\n ['🐭', 'mouse face', 'rodent'],\n ['🐹', 'hamster', 'pet'],\n ['🐰', 'rabbit face', 'bunny'],\n ['🦊', 'fox', 'animal'],\n ['🐻', 'bear', 'animal'],\n ['🐼', 'panda', 'bear'],\n ['🐨', 'koala', 'australia'],\n ['🐯', 'tiger face', 'animal'],\n ['🦁', 'lion', 'animal king'],\n ['🐮', 'cow face', 'farm'],\n ['🐷', 'pig face', 'farm'],\n ['🐸', 'frog', 'animal'],\n ['🐵', 'monkey face', 'animal'],\n ['🙈', 'see no evil monkey', 'monkey hide'],\n ['🙉', 'hear no evil monkey', 'monkey'],\n ['🙊', 'speak no evil monkey', 'monkey quiet'],\n ['🐒', 'monkey', 'animal'],\n ['🐔', 'chicken', 'farm'],\n ['🐧', 'penguin', 'bird cold'],\n ['🐦', 'bird', 'animal'],\n ['🐤', 'baby chick', 'bird'],\n ['🦆', 'duck', 'bird'],\n ['🦅', 'eagle', 'bird'],\n ['🦉', 'owl', 'bird night'],\n ['🦇', 'bat', 'halloween'],\n ['🐺', 'wolf', 'animal'],\n ['🐗', 'boar', 'animal'],\n ['🐴', 'horse face', 'animal'],\n ['🦄', 'unicorn', 'magic'],\n ['🐝', 'honeybee', 'bee insect'],\n ['🐛', 'bug', 'insect caterpillar'],\n ['🦋', 'butterfly', 'insect'],\n ['🐌', 'snail', 'slow'],\n ['🐞', 'lady beetle', 'ladybug insect'],\n ['🐜', 'ant', 'insect'],\n ['🕷️', 'spider', 'insect halloween'],\n ['🦂', 'scorpion', 'insect'],\n ['🐢', 'turtle', 'slow'],\n ['🐍', 'snake', 'animal'],\n ['🦎', 'lizard', 'reptile'],\n ['🦖', 't rex', 'dinosaur'],\n ['🐙', 'octopus', 'sea'],\n ['🦑', 'squid', 'sea'],\n ['🦐', 'shrimp', 'sea food'],\n ['🦀', 'crab', 'sea'],\n ['🐡', 'blowfish', 'fish sea'],\n ['🐠', 'tropical fish', 'sea'],\n ['🐟', 'fish', 'sea'],\n ['🐬', 'dolphin', 'sea'],\n ['🐳', 'spouting whale', 'sea'],\n ['🦈', 'shark', 'sea'],\n ['🐊', 'crocodile', 'reptile'],\n ['🐅', 'tiger', 'animal'],\n ['🦓', 'zebra', 'animal'],\n ['🦍', 'gorilla', 'ape'],\n ['🐘', 'elephant', 'animal'],\n ['🦏', 'rhinoceros', 'animal'],\n ['🐪', 'camel', 'desert'],\n ['🦒', 'giraffe', 'animal'],\n ['🐄', 'cow', 'farm'],\n ['🐖', 'pig', 'farm'],\n ['🐑', 'ewe', 'sheep farm'],\n ['🐐', 'goat', 'farm'],\n ['🐕', 'dog', 'pet'],\n ['🐈', 'cat', 'pet'],\n ['🐓', 'rooster', 'farm'],\n ['🦃', 'turkey', 'thanksgiving'],\n ['🕊️', 'dove', 'peace bird'],\n ['🐇', 'rabbit', 'bunny'],\n ['🐿️', 'chipmunk', 'squirrel'],\n ['🦔', 'hedgehog', 'animal'],\n ['🐾', 'paw prints', 'animal tracks'],\n ['🌵', 'cactus', 'plant desert'],\n ['🎄', 'christmas tree', 'holiday'],\n ['🌲', 'evergreen tree', 'forest'],\n ['🌳', 'deciduous tree', 'forest'],\n ['🌴', 'palm tree', 'beach tropical'],\n ['🌱', 'seedling', 'plant grow'],\n ['🌿', 'herb', 'plant leaf'],\n ['☘️', 'shamrock', 'clover irish'],\n ['🍀', 'four leaf clover', 'luck'],\n ['🍁', 'maple leaf', 'autumn canada'],\n ['🍂', 'fallen leaf', 'autumn'],\n ['🍃', 'leaf fluttering in wind', 'wind leaf'],\n ['🌺', 'hibiscus', 'flower'],\n ['🌻', 'sunflower', 'flower'],\n ['🌹', 'rose', 'flower love'],\n ['🥀', 'wilted flower', 'flower sad'],\n ['🌷', 'tulip', 'flower'],\n ['🌸', 'cherry blossom', 'flower sakura'],\n ['💐', 'bouquet', 'flowers gift'],\n ['🍄', 'mushroom', 'fungus'],\n ['🌍', 'globe showing europe africa', 'earth world'],\n ['🌙', 'crescent moon', 'night'],\n ['⭐', 'star', 'night favourite'],\n ['🌟', 'glowing star', 'sparkle'],\n ['☀️', 'sun', 'sunny weather'],\n ['⛅', 'sun behind cloud', 'weather'],\n ['☁️', 'cloud', 'weather'],\n ['🌧️', 'cloud with rain', 'weather rain'],\n ['⛈️', 'cloud with lightning and rain', 'storm'],\n ['❄️', 'snowflake', 'cold winter'],\n ['⛄', 'snowman without snow', 'winter'],\n ['🔥', 'fire', 'hot lit flame'],\n ['💧', 'droplet', 'water'],\n ['🌊', 'water wave', 'sea ocean'],\n ['🌈', 'rainbow', 'pride weather'],\n]\n\nconst FOOD: EmojiTuple[] = [\n ['🍏', 'green apple', 'fruit'],\n ['🍎', 'red apple', 'fruit'],\n ['🍐', 'pear', 'fruit'],\n ['🍊', 'tangerine', 'orange fruit'],\n ['🍋', 'lemon', 'fruit sour'],\n ['🍌', 'banana', 'fruit'],\n ['🍉', 'watermelon', 'fruit summer'],\n ['🍇', 'grapes', 'fruit'],\n ['🍓', 'strawberry', 'fruit'],\n ['🫐', 'blueberries', 'fruit'],\n ['🍈', 'melon', 'fruit'],\n ['🍒', 'cherries', 'fruit'],\n ['🍑', 'peach', 'fruit'],\n ['🥭', 'mango', 'fruit tropical'],\n ['🍍', 'pineapple', 'fruit tropical'],\n ['🥥', 'coconut', 'fruit tropical'],\n ['🥝', 'kiwi fruit', 'fruit'],\n ['🍅', 'tomato', 'vegetable'],\n ['🍆', 'eggplant', 'aubergine vegetable'],\n ['🥑', 'avocado', 'fruit'],\n ['🥦', 'broccoli', 'vegetable'],\n ['🥬', 'leafy green', 'vegetable salad'],\n ['🥒', 'cucumber', 'vegetable'],\n ['🌶️', 'hot pepper', 'spicy chilli'],\n ['🌽', 'ear of corn', 'vegetable'],\n ['🥕', 'carrot', 'vegetable'],\n ['🧄', 'garlic', 'vegetable'],\n ['🧅', 'onion', 'vegetable'],\n ['🥔', 'potato', 'vegetable'],\n ['🍠', 'roasted sweet potato', 'vegetable'],\n ['🥐', 'croissant', 'bread breakfast'],\n ['🥯', 'bagel', 'bread'],\n ['🍞', 'bread', 'loaf'],\n ['🥖', 'baguette bread', 'french bread'],\n ['🧀', 'cheese wedge', 'cheese'],\n ['🥚', 'egg', 'breakfast'],\n ['🍳', 'cooking', 'egg fried breakfast'],\n ['🧈', 'butter', 'dairy'],\n ['🥞', 'pancakes', 'breakfast'],\n ['🧇', 'waffle', 'breakfast'],\n ['🥓', 'bacon', 'breakfast meat'],\n ['🍔', 'hamburger', 'burger fast food'],\n ['🍟', 'french fries', 'chips fast food'],\n ['🍕', 'pizza', 'slice'],\n ['🌭', 'hot dog', 'fast food'],\n ['🥪', 'sandwich', 'lunch'],\n ['🌮', 'taco', 'mexican'],\n ['🌯', 'burrito', 'mexican wrap'],\n ['🥙', 'stuffed flatbread', 'kebab shawarma'],\n ['🧆', 'falafel', 'middle eastern'],\n ['🥗', 'green salad', 'healthy'],\n ['🥘', 'shallow pan of food', 'paella cooking'],\n ['🍝', 'spaghetti', 'pasta italian'],\n ['🍜', 'steaming bowl', 'ramen noodles'],\n ['🍲', 'pot of food', 'stew soup'],\n ['🍛', 'curry rice', 'curry'],\n ['🍣', 'sushi', 'japanese'],\n ['🍤', 'fried shrimp', 'tempura'],\n ['🍚', 'cooked rice', 'rice'],\n ['🥟', 'dumpling', 'gyoza'],\n ['🍿', 'popcorn', 'cinema snack'],\n ['🧂', 'salt', 'seasoning'],\n ['🥫', 'canned food', 'tin'],\n ['🍦', 'soft ice cream', 'dessert'],\n ['🍩', 'doughnut', 'donut dessert'],\n ['🍪', 'cookie', 'biscuit dessert'],\n ['🎂', 'birthday cake', 'birthday celebrate'],\n ['🍰', 'shortcake', 'cake dessert'],\n ['🧁', 'cupcake', 'dessert'],\n ['🥧', 'pie', 'dessert'],\n ['🍫', 'chocolate bar', 'sweet'],\n ['🍬', 'candy', 'sweet'],\n ['🍭', 'lollipop', 'sweet'],\n ['🍯', 'honey pot', 'honey sweet'],\n ['🍼', 'baby bottle', 'milk baby'],\n ['🥛', 'glass of milk', 'dairy'],\n ['☕', 'hot beverage', 'coffee tea'],\n ['🫖', 'teapot', 'tea'],\n ['🍵', 'teacup without handle', 'green tea'],\n ['🧃', 'beverage box', 'juice'],\n ['🥤', 'cup with straw', 'soda drink'],\n ['🧋', 'bubble tea', 'boba'],\n ['🍺', 'beer mug', 'beer drink'],\n ['🍻', 'clinking beer mugs', 'cheers beer'],\n ['🥂', 'clinking glasses', 'cheers celebrate'],\n ['🍷', 'wine glass', 'wine'],\n ['🥃', 'tumbler glass', 'whisky'],\n ['🍸', 'cocktail glass', 'martini'],\n ['🍹', 'tropical drink', 'cocktail'],\n ['🧊', 'ice', 'cold cube'],\n ['🍽️', 'fork and knife with plate', 'dinner eat'],\n ['🥄', 'spoon', 'cutlery'],\n]\n\nconst ACTIVITY: EmojiTuple[] = [\n ['⚽', 'soccer ball', 'football sport'],\n ['🏀', 'basketball', 'sport'],\n ['🏈', 'american football', 'sport'],\n ['⚾', 'baseball', 'sport'],\n ['🥎', 'softball', 'sport'],\n ['🎾', 'tennis', 'sport'],\n ['🏐', 'volleyball', 'sport'],\n ['🏉', 'rugby football', 'sport'],\n ['🥏', 'flying disc', 'frisbee'],\n ['🎱', 'pool 8 ball', 'billiards'],\n ['🏓', 'ping pong', 'table tennis'],\n ['🏸', 'badminton', 'sport'],\n ['🥅', 'goal net', 'sport'],\n ['🏒', 'ice hockey', 'sport'],\n ['🏑', 'field hockey', 'sport'],\n ['🥍', 'lacrosse', 'sport'],\n ['🏏', 'cricket game', 'sport'],\n ['🥊', 'boxing glove', 'boxing sport'],\n ['🥋', 'martial arts uniform', 'judo karate'],\n ['⛳', 'flag in hole', 'golf'],\n ['⛸️', 'ice skate', 'skating'],\n ['🎣', 'fishing pole', 'fishing'],\n ['🤿', 'diving mask', 'diving snorkel'],\n ['🎽', 'running shirt', 'marathon'],\n ['🎿', 'skis', 'skiing winter'],\n ['🛷', 'sled', 'winter'],\n ['🥌', 'curling stone', 'winter sport'],\n ['🏆', 'trophy', 'win award champion'],\n ['🥇', 'first place medal', 'gold win'],\n ['🥈', 'second place medal', 'silver'],\n ['🥉', 'third place medal', 'bronze'],\n ['🏅', 'sports medal', 'award'],\n ['🎖️', 'military medal', 'award'],\n ['🎯', 'bullseye', 'target darts goal'],\n ['🎮', 'video game', 'gaming controller'],\n ['🕹️', 'joystick', 'gaming'],\n ['🎲', 'game die', 'dice random'],\n ['♟️', 'chess pawn', 'chess'],\n ['🧩', 'puzzle piece', 'jigsaw'],\n ['🎰', 'slot machine', 'gambling'],\n ['🎳', 'bowling', 'sport'],\n ['🎪', 'circus tent', 'circus'],\n ['🎭', 'performing arts', 'theatre drama'],\n ['🎨', 'artist palette', 'art paint'],\n ['🎤', 'microphone', 'sing karaoke'],\n ['🎧', 'headphone', 'music listen'],\n ['🎼', 'musical score', 'music'],\n ['🎵', 'musical note', 'music'],\n ['🎶', 'musical notes', 'music'],\n ['🎹', 'musical keyboard', 'piano'],\n ['🥁', 'drum', 'music'],\n ['🎷', 'saxophone', 'music jazz'],\n ['🎺', 'trumpet', 'music'],\n ['🎸', 'guitar', 'music rock'],\n ['🎻', 'violin', 'music'],\n ['🎬', 'clapper board', 'film movie'],\n ['🎫', 'ticket', 'event'],\n ['🎗️', 'reminder ribbon', 'awareness'],\n ['🎉', 'party popper', 'celebrate congrats'],\n ['🎊', 'confetti ball', 'celebrate party'],\n ['🎈', 'balloon', 'party birthday'],\n ['🎁', 'wrapped gift', 'present birthday'],\n ['🎃', 'jack o lantern', 'halloween pumpkin'],\n ['🧨', 'firecracker', 'fireworks'],\n ['✨', 'sparkles', 'shiny clean magic'],\n ['🎇', 'sparkler', 'fireworks'],\n ['🎆', 'fireworks', 'celebrate'],\n]\n\nconst TRAVEL: EmojiTuple[] = [\n ['🚗', 'automobile', 'car drive'],\n ['🚕', 'taxi', 'cab'],\n ['🚙', 'sport utility vehicle', 'suv car'],\n ['🚌', 'bus', 'transport'],\n ['🚎', 'trolleybus', 'transport'],\n ['🏎️', 'racing car', 'formula one'],\n ['🚓', 'police car', 'police'],\n ['🚑', 'ambulance', 'emergency'],\n ['🚒', 'fire engine', 'emergency'],\n ['🚐', 'minibus', 'van'],\n ['🚚', 'delivery truck', 'shipping'],\n ['🚛', 'articulated lorry', 'truck'],\n ['🚜', 'tractor', 'farm'],\n ['🛵', 'motor scooter', 'vespa'],\n ['🏍️', 'motorcycle', 'bike'],\n ['🚲', 'bicycle', 'bike cycling'],\n ['🛴', 'kick scooter', 'scooter'],\n ['🚨', 'police car light', 'siren emergency'],\n ['🚔', 'oncoming police car', 'police'],\n ['🚍', 'oncoming bus', 'transport'],\n ['🚖', 'oncoming taxi', 'cab'],\n ['🚡', 'aerial tramway', 'cable car'],\n ['🚠', 'mountain cableway', 'cable car'],\n ['🚟', 'suspension railway', 'transport'],\n ['🚃', 'railway car', 'train'],\n ['🚋', 'tram car', 'tram'],\n ['🚞', 'mountain railway', 'train'],\n ['🚝', 'monorail', 'train'],\n ['🚄', 'high speed train', 'bullet train'],\n ['🚅', 'bullet train', 'shinkansen'],\n ['🚈', 'light rail', 'train'],\n ['🚂', 'locomotive', 'steam train'],\n ['🚆', 'train', 'transport'],\n ['🚇', 'metro', 'subway underground'],\n ['🚊', 'tram', 'transport'],\n ['🚉', 'station', 'train'],\n ['✈️', 'airplane', 'flight travel'],\n ['🛫', 'airplane departure', 'takeoff'],\n ['🛬', 'airplane arrival', 'landing'],\n ['🛩️', 'small airplane', 'flight'],\n ['💺', 'seat', 'flight'],\n ['🚁', 'helicopter', 'flight'],\n ['🚀', 'rocket', 'launch space startup'],\n ['🛸', 'flying saucer', 'ufo alien'],\n ['⛵', 'sailboat', 'sailing sea'],\n ['🚤', 'speedboat', 'boat'],\n ['🛥️', 'motor boat', 'boat'],\n ['🛳️', 'passenger ship', 'cruise'],\n ['⚓', 'anchor', 'ship'],\n ['⛽', 'fuel pump', 'petrol gas'],\n ['🚧', 'construction', 'roadworks'],\n ['🚦', 'vertical traffic light', 'traffic'],\n ['🚥', 'horizontal traffic light', 'traffic'],\n ['🗺️', 'world map', 'travel'],\n ['🗿', 'moai', 'statue'],\n ['🗽', 'statue of liberty', 'new york'],\n ['🗼', 'tokyo tower', 'japan'],\n ['🏰', 'castle', 'fairytale'],\n ['🏯', 'japanese castle', 'japan'],\n ['🏟️', 'stadium', 'sport'],\n ['🎡', 'ferris wheel', 'fair'],\n ['🎢', 'roller coaster', 'theme park'],\n ['🎠', 'carousel horse', 'fair'],\n ['⛲', 'fountain', 'park'],\n ['⛱️', 'umbrella on ground', 'beach'],\n ['🏖️', 'beach with umbrella', 'holiday'],\n ['🏝️', 'desert island', 'holiday'],\n ['🏔️', 'snow capped mountain', 'mountain'],\n ['⛰️', 'mountain', 'hiking'],\n ['🌋', 'volcano', 'eruption'],\n ['🏕️', 'camping', 'tent outdoors'],\n ['🏠', 'house', 'home'],\n ['🏡', 'house with garden', 'home'],\n ['🏢', 'office building', 'work'],\n ['🏥', 'hospital', 'health'],\n ['🏦', 'bank', 'money'],\n ['🏨', 'hotel', 'travel'],\n ['🏪', 'convenience store', 'shop'],\n ['🏫', 'school', 'education'],\n ['🕌', 'mosque', 'islam'],\n ['🕍', 'synagogue', 'judaism'],\n ['⛪', 'church', 'christianity'],\n ['🕋', 'kaaba', 'mecca islam'],\n ['🌃', 'night with stars', 'city night'],\n ['🌆', 'cityscape at dusk', 'city'],\n ['🌇', 'sunset', 'city evening'],\n ['🌉', 'bridge at night', 'city'],\n ['🎑', 'moon viewing ceremony', 'japan'],\n]\n\nconst OBJECTS: EmojiTuple[] = [\n ['⌚', 'watch', 'time'],\n ['📱', 'mobile phone', 'smartphone'],\n ['💻', 'laptop', 'computer work'],\n ['⌨️', 'keyboard', 'typing'],\n ['🖥️', 'desktop computer', 'pc'],\n ['🖨️', 'printer', 'print'],\n ['🖱️', 'computer mouse', 'click'],\n ['💽', 'computer disk', 'storage'],\n ['💾', 'floppy disk', 'save'],\n ['💿', 'optical disk', 'cd'],\n ['📀', 'dvd', 'disc'],\n ['📷', 'camera', 'photo'],\n ['📸', 'camera with flash', 'photo'],\n ['📹', 'video camera', 'record'],\n ['🎥', 'movie camera', 'film'],\n ['📞', 'telephone receiver', 'call phone'],\n ['☎️', 'telephone', 'call'],\n ['📟', 'pager', 'beeper'],\n ['📠', 'fax machine', 'fax'],\n ['📺', 'television', 'tv'],\n ['📻', 'radio', 'music'],\n ['🔋', 'battery', 'power'],\n ['🔌', 'electric plug', 'power'],\n ['💡', 'light bulb', 'idea'],\n ['🔦', 'flashlight', 'torch'],\n ['🕯️', 'candle', 'light'],\n ['🧯', 'fire extinguisher', 'safety'],\n ['🛢️', 'oil drum', 'barrel'],\n ['💸', 'money with wings', 'spending'],\n ['💵', 'dollar banknote', 'money cash'],\n ['💴', 'yen banknote', 'money'],\n ['💶', 'euro banknote', 'money'],\n ['💷', 'pound banknote', 'money'],\n ['💰', 'money bag', 'money rich'],\n ['💳', 'credit card', 'payment'],\n ['🧾', 'receipt', 'invoice bill'],\n ['💎', 'gem stone', 'diamond'],\n ['⚖️', 'balance scale', 'justice legal'],\n ['🧰', 'toolbox', 'tools'],\n ['🔧', 'wrench', 'tool fix'],\n ['🔨', 'hammer', 'tool build'],\n ['🪛', 'screwdriver', 'tool'],\n ['🔩', 'nut and bolt', 'tool'],\n ['⚙️', 'gear', 'settings cog'],\n ['🧲', 'magnet', 'attract'],\n ['🔫', 'water pistol', 'gun toy'],\n ['💣', 'bomb', 'explosive'],\n ['🔪', 'kitchen knife', 'cut'],\n ['🗡️', 'dagger', 'blade'],\n ['🛡️', 'shield', 'protection security'],\n ['🚬', 'cigarette', 'smoking'],\n ['⚰️', 'coffin', 'death'],\n ['🔮', 'crystal ball', 'fortune magic'],\n ['📿', 'prayer beads', 'religion'],\n ['💈', 'barber pole', 'haircut'],\n ['🔭', 'telescope', 'space'],\n ['🔬', 'microscope', 'science lab'],\n ['🧪', 'test tube', 'science'],\n ['🧬', 'dna', 'biology'],\n ['💊', 'pill', 'medicine'],\n ['💉', 'syringe', 'vaccine injection'],\n ['🩹', 'adhesive bandage', 'plaster'],\n ['🩺', 'stethoscope', 'doctor'],\n ['🚪', 'door', 'entry'],\n ['🪑', 'chair', 'seat'],\n ['🛏️', 'bed', 'sleep'],\n ['🚿', 'shower', 'bathroom'],\n ['🛁', 'bathtub', 'bathroom'],\n ['🧴', 'lotion bottle', 'soap'],\n ['🧼', 'soap', 'wash'],\n ['🧹', 'broom', 'clean'],\n ['🧺', 'basket', 'laundry'],\n ['🔑', 'key', 'unlock'],\n ['🔒', 'locked', 'secure privacy'],\n ['🔓', 'unlocked', 'open'],\n ['🔔', 'bell', 'notification alert'],\n ['🔕', 'bell with slash', 'mute silence'],\n ['📢', 'loudspeaker', 'announcement'],\n ['📣', 'megaphone', 'shout'],\n ['📯', 'postal horn', 'announce'],\n ['📌', 'pushpin', 'pin location'],\n ['📎', 'paperclip', 'attachment'],\n ['✂️', 'scissors', 'cut'],\n ['📝', 'memo', 'note write'],\n ['✏️', 'pencil', 'write edit'],\n ['🖊️', 'pen', 'write'],\n ['📖', 'open book', 'read'],\n ['📚', 'books', 'library read'],\n ['📓', 'notebook', 'notes'],\n ['📋', 'clipboard', 'list'],\n ['📅', 'calendar', 'date schedule'],\n ['📆', 'tear off calendar', 'date'],\n ['🗓️', 'spiral calendar', 'schedule'],\n ['📈', 'chart increasing', 'growth stats'],\n ['📉', 'chart decreasing', 'loss stats'],\n ['📊', 'bar chart', 'stats analytics'],\n ['🗂️', 'card index dividers', 'files'],\n ['📁', 'file folder', 'folder'],\n ['📂', 'open file folder', 'folder'],\n ['🗃️', 'card file box', 'archive'],\n ['🗄️', 'file cabinet', 'archive'],\n ['🗑️', 'wastebasket', 'delete trash'],\n ['📦', 'package', 'box shipping'],\n ['📫', 'closed mailbox with raised flag', 'mail'],\n ['📮', 'postbox', 'mail'],\n ['✉️', 'envelope', 'email mail'],\n ['📧', 'e mail', 'email'],\n ['📨', 'incoming envelope', 'mail'],\n ['📤', 'outbox tray', 'send'],\n ['📥', 'inbox tray', 'receive'],\n ['🔍', 'magnifying glass tilted left', 'search find'],\n ['🔎', 'magnifying glass tilted right', 'search'],\n ['👑', 'crown', 'king queen vip'],\n ['👓', 'glasses', 'eyewear'],\n ['🕶️', 'sunglasses', 'cool'],\n ['👔', 'necktie', 'formal work'],\n ['👕', 't shirt', 'clothes'],\n ['👖', 'jeans', 'clothes'],\n ['👗', 'dress', 'clothes'],\n ['👜', 'handbag', 'bag'],\n ['🎒', 'backpack', 'school bag'],\n ['👟', 'running shoe', 'sneaker'],\n ['👞', 'mans shoe', 'shoe'],\n ['🧦', 'socks', 'clothes'],\n ['🧢', 'billed cap', 'hat'],\n ['🎩', 'top hat', 'formal'],\n]\n\nconst SYMBOLS: EmojiTuple[] = [\n ['❤️', 'red heart', 'love like'],\n ['🧡', 'orange heart', 'love'],\n ['💛', 'yellow heart', 'love'],\n ['💚', 'green heart', 'love'],\n ['💙', 'blue heart', 'love'],\n ['💜', 'purple heart', 'love'],\n ['🖤', 'black heart', 'love'],\n ['🤍', 'white heart', 'love'],\n ['🤎', 'brown heart', 'love'],\n ['💔', 'broken heart', 'breakup sad'],\n ['❣️', 'heart exclamation', 'love'],\n ['💕', 'two hearts', 'love'],\n ['💞', 'revolving hearts', 'love'],\n ['💓', 'beating heart', 'love'],\n ['💗', 'growing heart', 'love'],\n ['💖', 'sparkling heart', 'love'],\n ['💘', 'heart with arrow', 'cupid love'],\n ['💝', 'heart with ribbon', 'gift love'],\n ['💟', 'heart decoration', 'love'],\n ['☮️', 'peace symbol', 'peace'],\n ['✝️', 'latin cross', 'christianity'],\n ['☪️', 'star and crescent', 'islam'],\n ['🕉️', 'om', 'hinduism'],\n ['☸️', 'wheel of dharma', 'buddhism'],\n ['✡️', 'star of david', 'judaism'],\n ['☯️', 'yin yang', 'balance'],\n ['♈', 'aries', 'zodiac'],\n ['♉', 'taurus', 'zodiac'],\n ['♊', 'gemini', 'zodiac'],\n ['♋', 'cancer', 'zodiac'],\n ['♌', 'leo', 'zodiac'],\n ['♍', 'virgo', 'zodiac'],\n ['♎', 'libra', 'zodiac'],\n ['♏', 'scorpio', 'zodiac'],\n ['♐', 'sagittarius', 'zodiac'],\n ['♑', 'capricorn', 'zodiac'],\n ['♒', 'aquarius', 'zodiac'],\n ['♓', 'pisces', 'zodiac'],\n ['🆔', 'id button', 'identity'],\n ['⚛️', 'atom symbol', 'science'],\n ['✅', 'check mark button', 'done yes tick'],\n ['☑️', 'check box with check', 'done'],\n ['✔️', 'check mark', 'tick done'],\n ['❌', 'cross mark', 'no wrong cancel'],\n ['❎', 'cross mark button', 'no'],\n ['➕', 'plus', 'add'],\n ['➖', 'minus', 'subtract'],\n ['➗', 'divide', 'division'],\n ['✖️', 'multiply', 'times'],\n ['♾️', 'infinity', 'forever'],\n ['‼️', 'double exclamation mark', 'important'],\n ['⁉️', 'exclamation question mark', 'surprise'],\n ['❓', 'question mark', 'help ask'],\n ['❔', 'white question mark', 'ask'],\n ['❕', 'white exclamation mark', 'important'],\n ['❗', 'exclamation mark', 'important warning'],\n ['〰️', 'wavy dash', 'squiggle'],\n ['⚠️', 'warning', 'caution alert'],\n ['🚫', 'prohibited', 'no forbidden'],\n ['⛔', 'no entry', 'stop'],\n ['♻️', 'recycling symbol', 'recycle green'],\n ['🔱', 'trident emblem', 'symbol'],\n ['⚜️', 'fleur de lis', 'symbol'],\n ['🔰', 'japanese symbol for beginner', 'novice'],\n ['⭕', 'hollow red circle', 'circle correct'],\n ['🆗', 'ok button', 'ok'],\n ['🆕', 'new button', 'new'],\n ['🆓', 'free button', 'free'],\n ['🆙', 'up button', 'up'],\n ['🔝', 'top arrow', 'top'],\n ['🔜', 'soon arrow', 'soon'],\n ['🔙', 'back arrow', 'back'],\n ['⬆️', 'up arrow', 'up'],\n ['⬇️', 'down arrow', 'down'],\n ['⬅️', 'left arrow', 'left'],\n ['➡️', 'right arrow', 'right'],\n ['↩️', 'right arrow curving left', 'reply back'],\n ['🔄', 'counterclockwise arrows', 'refresh sync'],\n ['🔃', 'clockwise vertical arrows', 'reload'],\n ['🔁', 'repeat', 'loop'],\n ['🔂', 'repeat single', 'loop one'],\n ['▶️', 'play button', 'play'],\n ['⏸️', 'pause button', 'pause'],\n ['⏹️', 'stop button', 'stop'],\n ['⏺️', 'record button', 'record'],\n ['⏭️', 'next track button', 'skip'],\n ['⏮️', 'last track button', 'previous'],\n ['🔀', 'shuffle tracks button', 'shuffle random'],\n ['🔊', 'speaker high volume', 'loud sound'],\n ['🔇', 'muted speaker', 'mute silent'],\n ['📶', 'antenna bars', 'signal'],\n ['📳', 'vibration mode', 'vibrate'],\n ['♿', 'wheelchair symbol', 'accessibility'],\n ['🚻', 'restroom', 'toilet'],\n ['🅿️', 'p button', 'parking'],\n ['🈚', 'japanese free of charge button', 'free'],\n ['💯', 'hundred points', 'perfect score'],\n ['🔢', 'input numbers', 'numbers'],\n ['💤', 'zzz', 'sleep'],\n ['🕐', 'one oclock', 'time clock'],\n ['⏰', 'alarm clock', 'time alarm'],\n ['⏳', 'hourglass not done', 'wait time'],\n ['⌛', 'hourglass done', 'time up'],\n ['🔴', 'red circle', 'circle'],\n ['🟠', 'orange circle', 'circle'],\n ['🟡', 'yellow circle', 'circle'],\n ['🟢', 'green circle', 'circle online'],\n ['🔵', 'blue circle', 'circle'],\n ['🟣', 'purple circle', 'circle'],\n ['⚫', 'black circle', 'circle'],\n ['⚪', 'white circle', 'circle'],\n ['🟥', 'red square', 'square'],\n ['🟩', 'green square', 'square'],\n ['🟦', 'blue square', 'square'],\n ['⬛', 'black large square', 'square'],\n ['⬜', 'white large square', 'square'],\n]\n\nconst FLAGS: EmojiTuple[] = [\n ['🏳️', 'white flag', 'surrender'],\n ['🏴', 'black flag', 'flag'],\n ['🏁', 'chequered flag', 'race finish'],\n ['🚩', 'triangular flag', 'red flag'],\n ['🏳️🌈', 'rainbow flag', 'pride lgbt'],\n ['🇦🇪', 'flag united arab emirates', 'uae'],\n ['🇦🇷', 'flag argentina', 'argentina'],\n ['🇦🇺', 'flag australia', 'australia'],\n ['🇧🇪', 'flag belgium', 'belgium'],\n ['🇧🇭', 'flag bahrain', 'bahrain'],\n ['🇧🇷', 'flag brazil', 'brazil'],\n ['🇨🇦', 'flag canada', 'canada'],\n ['🇨🇭', 'flag switzerland', 'switzerland'],\n ['🇨🇳', 'flag china', 'china'],\n ['🇩🇪', 'flag germany', 'germany'],\n ['🇩🇰', 'flag denmark', 'denmark'],\n ['🇪🇬', 'flag egypt', 'egypt'],\n ['🇪🇸', 'flag spain', 'spain'],\n ['🇫🇷', 'flag france', 'france'],\n ['🇬🇧', 'flag united kingdom', 'uk britain'],\n ['🇬🇷', 'flag greece', 'greece'],\n ['🇮🇩', 'flag indonesia', 'indonesia'],\n ['🇮🇪', 'flag ireland', 'ireland'],\n ['🇮🇳', 'flag india', 'india'],\n ['🇮🇹', 'flag italy', 'italy'],\n ['🇯🇵', 'flag japan', 'japan'],\n ['🇰🇷', 'flag south korea', 'korea'],\n ['🇰🇼', 'flag kuwait', 'kuwait'],\n ['🇲🇽', 'flag mexico', 'mexico'],\n ['🇲🇾', 'flag malaysia', 'malaysia'],\n ['🇳🇬', 'flag nigeria', 'nigeria'],\n ['🇳🇱', 'flag netherlands', 'netherlands'],\n ['🇳🇴', 'flag norway', 'norway'],\n ['🇴🇲', 'flag oman', 'oman'],\n ['🇵🇭', 'flag philippines', 'philippines'],\n ['🇵🇰', 'flag pakistan', 'pakistan'],\n ['🇵🇱', 'flag poland', 'poland'],\n ['🇵🇹', 'flag portugal', 'portugal'],\n ['🇶🇦', 'flag qatar', 'qatar'],\n ['🇷🇺', 'flag russia', 'russia'],\n ['🇸🇦', 'flag saudi arabia', 'saudi'],\n ['🇸🇪', 'flag sweden', 'sweden'],\n ['🇸🇬', 'flag singapore', 'singapore'],\n ['🇹🇷', 'flag turkey', 'turkey'],\n ['🇺🇸', 'flag united states', 'usa america'],\n ['🇿🇦', 'flag south africa', 'south africa'],\n]\n\nconst GROUPED: [Exclude<WhatsAppEmojiGroupId, 'recent'>, EmojiTuple[]][] = [\n ['smileys', SMILEYS],\n ['people', PEOPLE],\n ['animals', ANIMALS],\n ['food', FOOD],\n ['activity', ACTIVITY],\n ['travel', TRAVEL],\n ['objects', OBJECTS],\n ['symbols', SYMBOLS],\n ['flags', FLAGS],\n]\n\n/** The full dataset, in the order the picker renders it. */\nexport const WHATSAPP_EMOJIS: WhatsAppEmoji[] = GROUPED.flatMap(([group, entries]) =>\n entries.map(([emoji, name, keywords]) => ({\n emoji,\n name,\n keywords: keywords ? keywords.split(' ') : [],\n group,\n })),\n)\n\n/** Lookup by character, used to resolve recently-used emoji back to full entries. */\nexport const WHATSAPP_EMOJIS_BY_CHAR: ReadonlyMap<string, WhatsAppEmoji> = new Map(\n WHATSAPP_EMOJIS.map((entry) => [entry.emoji, entry]),\n)\n\n/** Group ids in the order the tab strip shows them, `recent` excluded. */\nexport const WHATSAPP_EMOJI_GROUP_ORDER = GROUPED.map(([group]) => group)\n","import type { WhatsAppInboxLabels } from '../labels'\nimport {\n WHATSAPP_EMOJI_GROUP_ORDER,\n WHATSAPP_EMOJIS,\n type WhatsAppEmoji,\n type WhatsAppEmojiGroupId,\n} from './emoji-data'\n\n/** Tab metadata for one emoji category. */\nexport interface WhatsAppEmojiGroup {\n id: WhatsAppEmojiGroupId\n\n /** Glyph shown in the tab strip. */\n icon: string\n\n /** Key of the label that names the group. */\n labelKey: keyof WhatsAppInboxLabels\n}\n\n/** Every category the picker can show, in tab order. `recent` comes first when it has entries. */\nexport const WHATSAPP_EMOJI_GROUPS: readonly WhatsAppEmojiGroup[] = [\n { id: 'recent', icon: '🕘', labelKey: 'emojiGroupRecent' },\n { id: 'smileys', icon: '😀', labelKey: 'emojiGroupSmileys' },\n { id: 'people', icon: '👋', labelKey: 'emojiGroupPeople' },\n { id: 'animals', icon: '🐶', labelKey: 'emojiGroupAnimals' },\n { id: 'food', icon: '🍔', labelKey: 'emojiGroupFood' },\n { id: 'activity', icon: '⚽', labelKey: 'emojiGroupActivity' },\n { id: 'travel', icon: '🚗', labelKey: 'emojiGroupTravel' },\n { id: 'objects', icon: '💡', labelKey: 'emojiGroupObjects' },\n { id: 'symbols', icon: '❤️', labelKey: 'emojiGroupSymbols' },\n { id: 'flags', icon: '🏁', labelKey: 'emojiGroupFlags' },\n]\n\n/**\n * Which emoji the picker offers.\n *\n * Allow-lists win over block-lists, and `filter` has the final say, so a policy can be expressed\n * either way round: start from everything and remove, or start from nothing and add.\n */\nexport interface WhatsAppEmojiFilterOptions {\n /** Only these categories are shown, in the order given. */\n groups?: WhatsAppEmojiGroupId[]\n\n /** These categories are removed. Ignored for a category listed in `groups`. */\n excludeGroups?: WhatsAppEmojiGroupId[]\n\n /** Allow-list of characters. When set, nothing outside it is shown. */\n emojis?: string[]\n\n /** Block-list of characters. */\n excludeEmojis?: string[]\n\n /** Final say. Return `false` to drop an entry that passed everything above. */\n filter?: (emoji: WhatsAppEmoji) => boolean\n\n /** Replaces the built-in dataset, for a fuller catalogue or localized names. */\n emojiData?: WhatsAppEmoji[]\n}\n\n/** Applies the configured allow-lists, block-lists and predicate to the dataset. */\nexport function filterEmojis(options: WhatsAppEmojiFilterOptions = {}): WhatsAppEmoji[] {\n const source = options.emojiData ?? WHATSAPP_EMOJIS\n const allowedGroups = options.groups && options.groups.length > 0 ? new Set(options.groups) : null\n const blockedGroups = new Set(options.excludeGroups ?? [])\n const allowedEmojis = options.emojis && options.emojis.length > 0 ? new Set(options.emojis) : null\n const blockedEmojis = new Set(options.excludeEmojis ?? [])\n\n return source.filter((entry) => {\n if (allowedGroups ? !allowedGroups.has(entry.group) : blockedGroups.has(entry.group)) {\n return false\n }\n\n if (allowedEmojis ? !allowedEmojis.has(entry.emoji) : blockedEmojis.has(entry.emoji)) {\n return false\n }\n\n return options.filter ? options.filter(entry) : true\n })\n}\n\n/**\n * Categories present in a filtered set, in the order `groups` asked for, or the default order.\n *\n * Derived from the entries rather than the options so a category that filtered down to nothing\n * never shows an empty tab.\n */\nexport function getEmojiGroups(\n emojis: WhatsAppEmoji[],\n order?: WhatsAppEmojiGroupId[],\n): WhatsAppEmojiGroupId[] {\n const present = new Set(emojis.map((entry) => entry.group))\n const sequence = order && order.length > 0 ? order : WHATSAPP_EMOJI_GROUP_ORDER\n\n return sequence.filter((group) => present.has(group))\n}\n\n/**\n * Matches a query against names and keywords.\n *\n * Whole-word prefix matching rather than a substring scan: searching `cat` should surface the cat\n * face before `communication`, and prefix matching on each word is what gets that ordering for\n * free while still finding `black cat`.\n */\nexport function searchEmojis(emojis: WhatsAppEmoji[], query: string): WhatsAppEmoji[] {\n const needle = query.trim().toLowerCase()\n\n if (needle.length === 0) {\n return emojis\n }\n\n const exact: WhatsAppEmoji[] = []\n const prefix: WhatsAppEmoji[] = []\n const partial: WhatsAppEmoji[] = []\n\n for (const entry of emojis) {\n if (entry.emoji === needle || entry.name === needle) {\n exact.push(entry)\n continue\n }\n\n const words = [...entry.name.split(' '), ...entry.keywords]\n\n if (words.some((word) => word.startsWith(needle))) {\n prefix.push(entry)\n } else if (entry.name.includes(needle)) {\n partial.push(entry)\n }\n }\n\n return [...exact, ...prefix, ...partial]\n}\n","import { computed, inject, provide, type InjectionKey } from 'vue'\nimport {\n DEFAULT_WHATSAPP_INBOX_LABELS,\n mergeWhatsAppLabels,\n type WhatsAppInboxLabels,\n type WhatsAppInboxLabelsOverride,\n} from './labels'\nimport type {\n WhatsAppConversationData,\n WhatsAppResolvedCapabilities,\n WhatsAppTimestamp,\n} from './types'\nimport {\n formatConversationTime,\n formatDayLabel,\n formatFileSize,\n formatFullTimestamp,\n formatMessageTime,\n resolveCapabilities,\n} from './utils'\n\n/**\n * Date, time and size formatting used across the inbox.\n *\n * Every formatter is replaceable for applications that use another date library or timezone.\n */\nexport interface WhatsAppInboxFormatters {\n /** Time shown under a message bubble. */\n messageTime: (value: WhatsAppTimestamp, locale: string | undefined) => string\n\n /** Full date and time, used for tooltips and screen-reader text. */\n fullTimestamp: (value: WhatsAppTimestamp, locale: string | undefined) => string\n\n /** Day divider label in the message list. */\n dayLabel: (\n value: WhatsAppTimestamp,\n locale: string | undefined,\n labels: WhatsAppInboxLabels,\n ) => string\n\n /** Timestamp column of a conversation list item. */\n conversationTime: (\n value: WhatsAppTimestamp | undefined,\n locale: string | undefined,\n labels: WhatsAppInboxLabels,\n ) => string\n\n /** Human readable file size. */\n fileSize: (bytes: number | undefined) => string\n}\n\n/** Built-in `Intl` based formatters. */\nexport const DEFAULT_WHATSAPP_INBOX_FORMATTERS: WhatsAppInboxFormatters = {\n messageTime: (value, locale) => formatMessageTime(value, locale),\n fullTimestamp: (value, locale) => formatFullTimestamp(value, locale),\n dayLabel: (value, locale, labels) => formatDayLabel(value, locale, labels),\n conversationTime: (value, locale, labels) => formatConversationTime(value, locale, labels),\n fileSize: (bytes) => formatFileSize(bytes),\n}\n\n/** Shared configuration published by `WhatsAppInboxProvider`. */\nexport interface WhatsAppInboxConfigSource {\n readonly labels: WhatsAppInboxLabelsOverride | undefined\n readonly locale: string | undefined\n readonly formatters: Partial<WhatsAppInboxFormatters> | undefined\n}\n\n/**\n * Resolved configuration, as every component consumes it.\n *\n * `labels` is already merged, and each formatter is bound to the resolved locale and labels, so\n * a component calls `config.messageTime(value)` without threading either through.\n */\nexport interface WhatsAppInboxConfig {\n readonly labels: WhatsAppInboxLabels\n readonly locale: string | undefined\n messageTime: (value: WhatsAppTimestamp) => string\n fullTimestamp: (value: WhatsAppTimestamp) => string\n dayLabel: (value: WhatsAppTimestamp) => string\n conversationTime: (value: WhatsAppTimestamp | undefined) => string\n fileSize: (bytes: number | undefined) => string\n}\n\nconst WhatsAppInboxConfigKey: InjectionKey<WhatsAppInboxConfigSource> = Symbol(\n 'mantine-whatsapp-inbox-config',\n)\n\n/** Publishes shared inbox configuration to every component below. */\nexport function provideWhatsAppInboxConfig(value: WhatsAppInboxConfigSource) {\n provide(WhatsAppInboxConfigKey, value)\n}\n\n/**\n * Reads the inbox configuration, merging a component's own `labels` and `locale` over it.\n *\n * Components outside a `WhatsAppInboxProvider` use the English defaults.\n */\nexport function useWhatsAppInboxConfig(\n labelsOverride?: () => WhatsAppInboxLabelsOverride | undefined,\n localeOverride?: () => string | undefined,\n): WhatsAppInboxConfig {\n const source = inject(WhatsAppInboxConfigKey, undefined)\n\n const labels = computed(() => {\n const own = labelsOverride?.()\n const inherited = source?.labels\n\n if (!own && !inherited) {\n return DEFAULT_WHATSAPP_INBOX_LABELS\n }\n\n return mergeWhatsAppLabels(inherited, own)\n })\n\n const locale = computed(() => localeOverride?.() ?? source?.locale)\n\n const formatters = computed<WhatsAppInboxFormatters>(() =>\n source?.formatters\n ? { ...DEFAULT_WHATSAPP_INBOX_FORMATTERS, ...source.formatters }\n : DEFAULT_WHATSAPP_INBOX_FORMATTERS,\n )\n\n return {\n get labels() {\n return labels.value\n },\n get locale() {\n return locale.value\n },\n messageTime: (value) => formatters.value.messageTime(value, locale.value),\n fullTimestamp: (value) => formatters.value.fullTimestamp(value, locale.value),\n dayLabel: (value) => formatters.value.dayLabel(value, locale.value, labels.value),\n conversationTime: (value) =>\n value === undefined\n ? ''\n : formatters.value.conversationTime(value, locale.value, labels.value),\n fileSize: (bytes) => formatters.value.fileSize(bytes),\n }\n}\n\n/**\n * The conversation the surrounding `WhatsAppConversation` is showing.\n *\n * Lets a consumer build a custom layout out of the primitives without re-passing the\n * conversation and its capabilities to each one. Every consumer of this context still accepts\n * the same values as props, and props always win.\n */\nexport interface WhatsAppConversationContextValue {\n readonly conversation: WhatsAppConversationData | undefined\n readonly conversationId: string | undefined\n readonly capabilities: WhatsAppResolvedCapabilities\n}\n\nconst WhatsAppConversationKey: InjectionKey<WhatsAppConversationContextValue> = Symbol(\n 'mantine-whatsapp-conversation',\n)\n\nexport function provideWhatsAppConversationContext(value: WhatsAppConversationContextValue) {\n provide(WhatsAppConversationKey, value)\n}\n\n/** Reads the surrounding conversation, or `undefined` outside a `WhatsAppConversation`. */\nexport function useWhatsAppConversationContext(): WhatsAppConversationContextValue | undefined {\n return inject(WhatsAppConversationKey, undefined)\n}\n\n/**\n * Resolves the capabilities a component should apply: its own prop when set, the surrounding\n * conversation's otherwise.\n */\nexport function useResolvedCapabilities(\n ownCapabilities: () => WhatsAppConversationData['capabilities'] | undefined,\n hasOwnCapabilities: () => boolean = () => ownCapabilities() !== undefined,\n) {\n const context = useWhatsAppConversationContext()\n\n return computed<WhatsAppResolvedCapabilities>(() =>\n hasOwnCapabilities() || !context\n ? resolveCapabilities(ownCapabilities())\n : context.capabilities,\n )\n}\n","<script setup lang=\"ts\">\nimport { provideWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type {\n WhatsAppInboxProviderProps,\n WhatsAppInboxProviderSlots,\n} from './WhatsAppInboxProvider.types'\n\ndefineOptions({ name: 'WhatsAppInboxProvider' })\n\nconst props = withDefaults(defineProps<WhatsAppInboxProviderProps>(), {\n labels: undefined,\n locale: undefined,\n formatters: undefined,\n})\n\ndefineSlots<WhatsAppInboxProviderSlots>()\n\n/**\n * Getters rather than a snapshot: the provider is set up once during `setup`, and every\n * component below re-reads the current value when the props change.\n */\nprovideWhatsAppInboxConfig({\n get labels() {\n return props.labels\n },\n get locale() {\n return props.locale\n },\n get formatters() {\n return props.formatters\n },\n})\n</script>\n\n<template>\n <slot />\n</template>\n","<script setup lang=\"ts\">\nimport { provideWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type {\n WhatsAppInboxProviderProps,\n WhatsAppInboxProviderSlots,\n} from './WhatsAppInboxProvider.types'\n\ndefineOptions({ name: 'WhatsAppInboxProvider' })\n\nconst props = withDefaults(defineProps<WhatsAppInboxProviderProps>(), {\n labels: undefined,\n locale: undefined,\n formatters: undefined,\n})\n\ndefineSlots<WhatsAppInboxProviderSlots>()\n\n/**\n * Getters rather than a snapshot: the provider is set up once during `setup`, and every\n * component below re-reads the current value when the props change.\n */\nprovideWhatsAppInboxConfig({\n get labels() {\n return props.labels\n },\n get locale() {\n return props.locale\n },\n get formatters() {\n return props.formatters\n },\n})\n</script>\n\n<template>\n <slot />\n</template>\n","import WhatsAppInboxProviderComponent from './WhatsAppInboxProvider.vue'\n\nexport const WhatsAppInboxProvider = WhatsAppInboxProviderComponent\n\nexport type {\n WhatsAppInboxProviderProps,\n WhatsAppInboxProviderSlots,\n} from './WhatsAppInboxProvider.types'\n",".contactPanelRoot {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n background-color: var(--mantine-color-body);\n border-inline-start: 1px solid var(--mantine-color-default-border);\n}\n\n.contactPanelHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);\n min-height: var(--wa-header-height, 64px);\n border-bottom: 1px solid var(--mantine-color-default-border);\n flex-shrink: 0;\n}\n\n.contactPanelTitle {\n font-size: var(--mantine-font-size-sm);\n font-weight: 600;\n}\n\n.contactPanelBody {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-md);\n padding: var(--mantine-spacing-md);\n}\n\n.contactPanelIdentity {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n text-align: center;\n}\n\n.contactPanelName {\n font-size: var(--mantine-font-size-md);\n font-weight: 600;\n}\n\n.contactPanelPhone {\n font-size: var(--mantine-font-size-sm);\n color: var(--mantine-color-dimmed);\n}\n\n.contactPanelField {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.contactPanelFieldLabel {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mantine-color-dimmed);\n}\n\n.contactPanelFieldValue {\n font-size: var(--mantine-font-size-sm);\n overflow-wrap: anywhere;\n}\n\n.contactPanelTags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.contactPanelFooter {\n padding: var(--mantine-spacing-md);\n border-top: 1px solid var(--mantine-color-default-border);\n flex-shrink: 0;\n}\n\n.contactPanelEmpty {\n padding: var(--mantine-spacing-lg);\n text-align: center;\n font-size: var(--mantine-font-size-sm);\n color: var(--mantine-color-dimmed);\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n withCloseButton: false,\n withHeader: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Anchor, Avatar, Badge, Box, CloseButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppContactPanelSlots } from '../../component-props'\nimport type { WhatsAppContactField } from '../../types'\nimport type {\n WhatsAppContactPanelEmits,\n WhatsAppContactPanelOwnProps,\n} from './WhatsAppContactPanel.types'\nimport classes from './WhatsAppContactPanel.module.css'\n\ndefineOptions({\n name: 'WhatsAppContactPanel',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppContactPanelOwnProps>(), {\n contact: undefined,\n conversation: undefined,\n withCloseButton: undefined,\n withHeader: undefined,\n title: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppContactPanelEmits>()\ndefineSlots<WhatsAppContactPanelSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppContactPanel', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppContactPanel',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'contactPanelRoot',\n})\n\nconst contact = computed(() => props.contact ?? props.conversation?.contact)\n\nconst displayName = computed(\n () => contact.value?.name || contact.value?.phoneNumber || contact.value?.id || '',\n)\n\n/**\n * The built-in rows and the consumer's own `fields`, flattened into one list so the panel does\n * not have to special-case which of them exist.\n */\nconst fields = computed<WhatsAppContactField[]>(() => {\n const current = contact.value\n\n if (!current) {\n return []\n }\n\n const result: WhatsAppContactField[] = []\n\n if (current.phoneNumber) {\n result.push({\n key: 'phone',\n label: config.labels.contactPhoneNumber,\n value: current.phoneNumber,\n href: `tel:${current.phoneNumber.replace(/\\s/g, '')}`,\n })\n }\n\n if (current.email) {\n result.push({\n key: 'email',\n label: config.labels.contactEmail,\n value: current.email,\n href: `mailto:${current.email}`,\n })\n }\n\n if (current.about) {\n result.push({ key: 'about', label: config.labels.contactAbout, value: current.about })\n }\n\n if (props.conversation?.status) {\n result.push({\n key: 'status',\n label: config.labels.contactStatus,\n value: String(props.conversation.status),\n })\n }\n\n if (props.conversation?.assignee) {\n result.push({\n key: 'assignee',\n label: config.labels.contactAssignee,\n value: props.conversation.assignee.name,\n })\n }\n\n return [...result, ...(current.fields ?? [])]\n})\n</script>\n\n<template>\n <Box\n component=\"aside\"\n v-bind=\"{ ...attrs, ...getStyles('contactPanelRoot') }\"\n :aria-label=\"props.title ?? config.labels.contactPanelTitle\"\n >\n <Box v-if=\"props.withHeader\" v-bind=\"getStyles('contactPanelHeader')\">\n <Box v-bind=\"getStyles('contactPanelTitle')\">\n {{ props.title ?? config.labels.contactPanelTitle }}\n </Box>\n <CloseButton\n v-if=\"props.withCloseButton\"\n :aria-label=\"config.labels.close\"\n @click=\"emit('close')\"\n />\n </Box>\n\n <Box v-if=\"!contact\" v-bind=\"getStyles('contactPanelEmpty')\">\n {{ config.labels.noConversationSelected }}\n </Box>\n\n <template v-else>\n <slot v-if=\"slots.contactPanel\" name=\"contactPanel\" :contact=\"contact\" />\n\n <Box v-else v-bind=\"getStyles('contactPanelBody')\">\n <slot name=\"contactPanelHeader\" :contact=\"contact\" />\n\n <Box v-bind=\"getStyles('contactPanelIdentity')\">\n <Avatar\n :src=\"contact.avatarUrl\"\n :name=\"displayName\"\n color=\"initials\"\n radius=\"xl\"\n size=\"xl\"\n aria-hidden=\"true\"\n />\n <Box v-bind=\"getStyles('contactPanelName')\">{{ displayName }}</Box>\n <Box\n v-if=\"contact.phoneNumber && contact.phoneNumber !== displayName\"\n v-bind=\"getStyles('contactPanelPhone')\"\n >\n {{ contact.phoneNumber }}\n </Box>\n </Box>\n\n <Box v-if=\"contact.tags?.length\" v-bind=\"getStyles('contactPanelField')\">\n <Box v-bind=\"getStyles('contactPanelFieldLabel')\">{{ config.labels.contactTags }}</Box>\n <Box v-bind=\"getStyles('contactPanelTags')\">\n <Badge v-for=\"tag in contact.tags\" :key=\"tag\" size=\"sm\" variant=\"light\">\n {{ tag }}\n </Badge>\n </Box>\n </Box>\n\n <Box v-for=\"field in fields\" :key=\"field.key\" v-bind=\"getStyles('contactPanelField')\">\n <Box v-bind=\"getStyles('contactPanelFieldLabel')\">{{ field.label }}</Box>\n <Box v-bind=\"getStyles('contactPanelFieldValue')\">\n <Anchor v-if=\"field.href\" :href=\"field.href\" size=\"sm\">{{ field.value }}</Anchor>\n <template v-else>{{ field.value }}</template>\n </Box>\n </Box>\n </Box>\n\n <Box v-if=\"slots.contactPanelFooter\" v-bind=\"getStyles('contactPanelFooter')\">\n <slot name=\"contactPanelFooter\" :contact=\"contact\" />\n </Box>\n </template>\n </Box>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n withCloseButton: false,\n withHeader: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Anchor, Avatar, Badge, Box, CloseButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppContactPanelSlots } from '../../component-props'\nimport type { WhatsAppContactField } from '../../types'\nimport type {\n WhatsAppContactPanelEmits,\n WhatsAppContactPanelOwnProps,\n} from './WhatsAppContactPanel.types'\nimport classes from './WhatsAppContactPanel.module.css'\n\ndefineOptions({\n name: 'WhatsAppContactPanel',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppContactPanelOwnProps>(), {\n contact: undefined,\n conversation: undefined,\n withCloseButton: undefined,\n withHeader: undefined,\n title: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppContactPanelEmits>()\ndefineSlots<WhatsAppContactPanelSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppContactPanel', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppContactPanel',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'contactPanelRoot',\n})\n\nconst contact = computed(() => props.contact ?? props.conversation?.contact)\n\nconst displayName = computed(\n () => contact.value?.name || contact.value?.phoneNumber || contact.value?.id || '',\n)\n\n/**\n * The built-in rows and the consumer's own `fields`, flattened into one list so the panel does\n * not have to special-case which of them exist.\n */\nconst fields = computed<WhatsAppContactField[]>(() => {\n const current = contact.value\n\n if (!current) {\n return []\n }\n\n const result: WhatsAppContactField[] = []\n\n if (current.phoneNumber) {\n result.push({\n key: 'phone',\n label: config.labels.contactPhoneNumber,\n value: current.phoneNumber,\n href: `tel:${current.phoneNumber.replace(/\\s/g, '')}`,\n })\n }\n\n if (current.email) {\n result.push({\n key: 'email',\n label: config.labels.contactEmail,\n value: current.email,\n href: `mailto:${current.email}`,\n })\n }\n\n if (current.about) {\n result.push({ key: 'about', label: config.labels.contactAbout, value: current.about })\n }\n\n if (props.conversation?.status) {\n result.push({\n key: 'status',\n label: config.labels.contactStatus,\n value: String(props.conversation.status),\n })\n }\n\n if (props.conversation?.assignee) {\n result.push({\n key: 'assignee',\n label: config.labels.contactAssignee,\n value: props.conversation.assignee.name,\n })\n }\n\n return [...result, ...(current.fields ?? [])]\n})\n</script>\n\n<template>\n <Box\n component=\"aside\"\n v-bind=\"{ ...attrs, ...getStyles('contactPanelRoot') }\"\n :aria-label=\"props.title ?? config.labels.contactPanelTitle\"\n >\n <Box v-if=\"props.withHeader\" v-bind=\"getStyles('contactPanelHeader')\">\n <Box v-bind=\"getStyles('contactPanelTitle')\">\n {{ props.title ?? config.labels.contactPanelTitle }}\n </Box>\n <CloseButton\n v-if=\"props.withCloseButton\"\n :aria-label=\"config.labels.close\"\n @click=\"emit('close')\"\n />\n </Box>\n\n <Box v-if=\"!contact\" v-bind=\"getStyles('contactPanelEmpty')\">\n {{ config.labels.noConversationSelected }}\n </Box>\n\n <template v-else>\n <slot v-if=\"slots.contactPanel\" name=\"contactPanel\" :contact=\"contact\" />\n\n <Box v-else v-bind=\"getStyles('contactPanelBody')\">\n <slot name=\"contactPanelHeader\" :contact=\"contact\" />\n\n <Box v-bind=\"getStyles('contactPanelIdentity')\">\n <Avatar\n :src=\"contact.avatarUrl\"\n :name=\"displayName\"\n color=\"initials\"\n radius=\"xl\"\n size=\"xl\"\n aria-hidden=\"true\"\n />\n <Box v-bind=\"getStyles('contactPanelName')\">{{ displayName }}</Box>\n <Box\n v-if=\"contact.phoneNumber && contact.phoneNumber !== displayName\"\n v-bind=\"getStyles('contactPanelPhone')\"\n >\n {{ contact.phoneNumber }}\n </Box>\n </Box>\n\n <Box v-if=\"contact.tags?.length\" v-bind=\"getStyles('contactPanelField')\">\n <Box v-bind=\"getStyles('contactPanelFieldLabel')\">{{ config.labels.contactTags }}</Box>\n <Box v-bind=\"getStyles('contactPanelTags')\">\n <Badge v-for=\"tag in contact.tags\" :key=\"tag\" size=\"sm\" variant=\"light\">\n {{ tag }}\n </Badge>\n </Box>\n </Box>\n\n <Box v-for=\"field in fields\" :key=\"field.key\" v-bind=\"getStyles('contactPanelField')\">\n <Box v-bind=\"getStyles('contactPanelFieldLabel')\">{{ field.label }}</Box>\n <Box v-bind=\"getStyles('contactPanelFieldValue')\">\n <Anchor v-if=\"field.href\" :href=\"field.href\" size=\"sm\">{{ field.value }}</Anchor>\n <template v-else>{{ field.value }}</template>\n </Box>\n </Box>\n </Box>\n\n <Box v-if=\"slots.contactPanelFooter\" v-bind=\"getStyles('contactPanelFooter')\">\n <slot name=\"contactPanelFooter\" :contact=\"contact\" />\n </Box>\n </template>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppContactPanelComponent from './WhatsAppContactPanel.vue'\nimport type { WhatsAppContactPanelFactory } from './WhatsAppContactPanel.types'\nimport classes from './WhatsAppContactPanel.module.css'\n\nexport const WhatsAppContactPanel = factory<WhatsAppContactPanelFactory>(\n WhatsAppContactPanelComponent,\n { classes },\n)\n\nexport type {\n WhatsAppContactPanelEmits,\n WhatsAppContactPanelFactory,\n WhatsAppContactPanelOwnProps,\n WhatsAppContactPanelProps,\n WhatsAppContactPanelStylesNames,\n} from './WhatsAppContactPanel.types'\n","/**\n * Outline icon paths used by the inbox.\n *\n * Bundled to avoid requiring a separate icon library. Paths use a 24x24 grid and\n * `currentColor`.\n */\nexport const WHATSAPP_ICON_PATHS = {\n clock: ['M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', 'M12 7v5l3 2'],\n check: ['M5 12l5 5l10 -10'],\n checks: ['M7 12l5 5l10 -10', 'M2 12l5 5m5 -5l5 -5'],\n alert: ['M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', 'M12 8v4', 'M12 16h.01'],\n alertTriangle: [\n 'M12 9v4',\n 'M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z',\n 'M12 16h.01',\n ],\n paperclip: [\n 'M15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3l6.5 -6.5a3 3 0 0 0 -6 -6l-6.5 6.5a4.5 4.5 0 0 0 9 9l6.5 -6.5',\n ],\n send: [\n 'M10 14l11 -11',\n 'M21 3l-6.5 18a.55 .55 0 0 1 -1 0l-3.5 -7l-7 -3.5a.55 .55 0 0 1 0 -1l18 -6.5',\n ],\n emoji: [\n 'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0',\n 'M9 10h.01',\n 'M15 10h.01',\n 'M9.5 15a3.5 3.5 0 0 0 5 0',\n ],\n template: [\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z',\n 'M9 13h6',\n 'M9 17h6',\n ],\n interactive: [\n 'M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n 'M4 14m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z',\n ],\n download: ['M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2', 'M7 11l5 5l5 -5', 'M12 4v12'],\n photo: [\n 'M15 8h.01',\n 'M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z',\n 'M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5',\n 'M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3',\n ],\n video: [\n 'M15 10l4.553 -2.276a1 1 0 0 1 1.447 .894v6.764a1 1 0 0 1 -1.447 .894l-4.553 -2.276z',\n 'M3 8a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z',\n ],\n microphone: [\n 'M9 5a3 3 0 0 1 6 0v5a3 3 0 0 1 -6 0z',\n 'M5 10a7 7 0 0 0 14 0',\n 'M8 21h8',\n 'M12 17v4',\n ],\n file: [\n 'M14 3v4a1 1 0 0 0 1 1h4',\n 'M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z',\n ],\n chevronDown: ['M6 9l6 6l6 -6'],\n arrowLeft: ['M5 12h14', 'M5 12l6 6', 'M5 12l6 -6'],\n search: ['M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0', 'M21 21l-6 -6'],\n info: ['M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', 'M12 9h.01', 'M11 12h1v4h1'],\n play: ['M7 4v16l13 -8z'],\n lock: [\n 'M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z',\n 'M12 16m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0',\n 'M8 11v-4a4 4 0 1 1 8 0v4',\n ],\n mute: [\n 'M17 17h-13a4 4 0 0 0 2 -3v-3a7 7 0 0 1 1.279 -3.951m2.041 -1.847c.593 -.135 1.183 -.202 1.68 -.202a7 7 0 0 1 7 7v3',\n 'M9 17v1a3 3 0 0 0 6 0v-1',\n 'M3 3l18 18',\n ],\n pin: [\n 'M15 4.5l-4 4l-4 1.5l-1.5 1.5l7 7l1.5 -1.5l1.5 -4l4 -4',\n 'M9 15l-4.5 4.5',\n 'M14.5 4l5.5 5.5',\n ],\n externalLink: [\n 'M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6',\n 'M11 13l9 -9',\n 'M15 4h5v5',\n ],\n phone: [\n 'M5 4h4l2 5l-2.5 1.5a11 11 0 0 0 5 5l1.5 -2.5l5 2v4a2 2 0 0 1 -2 2a16 16 0 0 1 -15 -15a2 2 0 0 1 2 -2',\n ],\n mapPin: [\n 'M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0',\n 'M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0z',\n ],\n user: ['M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0', 'M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2'],\n close: ['M18 6l-12 12', 'M6 6l12 12'],\n refresh: ['M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4', 'M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4'],\n reply: ['M18 18v-6a3 3 0 0 0 -3 -3h-10', 'M9 13l-4 -4l4 -4'],\n message: [\n 'M8 9h8',\n 'M8 13h6',\n 'M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3z',\n ],\n plus: ['M12 5v14', 'M5 12h14'],\n inbox: [\n 'M4 13h3l3 3h4l3 -3h3',\n 'M5 19h14a2 2 0 0 0 2 -2v-10a2 2 0 0 0 -2 -2h-14a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2z',\n ],\n} as const\n\n/** Name of one of the built-in icons. */\nexport type WhatsAppIconName = keyof typeof WHATSAPP_ICON_PATHS\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { WHATSAPP_ICON_PATHS, type WhatsAppIconName } from './icon-paths'\n\ndefineOptions({ name: 'WhatsAppIcon', inheritAttrs: false })\n\nconst props = withDefaults(\n defineProps<{\n /** Which built-in glyph to render. */\n name: WhatsAppIconName\n\n /** Any valid CSS length. Numbers are treated as pixels. */\n size?: string | number\n\n /** Stroke width on the 24x24 grid. */\n strokeWidth?: number\n\n /** Filled glyphs (`play`) look better without a stroke. */\n filled?: boolean\n }>(),\n { size: '1em', strokeWidth: 2, filled: false },\n)\n\nconst attrs = useAttrs()\n\nconst dimension = computed(() => (typeof props.size === 'number' ? `${props.size}px` : props.size))\nconst paths = computed(() => WHATSAPP_ICON_PATHS[props.name])\n</script>\n\n<template>\n <svg\n v-bind=\"attrs\"\n :width=\"dimension\"\n :height=\"dimension\"\n viewBox=\"0 0 24 24\"\n :fill=\"props.filled ? 'currentColor' : 'none'\"\n :stroke=\"props.filled ? 'none' : 'currentColor'\"\n :stroke-width=\"props.strokeWidth\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path v-for=\"d in paths\" :key=\"d\" :d=\"d\" />\n </svg>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { WHATSAPP_ICON_PATHS, type WhatsAppIconName } from './icon-paths'\n\ndefineOptions({ name: 'WhatsAppIcon', inheritAttrs: false })\n\nconst props = withDefaults(\n defineProps<{\n /** Which built-in glyph to render. */\n name: WhatsAppIconName\n\n /** Any valid CSS length. Numbers are treated as pixels. */\n size?: string | number\n\n /** Stroke width on the 24x24 grid. */\n strokeWidth?: number\n\n /** Filled glyphs (`play`) look better without a stroke. */\n filled?: boolean\n }>(),\n { size: '1em', strokeWidth: 2, filled: false },\n)\n\nconst attrs = useAttrs()\n\nconst dimension = computed(() => (typeof props.size === 'number' ? `${props.size}px` : props.size))\nconst paths = computed(() => WHATSAPP_ICON_PATHS[props.name])\n</script>\n\n<template>\n <svg\n v-bind=\"attrs\"\n :width=\"dimension\"\n :height=\"dimension\"\n viewBox=\"0 0 24 24\"\n :fill=\"props.filled ? 'currentColor' : 'none'\"\n :stroke=\"props.filled ? 'none' : 'currentColor'\"\n :stroke-width=\"props.strokeWidth\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path v-for=\"d in paths\" :key=\"d\" :d=\"d\" />\n </svg>\n</template>\n",".attachmentPreviewRoot {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n padding: 6px 8px;\n border-radius: var(--mantine-radius-md);\n border: 1px solid var(--mantine-color-default-border);\n background-color: var(--mantine-color-body);\n min-width: 200px;\n max-width: 280px;\n}\n\n.attachmentPreviewRoot:where([data-status='failed']) {\n border-color: var(--mantine-color-error);\n}\n\n.attachmentPreviewThumb {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: var(--mantine-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: var(--mantine-color-default-hover);\n color: var(--mantine-color-dimmed);\n overflow: hidden;\n}\n\n.attachmentPreviewThumbImage {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.attachmentPreviewBody {\n flex: 1;\n min-width: 0;\n}\n\n.attachmentPreviewName {\n font-size: var(--mantine-font-size-xs);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.attachmentPreviewMeta {\n font-size: 11px;\n color: var(--mantine-color-dimmed);\n}\n\n.attachmentPreviewProgress {\n margin-top: 4px;\n}\n\n.attachmentPreviewError {\n font-size: 11px;\n color: var(--mantine-color-error);\n}\n\n.attachmentPreviewActions {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n}\n","<script lang=\"ts\">\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppMediaType } from '../../types'\n\nconst defaultProps = {\n withRemove: true,\n} as const\n\nconst UPLOAD_ICONS: Record<WhatsAppMediaType, WhatsAppIconName> = {\n image: 'photo',\n video: 'video',\n audio: 'microphone',\n document: 'file',\n sticker: 'photo',\n}\n\nexport { defaultProps, UPLOAD_ICONS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { ActionIcon, Box, Progress, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppAttachmentPreviewEmits,\n WhatsAppAttachmentPreviewOwnProps,\n} from './WhatsAppAttachmentPreview.types'\nimport classes from './WhatsAppAttachmentPreview.module.css'\n\ndefineOptions({\n name: 'WhatsAppAttachmentPreview',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppAttachmentPreviewOwnProps>(), {\n withRemove: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppAttachmentPreviewEmits>()\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppAttachmentPreview', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppAttachmentPreview',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'attachmentPreviewRoot',\n})\n\nconst upload = computed(() => props.upload)\nconst isUploading = computed(\n () => upload.value.status === 'uploading' || upload.value.status === 'pending',\n)\nconst isFailed = computed(() => upload.value.status === 'failed')\n\nconst thumbnail = computed(() =>\n upload.value.mediaType === 'image' || upload.value.mediaType === 'sticker'\n ? (upload.value.previewUrl ??\n upload.value.attachment?.thumbnailUrl ??\n upload.value.attachment?.url)\n : undefined,\n)\n\nconst metaText = computed(() => {\n if (isUploading.value) {\n return upload.value.progress === undefined\n ? config.labels.uploading\n : `${config.labels.uploading} ${Math.round(upload.value.progress)}%`\n }\n\n return config.fileSize(upload.value.size)\n})\n\n/**\n * Use an indeterminate bar until the consumer reports progress.\n */\nconst progressValue = computed(() => upload.value.progress ?? 100)\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('attachmentPreviewRoot') }\"\n :data-status=\"upload.status\"\n :data-media-type=\"upload.mediaType\"\n >\n <Box v-bind=\"getStyles('attachmentPreviewThumb')\">\n <img\n v-if=\"thumbnail\"\n v-bind=\"getStyles('attachmentPreviewThumbImage')\"\n :src=\"thumbnail\"\n :alt=\"upload.fileName\"\n />\n <WhatsAppIcon v-else :name=\"UPLOAD_ICONS[upload.mediaType]\" size=\"20\" />\n </Box>\n\n <Box v-bind=\"getStyles('attachmentPreviewBody')\">\n <Box v-bind=\"getStyles('attachmentPreviewName')\" :title=\"upload.fileName\">\n {{ upload.fileName }}\n </Box>\n\n <Box v-if=\"isFailed\" v-bind=\"getStyles('attachmentPreviewError')\" role=\"alert\">\n {{ upload.error || config.labels.uploadFailed }}\n </Box>\n\n <Box v-else v-bind=\"getStyles('attachmentPreviewMeta')\">{{ metaText }}</Box>\n\n <Progress\n v-if=\"isUploading\"\n v-bind=\"getStyles('attachmentPreviewProgress')\"\n size=\"xs\"\n :value=\"progressValue\"\n :animated=\"upload.progress === undefined\"\n :aria-label=\"config.labels.uploading\"\n />\n </Box>\n\n <Box v-bind=\"getStyles('attachmentPreviewActions')\">\n <ActionIcon\n v-if=\"isFailed\"\n variant=\"subtle\"\n color=\"red\"\n size=\"sm\"\n :aria-label=\"`${config.labels.retryUpload}: ${upload.fileName}`\"\n @click=\"emit('retry', upload)\"\n >\n <WhatsAppIcon name=\"refresh\" size=\"16\" />\n </ActionIcon>\n\n <ActionIcon\n v-if=\"isUploading\"\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n :aria-label=\"`${config.labels.cancelUpload}: ${upload.fileName}`\"\n @click=\"emit('cancel', upload)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n\n <ActionIcon\n v-else-if=\"props.withRemove\"\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n :aria-label=\"`${config.labels.removeAttachment}: ${upload.fileName}`\"\n @click=\"emit('remove', upload)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppMediaType } from '../../types'\n\nconst defaultProps = {\n withRemove: true,\n} as const\n\nconst UPLOAD_ICONS: Record<WhatsAppMediaType, WhatsAppIconName> = {\n image: 'photo',\n video: 'video',\n audio: 'microphone',\n document: 'file',\n sticker: 'photo',\n}\n\nexport { defaultProps, UPLOAD_ICONS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { ActionIcon, Box, Progress, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppAttachmentPreviewEmits,\n WhatsAppAttachmentPreviewOwnProps,\n} from './WhatsAppAttachmentPreview.types'\nimport classes from './WhatsAppAttachmentPreview.module.css'\n\ndefineOptions({\n name: 'WhatsAppAttachmentPreview',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppAttachmentPreviewOwnProps>(), {\n withRemove: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppAttachmentPreviewEmits>()\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppAttachmentPreview', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppAttachmentPreview',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'attachmentPreviewRoot',\n})\n\nconst upload = computed(() => props.upload)\nconst isUploading = computed(\n () => upload.value.status === 'uploading' || upload.value.status === 'pending',\n)\nconst isFailed = computed(() => upload.value.status === 'failed')\n\nconst thumbnail = computed(() =>\n upload.value.mediaType === 'image' || upload.value.mediaType === 'sticker'\n ? (upload.value.previewUrl ??\n upload.value.attachment?.thumbnailUrl ??\n upload.value.attachment?.url)\n : undefined,\n)\n\nconst metaText = computed(() => {\n if (isUploading.value) {\n return upload.value.progress === undefined\n ? config.labels.uploading\n : `${config.labels.uploading} ${Math.round(upload.value.progress)}%`\n }\n\n return config.fileSize(upload.value.size)\n})\n\n/**\n * Use an indeterminate bar until the consumer reports progress.\n */\nconst progressValue = computed(() => upload.value.progress ?? 100)\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('attachmentPreviewRoot') }\"\n :data-status=\"upload.status\"\n :data-media-type=\"upload.mediaType\"\n >\n <Box v-bind=\"getStyles('attachmentPreviewThumb')\">\n <img\n v-if=\"thumbnail\"\n v-bind=\"getStyles('attachmentPreviewThumbImage')\"\n :src=\"thumbnail\"\n :alt=\"upload.fileName\"\n />\n <WhatsAppIcon v-else :name=\"UPLOAD_ICONS[upload.mediaType]\" size=\"20\" />\n </Box>\n\n <Box v-bind=\"getStyles('attachmentPreviewBody')\">\n <Box v-bind=\"getStyles('attachmentPreviewName')\" :title=\"upload.fileName\">\n {{ upload.fileName }}\n </Box>\n\n <Box v-if=\"isFailed\" v-bind=\"getStyles('attachmentPreviewError')\" role=\"alert\">\n {{ upload.error || config.labels.uploadFailed }}\n </Box>\n\n <Box v-else v-bind=\"getStyles('attachmentPreviewMeta')\">{{ metaText }}</Box>\n\n <Progress\n v-if=\"isUploading\"\n v-bind=\"getStyles('attachmentPreviewProgress')\"\n size=\"xs\"\n :value=\"progressValue\"\n :animated=\"upload.progress === undefined\"\n :aria-label=\"config.labels.uploading\"\n />\n </Box>\n\n <Box v-bind=\"getStyles('attachmentPreviewActions')\">\n <ActionIcon\n v-if=\"isFailed\"\n variant=\"subtle\"\n color=\"red\"\n size=\"sm\"\n :aria-label=\"`${config.labels.retryUpload}: ${upload.fileName}`\"\n @click=\"emit('retry', upload)\"\n >\n <WhatsAppIcon name=\"refresh\" size=\"16\" />\n </ActionIcon>\n\n <ActionIcon\n v-if=\"isUploading\"\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n :aria-label=\"`${config.labels.cancelUpload}: ${upload.fileName}`\"\n @click=\"emit('cancel', upload)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n\n <ActionIcon\n v-else-if=\"props.withRemove\"\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n :aria-label=\"`${config.labels.removeAttachment}: ${upload.fileName}`\"\n @click=\"emit('remove', upload)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppAttachmentPreviewComponent from './WhatsAppAttachmentPreview.vue'\nimport type { WhatsAppAttachmentPreviewFactory } from './WhatsAppAttachmentPreview.types'\nimport classes from './WhatsAppAttachmentPreview.module.css'\n\nexport const WhatsAppAttachmentPreview = factory<WhatsAppAttachmentPreviewFactory>(\n WhatsAppAttachmentPreviewComponent,\n { classes },\n)\n\nexport type {\n WhatsAppAttachmentPreviewEmits,\n WhatsAppAttachmentPreviewFactory,\n WhatsAppAttachmentPreviewOwnProps,\n WhatsAppAttachmentPreviewProps,\n WhatsAppAttachmentPreviewStylesNames,\n} from './WhatsAppAttachmentPreview.types'\n",".emojiPickerRoot {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-xs);\n width: var(--wa-emoji-width, 340px);\n max-width: 100%;\n}\n\n.emojiPickerSearch {\n width: 100%;\n}\n\n.emojiPickerTabs {\n display: flex;\n align-items: center;\n gap: 2px;\n border-bottom: 1px solid var(--mantine-color-default-border);\n padding-bottom: 4px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.emojiPickerTabs::-webkit-scrollbar {\n display: none;\n}\n\n.emojiPickerTab {\n flex: 1;\n min-width: 30px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px 0;\n font-size: 17px;\n line-height: 1;\n border-radius: var(--mantine-radius-sm);\n opacity: 0.45;\n border-bottom: 2px solid transparent;\n}\n\n.emojiPickerTab:where([data-active]) {\n opacity: 1;\n border-bottom-color: var(--mantine-primary-color-filled);\n}\n\n.emojiPickerTab {\n @mixin hover {\n opacity: 1;\n background-color: var(--mantine-color-default-hover);\n }\n}\n\n.emojiPickerBody {\n height: var(--wa-emoji-height, 260px);\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n.emojiPickerGroup {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.emojiPickerGroupLabel {\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 4px 2px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mantine-color-dimmed);\n background-color: var(--mantine-color-body);\n}\n\n.emojiPickerGrid {\n display: grid;\n grid-template-columns: repeat(var(--wa-emoji-columns, 8), minmax(0, 1fr));\n gap: 2px;\n padding-bottom: var(--mantine-spacing-xs);\n}\n\n.emojiPickerItem {\n display: flex;\n align-items: center;\n justify-content: center;\n aspect-ratio: 1;\n font-size: 22px;\n line-height: 1;\n border-radius: var(--mantine-radius-sm);\n}\n\n.emojiPickerItem {\n @mixin hover {\n background-color: var(--mantine-color-default-hover);\n }\n}\n\n.emojiPickerItem:where(:focus-visible) {\n background-color: var(--mantine-color-default-hover);\n}\n\n.emojiPickerEmpty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n font-size: var(--mantine-font-size-sm);\n color: var(--mantine-color-dimmed);\n}\n\n.emojiPickerPreview {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n min-height: 28px;\n border-top: 1px solid var(--mantine-color-default-border);\n padding-top: 6px;\n}\n\n.emojiPickerPreviewEmoji {\n font-size: 22px;\n line-height: 1;\n}\n\n.emojiPickerPreviewName {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n recentLimit: 24,\n withRecent: true,\n withSearch: true,\n withTabs: true,\n withPreview: true,\n columns: 8,\n} as const\n\nfunction toCssLength(value: string | number | undefined) {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'number' ? `${value}px` : value\n}\n\nconst varsResolver = createVarsResolver<any>((_, { columns, height, width }) => ({\n emojiPickerRoot: {\n '--wa-emoji-columns': columns === undefined ? undefined : String(columns),\n '--wa-emoji-height': toCssLength(height),\n '--wa-emoji-width': toCssLength(width),\n },\n}))\n\nexport { defaultProps, toCssLength, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch } from 'vue'\nimport { Box, TextInput, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport {\n filterEmojis,\n getEmojiGroups,\n searchEmojis,\n WHATSAPP_EMOJI_GROUPS,\n WHATSAPP_EMOJIS_BY_CHAR,\n type WhatsAppEmoji,\n type WhatsAppEmojiGroupId,\n} from '../../emoji'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppEmojiPickerEmits,\n WhatsAppEmojiPickerOwnProps,\n WhatsAppEmojiPickerSlots,\n} from './WhatsAppEmojiPicker.types'\nimport classes from './WhatsAppEmojiPicker.module.css'\n\ndefineOptions({\n name: 'WhatsAppEmojiPicker',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppEmojiPickerOwnProps>(), {\n search: undefined,\n defaultSearch: undefined,\n recentEmojis: undefined,\n defaultRecentEmojis: undefined,\n recentLimit: undefined,\n withRecent: undefined,\n withSearch: undefined,\n withTabs: undefined,\n withPreview: undefined,\n columns: undefined,\n height: undefined,\n width: undefined,\n groups: undefined,\n excludeGroups: undefined,\n emojis: undefined,\n excludeEmojis: undefined,\n filter: undefined,\n emojiData: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppEmojiPickerEmits>()\ndefineSlots<WhatsAppEmojiPickerSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppEmojiPicker', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppEmojiPicker',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'emojiPickerRoot',\n})\n\nconst [search, setSearch] = useUncontrolled<string>({\n value: () => props.search,\n defaultValue: props.defaultSearch,\n finalValue: '',\n onChange: (value) => emit('update:search', value),\n})\n\nconst [recent, setRecent] = useUncontrolled<string[]>({\n value: () => props.recentEmojis,\n defaultValue: props.defaultRecentEmojis,\n finalValue: [],\n onChange: (value) => emit('update:recentEmojis', value),\n})\n\nconst available = computed(() =>\n filterEmojis({\n groups: props.groups,\n excludeGroups: props.excludeGroups,\n emojis: props.emojis,\n excludeEmojis: props.excludeEmojis,\n filter: props.filter,\n emojiData: props.emojiData,\n }),\n)\n\nconst availableChars = computed(() => new Set(available.value.map((entry) => entry.emoji)))\n\n/**\n * Recently used entries, resolved back to full records.\n *\n * Filtered against what is currently available, so an emoji that a later policy change put out of\n * reach does not linger in the recent row.\n */\nconst recentEmojis = computed<WhatsAppEmoji[]>(() => {\n if (!props.withRecent) {\n return []\n }\n\n return recent.value\n .filter((char) => availableChars.value.has(char))\n .map((char) => WHATSAPP_EMOJIS_BY_CHAR.get(char))\n .filter((entry): entry is WhatsAppEmoji => entry !== undefined)\n .map((entry) => ({ ...entry, group: 'recent' as const }))\n})\n\nconst matches = computed(() => searchEmojis(available.value, search.value))\nconst searching = computed(() => search.value.trim().length > 0)\n\nconst sections = computed(() => {\n if (searching.value) {\n return matches.value.length > 0\n ? [{ group: 'recent' as WhatsAppEmojiGroupId, emojis: matches.value, isResults: true }]\n : []\n }\n\n const groups = getEmojiGroups(available.value, props.groups)\n const result: { group: WhatsAppEmojiGroupId; emojis: WhatsAppEmoji[]; isResults: boolean }[] = []\n\n if (recentEmojis.value.length > 0) {\n result.push({ group: 'recent', emojis: recentEmojis.value, isResults: false })\n }\n\n for (const group of groups) {\n result.push({\n group,\n emojis: available.value.filter((entry) => entry.group === group),\n isResults: false,\n })\n }\n\n return result\n})\n\nconst tabs = computed(() => {\n const present = new Set(sections.value.map((section) => section.group))\n\n return WHATSAPP_EMOJI_GROUPS.filter((group) => present.has(group.id))\n})\n\nconst activeGroup = ref<WhatsAppEmojiGroupId>('smileys')\nconst previewEmoji = ref<WhatsAppEmoji | null>(null)\n\nconst bodyElement = ref<HTMLDivElement | null>(null)\nconst sectionElements = new Map<WhatsAppEmojiGroupId, HTMLElement>()\n\nfunction registerSection(group: WhatsAppEmojiGroupId, element: Element | null) {\n if (element) {\n sectionElements.set(group, element as HTMLElement)\n } else {\n sectionElements.delete(group)\n }\n}\n\nfunction scrollToGroup(group: WhatsAppEmojiGroupId) {\n const body = bodyElement.value\n const section = sectionElements.get(group)\n\n if (body && section) {\n body.scrollTop = section.offsetTop\n }\n\n activeGroup.value = group\n emit('groupChange', group)\n}\n\n/** Synchronizes the active tab with the scroll position. */\nfunction handleScroll() {\n const body = bodyElement.value\n\n if (!body || searching.value) {\n return\n }\n\n let current = sections.value[0]?.group\n\n for (const section of sections.value) {\n const element = sectionElements.get(section.group)\n\n if (element && element.offsetTop - body.scrollTop <= 8) {\n current = section.group\n }\n }\n\n if (current && current !== activeGroup.value) {\n activeGroup.value = current\n emit('groupChange', current)\n }\n}\n\nwatch(sections, () => {\n const first = sections.value[0]?.group\n\n if (first && !sections.value.some((section) => section.group === activeGroup.value)) {\n activeGroup.value = first\n }\n})\n\n/**\n * Flat list of every rendered emoji, used by the arrow keys.\n *\n * The grid uses roving tabindex so only one emoji button is in the tab order.\n */\nconst flatEmojis = computed(() => sections.value.flatMap((section) => section.emojis))\n\nconst activeIndex = ref(0)\n\nwatch(flatEmojis, () => {\n activeIndex.value = 0\n})\n\nfunction focusIndex(index: number) {\n const clamped = Math.max(0, Math.min(index, flatEmojis.value.length - 1))\n activeIndex.value = clamped\n\n void nextTick(() => {\n const target = bodyElement.value?.querySelectorAll<HTMLElement>('[data-emoji-index]')[clamped]\n\n target?.focus()\n previewEmoji.value = flatEmojis.value[clamped] ?? null\n })\n}\n\nfunction handleItemFocus(index: number, entry: WhatsAppEmoji) {\n activeIndex.value = index\n previewEmoji.value = entry\n}\n\nfunction handleGridKeydown(event: KeyboardEvent) {\n const columns = props.columns ?? defaultProps.columns\n const keys: Record<string, number> = {\n ArrowRight: 1,\n ArrowLeft: -1,\n ArrowDown: columns,\n ArrowUp: -columns,\n }\n\n if (event.key in keys) {\n event.preventDefault()\n focusIndex(activeIndex.value + keys[event.key])\n return\n }\n\n if (event.key === 'Home') {\n event.preventDefault()\n focusIndex(0)\n }\n\n if (event.key === 'End') {\n event.preventDefault()\n focusIndex(flatEmojis.value.length - 1)\n }\n}\n\nfunction select(emoji: WhatsAppEmoji) {\n const next = [emoji.emoji, ...recent.value.filter((char) => char !== emoji.emoji)].slice(\n 0,\n props.recentLimit ?? defaultProps.recentLimit,\n )\n\n setRecent(next)\n emit('select', emoji)\n}\n\nfunction indexOf(section: number, item: number) {\n let offset = 0\n\n for (let index = 0; index < section; index += 1) {\n offset += sections.value[index].emojis.length\n }\n\n return offset + item\n}\n\nfunction groupLabel(group: WhatsAppEmojiGroupId, isResults: boolean) {\n if (isResults) {\n return config.labels.emojiPickerSearchResults\n }\n\n const meta = WHATSAPP_EMOJI_GROUPS.find((entry) => entry.id === group)\n\n return meta ? config.labels[meta.labelKey] : group\n}\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('emojiPickerRoot') }\"\n role=\"group\"\n :aria-label=\"config.labels.emojiPickerLabel\"\n >\n <TextInput\n v-if=\"props.withSearch\"\n v-bind=\"getStyles('emojiPickerSearch')\"\n size=\"xs\"\n type=\"search\"\n :model-value=\"search\"\n :placeholder=\"config.labels.emojiPickerSearchPlaceholder\"\n :aria-label=\"config.labels.emojiPickerSearchPlaceholder\"\n @update:model-value=\"setSearch($event)\"\n >\n <template #leftSection>\n <WhatsAppIcon name=\"search\" size=\"14\" />\n </template>\n </TextInput>\n\n <Box\n v-if=\"props.withTabs && !searching && tabs.length > 1\"\n v-bind=\"getStyles('emojiPickerTabs')\"\n role=\"tablist\"\n :aria-label=\"config.labels.emojiPickerLabel\"\n >\n <UnstyledButton\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n v-bind=\"getStyles('emojiPickerTab')\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"tab.id === activeGroup\"\n :aria-label=\"config.labels[tab.labelKey] as string\"\n :title=\"config.labels[tab.labelKey] as string\"\n :data-active=\"tab.id === activeGroup ? '' : undefined\"\n @click=\"scrollToGroup(tab.id)\"\n >\n {{ tab.icon }}\n </UnstyledButton>\n </Box>\n\n <div ref=\"bodyElement\" v-bind=\"getStyles('emojiPickerBody')\" @scroll=\"handleScroll\">\n <Box v-if=\"sections.length === 0\" v-bind=\"getStyles('emojiPickerEmpty')\">\n <slot v-if=\"slots.emptyEmojis\" name=\"emptyEmojis\" :search=\"search\" />\n <template v-else>{{ config.labels.emojiPickerNoResults }}</template>\n </Box>\n\n <Box\n v-for=\"(section, sectionIndex) in sections\"\n :key=\"section.group + (section.isResults ? '-results' : '')\"\n :root-ref=\"(node: Element | null) => registerSection(section.group, node)\"\n v-bind=\"getStyles('emojiPickerGroup')\"\n >\n <Box v-bind=\"getStyles('emojiPickerGroupLabel')\">\n {{ groupLabel(section.group, section.isResults) }}\n </Box>\n\n <Box v-bind=\"getStyles('emojiPickerGrid')\" role=\"group\" @keydown=\"handleGridKeydown\">\n <UnstyledButton\n v-for=\"(entry, itemIndex) in section.emojis\"\n :key=\"entry.emoji\"\n v-bind=\"getStyles('emojiPickerItem')\"\n type=\"button\"\n :data-emoji-index=\"indexOf(sectionIndex, itemIndex)\"\n :tabindex=\"indexOf(sectionIndex, itemIndex) === activeIndex ? 0 : -1\"\n :aria-label=\"entry.name\"\n :title=\"entry.name\"\n @click=\"select(entry)\"\n @focus=\"handleItemFocus(indexOf(sectionIndex, itemIndex), entry)\"\n @mouseenter=\"previewEmoji = entry\"\n >\n {{ entry.emoji }}\n </UnstyledButton>\n </Box>\n </Box>\n </div>\n\n <Box v-if=\"props.withPreview\" v-bind=\"getStyles('emojiPickerPreview')\">\n <slot v-if=\"slots.emojiPickerFooter\" name=\"emojiPickerFooter\" :emoji=\"previewEmoji\" />\n <template v-else-if=\"previewEmoji\">\n <Box component=\"span\" v-bind=\"getStyles('emojiPickerPreviewEmoji')\">\n {{ previewEmoji.emoji }}\n </Box>\n <Box component=\"span\" v-bind=\"getStyles('emojiPickerPreviewName')\">\n {{ previewEmoji.name }}\n </Box>\n </template>\n </Box>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n recentLimit: 24,\n withRecent: true,\n withSearch: true,\n withTabs: true,\n withPreview: true,\n columns: 8,\n} as const\n\nfunction toCssLength(value: string | number | undefined) {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'number' ? `${value}px` : value\n}\n\nconst varsResolver = createVarsResolver<any>((_, { columns, height, width }) => ({\n emojiPickerRoot: {\n '--wa-emoji-columns': columns === undefined ? undefined : String(columns),\n '--wa-emoji-height': toCssLength(height),\n '--wa-emoji-width': toCssLength(width),\n },\n}))\n\nexport { defaultProps, toCssLength, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch } from 'vue'\nimport { Box, TextInput, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport {\n filterEmojis,\n getEmojiGroups,\n searchEmojis,\n WHATSAPP_EMOJI_GROUPS,\n WHATSAPP_EMOJIS_BY_CHAR,\n type WhatsAppEmoji,\n type WhatsAppEmojiGroupId,\n} from '../../emoji'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppEmojiPickerEmits,\n WhatsAppEmojiPickerOwnProps,\n WhatsAppEmojiPickerSlots,\n} from './WhatsAppEmojiPicker.types'\nimport classes from './WhatsAppEmojiPicker.module.css'\n\ndefineOptions({\n name: 'WhatsAppEmojiPicker',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppEmojiPickerOwnProps>(), {\n search: undefined,\n defaultSearch: undefined,\n recentEmojis: undefined,\n defaultRecentEmojis: undefined,\n recentLimit: undefined,\n withRecent: undefined,\n withSearch: undefined,\n withTabs: undefined,\n withPreview: undefined,\n columns: undefined,\n height: undefined,\n width: undefined,\n groups: undefined,\n excludeGroups: undefined,\n emojis: undefined,\n excludeEmojis: undefined,\n filter: undefined,\n emojiData: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppEmojiPickerEmits>()\ndefineSlots<WhatsAppEmojiPickerSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppEmojiPicker', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppEmojiPicker',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'emojiPickerRoot',\n})\n\nconst [search, setSearch] = useUncontrolled<string>({\n value: () => props.search,\n defaultValue: props.defaultSearch,\n finalValue: '',\n onChange: (value) => emit('update:search', value),\n})\n\nconst [recent, setRecent] = useUncontrolled<string[]>({\n value: () => props.recentEmojis,\n defaultValue: props.defaultRecentEmojis,\n finalValue: [],\n onChange: (value) => emit('update:recentEmojis', value),\n})\n\nconst available = computed(() =>\n filterEmojis({\n groups: props.groups,\n excludeGroups: props.excludeGroups,\n emojis: props.emojis,\n excludeEmojis: props.excludeEmojis,\n filter: props.filter,\n emojiData: props.emojiData,\n }),\n)\n\nconst availableChars = computed(() => new Set(available.value.map((entry) => entry.emoji)))\n\n/**\n * Recently used entries, resolved back to full records.\n *\n * Filtered against what is currently available, so an emoji that a later policy change put out of\n * reach does not linger in the recent row.\n */\nconst recentEmojis = computed<WhatsAppEmoji[]>(() => {\n if (!props.withRecent) {\n return []\n }\n\n return recent.value\n .filter((char) => availableChars.value.has(char))\n .map((char) => WHATSAPP_EMOJIS_BY_CHAR.get(char))\n .filter((entry): entry is WhatsAppEmoji => entry !== undefined)\n .map((entry) => ({ ...entry, group: 'recent' as const }))\n})\n\nconst matches = computed(() => searchEmojis(available.value, search.value))\nconst searching = computed(() => search.value.trim().length > 0)\n\nconst sections = computed(() => {\n if (searching.value) {\n return matches.value.length > 0\n ? [{ group: 'recent' as WhatsAppEmojiGroupId, emojis: matches.value, isResults: true }]\n : []\n }\n\n const groups = getEmojiGroups(available.value, props.groups)\n const result: { group: WhatsAppEmojiGroupId; emojis: WhatsAppEmoji[]; isResults: boolean }[] = []\n\n if (recentEmojis.value.length > 0) {\n result.push({ group: 'recent', emojis: recentEmojis.value, isResults: false })\n }\n\n for (const group of groups) {\n result.push({\n group,\n emojis: available.value.filter((entry) => entry.group === group),\n isResults: false,\n })\n }\n\n return result\n})\n\nconst tabs = computed(() => {\n const present = new Set(sections.value.map((section) => section.group))\n\n return WHATSAPP_EMOJI_GROUPS.filter((group) => present.has(group.id))\n})\n\nconst activeGroup = ref<WhatsAppEmojiGroupId>('smileys')\nconst previewEmoji = ref<WhatsAppEmoji | null>(null)\n\nconst bodyElement = ref<HTMLDivElement | null>(null)\nconst sectionElements = new Map<WhatsAppEmojiGroupId, HTMLElement>()\n\nfunction registerSection(group: WhatsAppEmojiGroupId, element: Element | null) {\n if (element) {\n sectionElements.set(group, element as HTMLElement)\n } else {\n sectionElements.delete(group)\n }\n}\n\nfunction scrollToGroup(group: WhatsAppEmojiGroupId) {\n const body = bodyElement.value\n const section = sectionElements.get(group)\n\n if (body && section) {\n body.scrollTop = section.offsetTop\n }\n\n activeGroup.value = group\n emit('groupChange', group)\n}\n\n/** Synchronizes the active tab with the scroll position. */\nfunction handleScroll() {\n const body = bodyElement.value\n\n if (!body || searching.value) {\n return\n }\n\n let current = sections.value[0]?.group\n\n for (const section of sections.value) {\n const element = sectionElements.get(section.group)\n\n if (element && element.offsetTop - body.scrollTop <= 8) {\n current = section.group\n }\n }\n\n if (current && current !== activeGroup.value) {\n activeGroup.value = current\n emit('groupChange', current)\n }\n}\n\nwatch(sections, () => {\n const first = sections.value[0]?.group\n\n if (first && !sections.value.some((section) => section.group === activeGroup.value)) {\n activeGroup.value = first\n }\n})\n\n/**\n * Flat list of every rendered emoji, used by the arrow keys.\n *\n * The grid uses roving tabindex so only one emoji button is in the tab order.\n */\nconst flatEmojis = computed(() => sections.value.flatMap((section) => section.emojis))\n\nconst activeIndex = ref(0)\n\nwatch(flatEmojis, () => {\n activeIndex.value = 0\n})\n\nfunction focusIndex(index: number) {\n const clamped = Math.max(0, Math.min(index, flatEmojis.value.length - 1))\n activeIndex.value = clamped\n\n void nextTick(() => {\n const target = bodyElement.value?.querySelectorAll<HTMLElement>('[data-emoji-index]')[clamped]\n\n target?.focus()\n previewEmoji.value = flatEmojis.value[clamped] ?? null\n })\n}\n\nfunction handleItemFocus(index: number, entry: WhatsAppEmoji) {\n activeIndex.value = index\n previewEmoji.value = entry\n}\n\nfunction handleGridKeydown(event: KeyboardEvent) {\n const columns = props.columns ?? defaultProps.columns\n const keys: Record<string, number> = {\n ArrowRight: 1,\n ArrowLeft: -1,\n ArrowDown: columns,\n ArrowUp: -columns,\n }\n\n if (event.key in keys) {\n event.preventDefault()\n focusIndex(activeIndex.value + keys[event.key])\n return\n }\n\n if (event.key === 'Home') {\n event.preventDefault()\n focusIndex(0)\n }\n\n if (event.key === 'End') {\n event.preventDefault()\n focusIndex(flatEmojis.value.length - 1)\n }\n}\n\nfunction select(emoji: WhatsAppEmoji) {\n const next = [emoji.emoji, ...recent.value.filter((char) => char !== emoji.emoji)].slice(\n 0,\n props.recentLimit ?? defaultProps.recentLimit,\n )\n\n setRecent(next)\n emit('select', emoji)\n}\n\nfunction indexOf(section: number, item: number) {\n let offset = 0\n\n for (let index = 0; index < section; index += 1) {\n offset += sections.value[index].emojis.length\n }\n\n return offset + item\n}\n\nfunction groupLabel(group: WhatsAppEmojiGroupId, isResults: boolean) {\n if (isResults) {\n return config.labels.emojiPickerSearchResults\n }\n\n const meta = WHATSAPP_EMOJI_GROUPS.find((entry) => entry.id === group)\n\n return meta ? config.labels[meta.labelKey] : group\n}\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('emojiPickerRoot') }\"\n role=\"group\"\n :aria-label=\"config.labels.emojiPickerLabel\"\n >\n <TextInput\n v-if=\"props.withSearch\"\n v-bind=\"getStyles('emojiPickerSearch')\"\n size=\"xs\"\n type=\"search\"\n :model-value=\"search\"\n :placeholder=\"config.labels.emojiPickerSearchPlaceholder\"\n :aria-label=\"config.labels.emojiPickerSearchPlaceholder\"\n @update:model-value=\"setSearch($event)\"\n >\n <template #leftSection>\n <WhatsAppIcon name=\"search\" size=\"14\" />\n </template>\n </TextInput>\n\n <Box\n v-if=\"props.withTabs && !searching && tabs.length > 1\"\n v-bind=\"getStyles('emojiPickerTabs')\"\n role=\"tablist\"\n :aria-label=\"config.labels.emojiPickerLabel\"\n >\n <UnstyledButton\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n v-bind=\"getStyles('emojiPickerTab')\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"tab.id === activeGroup\"\n :aria-label=\"config.labels[tab.labelKey] as string\"\n :title=\"config.labels[tab.labelKey] as string\"\n :data-active=\"tab.id === activeGroup ? '' : undefined\"\n @click=\"scrollToGroup(tab.id)\"\n >\n {{ tab.icon }}\n </UnstyledButton>\n </Box>\n\n <div ref=\"bodyElement\" v-bind=\"getStyles('emojiPickerBody')\" @scroll=\"handleScroll\">\n <Box v-if=\"sections.length === 0\" v-bind=\"getStyles('emojiPickerEmpty')\">\n <slot v-if=\"slots.emptyEmojis\" name=\"emptyEmojis\" :search=\"search\" />\n <template v-else>{{ config.labels.emojiPickerNoResults }}</template>\n </Box>\n\n <Box\n v-for=\"(section, sectionIndex) in sections\"\n :key=\"section.group + (section.isResults ? '-results' : '')\"\n :root-ref=\"(node: Element | null) => registerSection(section.group, node)\"\n v-bind=\"getStyles('emojiPickerGroup')\"\n >\n <Box v-bind=\"getStyles('emojiPickerGroupLabel')\">\n {{ groupLabel(section.group, section.isResults) }}\n </Box>\n\n <Box v-bind=\"getStyles('emojiPickerGrid')\" role=\"group\" @keydown=\"handleGridKeydown\">\n <UnstyledButton\n v-for=\"(entry, itemIndex) in section.emojis\"\n :key=\"entry.emoji\"\n v-bind=\"getStyles('emojiPickerItem')\"\n type=\"button\"\n :data-emoji-index=\"indexOf(sectionIndex, itemIndex)\"\n :tabindex=\"indexOf(sectionIndex, itemIndex) === activeIndex ? 0 : -1\"\n :aria-label=\"entry.name\"\n :title=\"entry.name\"\n @click=\"select(entry)\"\n @focus=\"handleItemFocus(indexOf(sectionIndex, itemIndex), entry)\"\n @mouseenter=\"previewEmoji = entry\"\n >\n {{ entry.emoji }}\n </UnstyledButton>\n </Box>\n </Box>\n </div>\n\n <Box v-if=\"props.withPreview\" v-bind=\"getStyles('emojiPickerPreview')\">\n <slot v-if=\"slots.emojiPickerFooter\" name=\"emojiPickerFooter\" :emoji=\"previewEmoji\" />\n <template v-else-if=\"previewEmoji\">\n <Box component=\"span\" v-bind=\"getStyles('emojiPickerPreviewEmoji')\">\n {{ previewEmoji.emoji }}\n </Box>\n <Box component=\"span\" v-bind=\"getStyles('emojiPickerPreviewName')\">\n {{ previewEmoji.name }}\n </Box>\n </template>\n </Box>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppEmojiPickerComponent from './WhatsAppEmojiPicker.vue'\nimport type { WhatsAppEmojiPickerFactory } from './WhatsAppEmojiPicker.types'\nimport classes from './WhatsAppEmojiPicker.module.css'\n\nexport const WhatsAppEmojiPicker = factory<WhatsAppEmojiPickerFactory>(\n WhatsAppEmojiPickerComponent,\n { classes },\n)\n\nexport type {\n WhatsAppEmojiPickerEmits,\n WhatsAppEmojiPickerFactory,\n WhatsAppEmojiPickerOwnProps,\n WhatsAppEmojiPickerProps,\n WhatsAppEmojiPickerSlots,\n WhatsAppEmojiPickerStylesNames,\n} from './WhatsAppEmojiPicker.types'\n",".interactiveEditorRoot {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-sm);\n}\n\n.interactiveEditorSection {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-xs);\n}\n\n.interactiveEditorSectionTitle {\n font-size: var(--mantine-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mantine-color-dimmed);\n}\n\n.interactiveEditorRow {\n display: flex;\n align-items: flex-end;\n gap: var(--mantine-spacing-xs);\n}\n\n.interactiveEditorItem {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-xs);\n border-radius: var(--mantine-radius-md);\n border: 1px solid var(--mantine-color-default-border);\n}\n\n.interactiveEditorFooter {\n display: flex;\n justify-content: flex-end;\n gap: var(--mantine-spacing-xs);\n padding-top: var(--mantine-spacing-xs);\n border-top: 1px solid var(--mantine-color-default-border);\n}\n","<script lang=\"ts\">\nimport type { WhatsAppInteractiveContent, WhatsAppInteractiveType } from '../../types'\nimport { createClientId } from '../../utils'\n\nconst defaultProps = {\n maxButtons: 3,\n maxRowsPerSection: 10,\n disabled: false,\n} as const\n\n/**\n * A fresh, well-formed draft of the given type.\n *\n * The draft is always a valid `WhatsAppInteractiveContent`, never a loose bag of fields: the\n * `v-model` a consumer binds is the same discriminated union the message would be sent with, so\n * there is nothing to translate on submit.\n */\nfunction createInteractiveDraft(\n type: WhatsAppInteractiveType,\n previous?: WhatsAppInteractiveContent,\n): WhatsAppInteractiveContent {\n const shared = {\n header: previous?.header,\n body: previous?.body ?? '',\n footer: previous?.footer,\n }\n\n if (type === 'cta_url') {\n return { ...shared, type: 'cta_url', action: { displayText: '', url: '' } }\n }\n\n if (type === 'list') {\n return {\n ...shared,\n type: 'list',\n button: '',\n sections: [{ title: '', rows: [{ id: createClientId(), title: '', description: '' }] }],\n }\n }\n\n return { ...shared, type: 'button', buttons: [{ id: createClientId(), title: '' }] }\n}\n\nexport { createInteractiveDraft, defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs } from 'vue'\nimport {\n ActionIcon,\n Box,\n Button,\n SegmentedControl,\n Text,\n TextInput,\n Textarea,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppInteractiveButtonContent,\n WhatsAppInteractiveCtaUrlContent,\n WhatsAppInteractiveListContent,\n} from '../../types'\nimport type {\n WhatsAppInteractiveMessageEditorEmits,\n WhatsAppInteractiveMessageEditorOwnProps,\n} from './WhatsAppInteractiveMessageEditor.types'\nimport classes from './WhatsAppInteractiveMessageEditor.module.css'\n\ndefineOptions({\n name: 'WhatsAppInteractiveMessageEditor',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInteractiveMessageEditorOwnProps>(), {\n modelValue: undefined,\n defaultValue: undefined,\n interactiveTypes: undefined,\n maxButtons: undefined,\n maxRowsPerSection: undefined,\n disabled: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppInteractiveMessageEditorEmits>()\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInteractiveMessageEditor', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInteractiveMessageEditor',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'interactiveEditorRoot',\n})\n\nconst availableTypes = computed<WhatsAppInteractiveType[]>(() =>\n props.interactiveTypes && props.interactiveTypes.length > 0 ? props.interactiveTypes : ['button'],\n)\n\nconst [content, setContent] = useUncontrolled<WhatsAppInteractiveContent>({\n value: () => props.modelValue,\n defaultValue: props.defaultValue,\n finalValue: createInteractiveDraft(props.interactiveTypes?.[0] ?? 'button'),\n onChange: (value) => emit('update:modelValue', value),\n})\n\nconst typeOptions = computed(() =>\n availableTypes.value.map((type) => ({\n value: type,\n label:\n type === 'button'\n ? config.labels.interactiveTypeButton\n : type === 'cta_url'\n ? config.labels.interactiveTypeCtaUrl\n : config.labels.interactiveTypeList,\n })),\n)\n\nconst buttonContent = computed(() =>\n content.value.type === 'button' ? (content.value as WhatsAppInteractiveButtonContent) : undefined,\n)\nconst ctaContent = computed(() =>\n content.value.type === 'cta_url'\n ? (content.value as WhatsAppInteractiveCtaUrlContent)\n : undefined,\n)\nconst listContent = computed(() =>\n content.value.type === 'list' ? (content.value as WhatsAppInteractiveListContent) : undefined,\n)\n\nconst errors = computed(() => {\n const current = content.value\n const result: { body?: string; buttons?: string; url?: string; rows?: string } = {}\n\n if (current.body.trim().length === 0) {\n result.body = config.labels.interactiveBodyRequired\n }\n\n if (current.type === 'button' && !current.buttons.some((button) => button.title.trim())) {\n result.buttons = config.labels.interactiveButtonsRequired\n }\n\n if (\n current.type === 'cta_url' &&\n (current.action.displayText.trim().length === 0 ||\n !/^https?:\\/\\/\\S+$/i.test(current.action.url))\n ) {\n result.url = config.labels.interactiveUrlRequired\n }\n\n if (current.type === 'list') {\n const hasRow = current.sections.some((section) =>\n section.rows.some((row) => row.title.trim().length > 0),\n )\n\n if (!hasRow || current.button.trim().length === 0) {\n result.rows = config.labels.interactiveRowsRequired\n }\n }\n\n return result\n})\n\nconst valid = computed(() => Object.keys(errors.value).length === 0)\n\nconst submitted = ref(false)\n\nfunction changeType(type: WhatsAppInteractiveType) {\n setContent(createInteractiveDraft(type, content.value))\n}\n\nfunction patch(partial: Partial<WhatsAppInteractiveContent>) {\n setContent({ ...content.value, ...partial } as WhatsAppInteractiveContent)\n}\n\nfunction setButtonTitle(index: number, title: string) {\n const current = buttonContent.value\n\n if (!current) {\n return\n }\n\n const buttons = current.buttons.map((button, buttonIndex) =>\n buttonIndex === index ? { ...button, title } : button,\n )\n\n setContent({ ...current, buttons })\n}\n\nfunction addButton() {\n const current = buttonContent.value\n\n if (!current || current.buttons.length >= (props.maxButtons ?? defaultProps.maxButtons)) {\n return\n }\n\n setContent({ ...current, buttons: [...current.buttons, { id: createClientId(), title: '' }] })\n}\n\nfunction removeButton(index: number) {\n const current = buttonContent.value\n\n if (!current || current.buttons.length <= 1) {\n return\n }\n\n setContent({\n ...current,\n buttons: current.buttons.filter((_, buttonIndex) => buttonIndex !== index),\n })\n}\n\nfunction setAction(partial: Partial<WhatsAppInteractiveCtaUrlContent['action']>) {\n const current = ctaContent.value\n\n if (!current) {\n return\n }\n\n setContent({ ...current, action: { ...current.action, ...partial } })\n}\n\nfunction setSectionTitle(sectionIndex: number, title: string) {\n const current = listContent.value\n\n if (!current) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex ? { ...section, title } : section,\n ),\n })\n}\n\nfunction setRow(\n sectionIndex: number,\n rowIndex: number,\n partial: { title?: string; description?: string },\n) {\n const current = listContent.value\n\n if (!current) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex\n ? {\n ...section,\n rows: section.rows.map((row, currentRowIndex) =>\n currentRowIndex === rowIndex ? { ...row, ...partial } : row,\n ),\n }\n : section,\n ),\n })\n}\n\nfunction addRow(sectionIndex: number) {\n const current = listContent.value\n const max = props.maxRowsPerSection ?? defaultProps.maxRowsPerSection\n\n if (!current || current.sections[sectionIndex].rows.length >= max) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex\n ? {\n ...section,\n rows: [...section.rows, { id: createClientId(), title: '', description: '' }],\n }\n : section,\n ),\n })\n}\n\nfunction removeRow(sectionIndex: number, rowIndex: number) {\n const current = listContent.value\n\n if (!current || current.sections[sectionIndex].rows.length <= 1) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex\n ? { ...section, rows: section.rows.filter((_, currentIndex) => currentIndex !== rowIndex) }\n : section,\n ),\n })\n}\n\nfunction addSection() {\n const current = listContent.value\n\n if (!current) {\n return\n }\n\n setContent({\n ...current,\n sections: [\n ...current.sections,\n { title: '', rows: [{ id: createClientId(), title: '', description: '' }] },\n ],\n })\n}\n\nfunction removeSection(sectionIndex: number) {\n const current = listContent.value\n\n if (!current || current.sections.length <= 1) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.filter((_, index) => index !== sectionIndex),\n })\n}\n\nfunction submit() {\n submitted.value = true\n\n if (valid.value) {\n emit('submit', content.value)\n }\n}\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('interactiveEditorRoot') }\">\n <SegmentedControl\n v-if=\"typeOptions.length > 1\"\n :model-value=\"content.type\"\n :data=\"typeOptions\"\n :disabled=\"props.disabled\"\n size=\"xs\"\n full-width\n :aria-label=\"config.labels.interactiveType\"\n @update:model-value=\"changeType($event as any)\"\n />\n\n <TextInput\n size=\"sm\"\n :label=\"config.labels.interactiveHeader\"\n :disabled=\"props.disabled\"\n :model-value=\"content.header?.text ?? ''\"\n @update:model-value=\"patch({ header: $event ? { type: 'text', text: $event } : undefined })\"\n />\n\n <Textarea\n size=\"sm\"\n autosize\n :min-rows=\"2\"\n :max-rows=\"6\"\n required\n :label=\"config.labels.interactiveBody\"\n :disabled=\"props.disabled\"\n :error=\"submitted ? errors.body : undefined\"\n :model-value=\"content.body\"\n @update:model-value=\"patch({ body: $event })\"\n />\n\n <TextInput\n size=\"sm\"\n :label=\"config.labels.interactiveFooter\"\n :disabled=\"props.disabled\"\n :model-value=\"content.footer ?? ''\"\n @update:model-value=\"patch({ footer: $event || undefined })\"\n />\n\n <Box v-if=\"buttonContent\" v-bind=\"getStyles('interactiveEditorSection')\">\n <Box v-bind=\"getStyles('interactiveEditorSectionTitle')\">\n {{ config.labels.interactiveButtons }}\n </Box>\n\n <Box\n v-for=\"(button, index) in buttonContent.buttons\"\n :key=\"button.id\"\n v-bind=\"getStyles('interactiveEditorRow')\"\n >\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveButtonText} ${index + 1}`\"\n :placeholder=\"config.labels.interactiveButtonText\"\n :disabled=\"props.disabled\"\n :model-value=\"button.title\"\n @update:model-value=\"setButtonTitle(index, $event)\"\n />\n\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || buttonContent.buttons.length <= 1\"\n :aria-label=\"`${config.labels.interactiveRemoveButton} ${index + 1}`\"\n @click=\"removeButton(index)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Text v-if=\"submitted && errors.buttons\" size=\"xs\" c=\"red\">{{ errors.buttons }}</Text>\n\n <Button\n variant=\"subtle\"\n size=\"xs\"\n :disabled=\"props.disabled || buttonContent.buttons.length >= (props.maxButtons ?? 3)\"\n @click=\"addButton\"\n >\n <WhatsAppIcon name=\"plus\" size=\"14\" />\n {{ config.labels.interactiveAddButton }}\n </Button>\n </Box>\n\n <Box v-else-if=\"ctaContent\" v-bind=\"getStyles('interactiveEditorSection')\">\n <TextInput\n size=\"sm\"\n required\n :label=\"config.labels.interactiveCtaDisplayText\"\n :disabled=\"props.disabled\"\n :model-value=\"ctaContent.action.displayText\"\n @update:model-value=\"setAction({ displayText: $event })\"\n />\n\n <TextInput\n size=\"sm\"\n required\n type=\"url\"\n placeholder=\"https://\"\n :label=\"config.labels.interactiveCtaUrl\"\n :disabled=\"props.disabled\"\n :error=\"submitted ? errors.url : undefined\"\n :model-value=\"ctaContent.action.url\"\n @update:model-value=\"setAction({ url: $event })\"\n />\n </Box>\n\n <Box v-else-if=\"listContent\" v-bind=\"getStyles('interactiveEditorSection')\">\n <TextInput\n size=\"sm\"\n required\n :label=\"config.labels.interactiveListButton\"\n :disabled=\"props.disabled\"\n :model-value=\"listContent.button\"\n @update:model-value=\"patch({ button: $event } as any)\"\n />\n\n <Box v-bind=\"getStyles('interactiveEditorSectionTitle')\">\n {{ config.labels.interactiveListSections }}\n </Box>\n\n <Box\n v-for=\"(section, sectionIndex) in listContent.sections\"\n :key=\"sectionIndex\"\n v-bind=\"getStyles('interactiveEditorItem')\"\n >\n <Box v-bind=\"getStyles('interactiveEditorRow')\">\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveSectionTitle} ${sectionIndex + 1}`\"\n :placeholder=\"config.labels.interactiveSectionTitle\"\n :disabled=\"props.disabled\"\n :model-value=\"section.title ?? ''\"\n @update:model-value=\"setSectionTitle(sectionIndex, $event)\"\n />\n\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || listContent.sections.length <= 1\"\n :aria-label=\"`${config.labels.interactiveRemoveSection} ${sectionIndex + 1}`\"\n @click=\"removeSection(sectionIndex)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Box\n v-for=\"(row, rowIndex) in section.rows\"\n :key=\"row.id\"\n v-bind=\"getStyles('interactiveEditorRow')\"\n >\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveRowTitle} ${rowIndex + 1}`\"\n :placeholder=\"config.labels.interactiveRowTitle\"\n :disabled=\"props.disabled\"\n :model-value=\"row.title\"\n @update:model-value=\"setRow(sectionIndex, rowIndex, { title: $event })\"\n />\n\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveRowDescription} ${rowIndex + 1}`\"\n :placeholder=\"config.labels.interactiveRowDescription\"\n :disabled=\"props.disabled\"\n :model-value=\"row.description ?? ''\"\n @update:model-value=\"setRow(sectionIndex, rowIndex, { description: $event })\"\n />\n\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || section.rows.length <= 1\"\n :aria-label=\"`${config.labels.interactiveRemoveRow} ${rowIndex + 1}`\"\n @click=\"removeRow(sectionIndex, rowIndex)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Button variant=\"subtle\" size=\"xs\" :disabled=\"props.disabled\" @click=\"addRow(sectionIndex)\">\n <WhatsAppIcon name=\"plus\" size=\"14\" />\n {{ config.labels.interactiveAddRow }}\n </Button>\n </Box>\n\n <Text v-if=\"submitted && errors.rows\" size=\"xs\" c=\"red\">{{ errors.rows }}</Text>\n\n <Button variant=\"subtle\" size=\"xs\" :disabled=\"props.disabled\" @click=\"addSection\">\n <WhatsAppIcon name=\"plus\" size=\"14\" />\n {{ config.labels.interactiveAddSection }}\n </Button>\n </Box>\n\n <Box v-bind=\"getStyles('interactiveEditorFooter')\">\n <Button variant=\"subtle\" size=\"sm\" :disabled=\"props.disabled\" @click=\"emit('cancel')\">\n {{ config.labels.cancel }}\n </Button>\n\n <Button size=\"sm\" :disabled=\"props.disabled\" @click=\"submit\">\n {{ config.labels.interactiveSubmit }}\n </Button>\n </Box>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport type { WhatsAppInteractiveContent, WhatsAppInteractiveType } from '../../types'\nimport { createClientId } from '../../utils'\n\nconst defaultProps = {\n maxButtons: 3,\n maxRowsPerSection: 10,\n disabled: false,\n} as const\n\n/**\n * A fresh, well-formed draft of the given type.\n *\n * The draft is always a valid `WhatsAppInteractiveContent`, never a loose bag of fields: the\n * `v-model` a consumer binds is the same discriminated union the message would be sent with, so\n * there is nothing to translate on submit.\n */\nfunction createInteractiveDraft(\n type: WhatsAppInteractiveType,\n previous?: WhatsAppInteractiveContent,\n): WhatsAppInteractiveContent {\n const shared = {\n header: previous?.header,\n body: previous?.body ?? '',\n footer: previous?.footer,\n }\n\n if (type === 'cta_url') {\n return { ...shared, type: 'cta_url', action: { displayText: '', url: '' } }\n }\n\n if (type === 'list') {\n return {\n ...shared,\n type: 'list',\n button: '',\n sections: [{ title: '', rows: [{ id: createClientId(), title: '', description: '' }] }],\n }\n }\n\n return { ...shared, type: 'button', buttons: [{ id: createClientId(), title: '' }] }\n}\n\nexport { createInteractiveDraft, defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs } from 'vue'\nimport {\n ActionIcon,\n Box,\n Button,\n SegmentedControl,\n Text,\n TextInput,\n Textarea,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppInteractiveButtonContent,\n WhatsAppInteractiveCtaUrlContent,\n WhatsAppInteractiveListContent,\n} from '../../types'\nimport type {\n WhatsAppInteractiveMessageEditorEmits,\n WhatsAppInteractiveMessageEditorOwnProps,\n} from './WhatsAppInteractiveMessageEditor.types'\nimport classes from './WhatsAppInteractiveMessageEditor.module.css'\n\ndefineOptions({\n name: 'WhatsAppInteractiveMessageEditor',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInteractiveMessageEditorOwnProps>(), {\n modelValue: undefined,\n defaultValue: undefined,\n interactiveTypes: undefined,\n maxButtons: undefined,\n maxRowsPerSection: undefined,\n disabled: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppInteractiveMessageEditorEmits>()\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInteractiveMessageEditor', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInteractiveMessageEditor',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'interactiveEditorRoot',\n})\n\nconst availableTypes = computed<WhatsAppInteractiveType[]>(() =>\n props.interactiveTypes && props.interactiveTypes.length > 0 ? props.interactiveTypes : ['button'],\n)\n\nconst [content, setContent] = useUncontrolled<WhatsAppInteractiveContent>({\n value: () => props.modelValue,\n defaultValue: props.defaultValue,\n finalValue: createInteractiveDraft(props.interactiveTypes?.[0] ?? 'button'),\n onChange: (value) => emit('update:modelValue', value),\n})\n\nconst typeOptions = computed(() =>\n availableTypes.value.map((type) => ({\n value: type,\n label:\n type === 'button'\n ? config.labels.interactiveTypeButton\n : type === 'cta_url'\n ? config.labels.interactiveTypeCtaUrl\n : config.labels.interactiveTypeList,\n })),\n)\n\nconst buttonContent = computed(() =>\n content.value.type === 'button' ? (content.value as WhatsAppInteractiveButtonContent) : undefined,\n)\nconst ctaContent = computed(() =>\n content.value.type === 'cta_url'\n ? (content.value as WhatsAppInteractiveCtaUrlContent)\n : undefined,\n)\nconst listContent = computed(() =>\n content.value.type === 'list' ? (content.value as WhatsAppInteractiveListContent) : undefined,\n)\n\nconst errors = computed(() => {\n const current = content.value\n const result: { body?: string; buttons?: string; url?: string; rows?: string } = {}\n\n if (current.body.trim().length === 0) {\n result.body = config.labels.interactiveBodyRequired\n }\n\n if (current.type === 'button' && !current.buttons.some((button) => button.title.trim())) {\n result.buttons = config.labels.interactiveButtonsRequired\n }\n\n if (\n current.type === 'cta_url' &&\n (current.action.displayText.trim().length === 0 ||\n !/^https?:\\/\\/\\S+$/i.test(current.action.url))\n ) {\n result.url = config.labels.interactiveUrlRequired\n }\n\n if (current.type === 'list') {\n const hasRow = current.sections.some((section) =>\n section.rows.some((row) => row.title.trim().length > 0),\n )\n\n if (!hasRow || current.button.trim().length === 0) {\n result.rows = config.labels.interactiveRowsRequired\n }\n }\n\n return result\n})\n\nconst valid = computed(() => Object.keys(errors.value).length === 0)\n\nconst submitted = ref(false)\n\nfunction changeType(type: WhatsAppInteractiveType) {\n setContent(createInteractiveDraft(type, content.value))\n}\n\nfunction patch(partial: Partial<WhatsAppInteractiveContent>) {\n setContent({ ...content.value, ...partial } as WhatsAppInteractiveContent)\n}\n\nfunction setButtonTitle(index: number, title: string) {\n const current = buttonContent.value\n\n if (!current) {\n return\n }\n\n const buttons = current.buttons.map((button, buttonIndex) =>\n buttonIndex === index ? { ...button, title } : button,\n )\n\n setContent({ ...current, buttons })\n}\n\nfunction addButton() {\n const current = buttonContent.value\n\n if (!current || current.buttons.length >= (props.maxButtons ?? defaultProps.maxButtons)) {\n return\n }\n\n setContent({ ...current, buttons: [...current.buttons, { id: createClientId(), title: '' }] })\n}\n\nfunction removeButton(index: number) {\n const current = buttonContent.value\n\n if (!current || current.buttons.length <= 1) {\n return\n }\n\n setContent({\n ...current,\n buttons: current.buttons.filter((_, buttonIndex) => buttonIndex !== index),\n })\n}\n\nfunction setAction(partial: Partial<WhatsAppInteractiveCtaUrlContent['action']>) {\n const current = ctaContent.value\n\n if (!current) {\n return\n }\n\n setContent({ ...current, action: { ...current.action, ...partial } })\n}\n\nfunction setSectionTitle(sectionIndex: number, title: string) {\n const current = listContent.value\n\n if (!current) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex ? { ...section, title } : section,\n ),\n })\n}\n\nfunction setRow(\n sectionIndex: number,\n rowIndex: number,\n partial: { title?: string; description?: string },\n) {\n const current = listContent.value\n\n if (!current) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex\n ? {\n ...section,\n rows: section.rows.map((row, currentRowIndex) =>\n currentRowIndex === rowIndex ? { ...row, ...partial } : row,\n ),\n }\n : section,\n ),\n })\n}\n\nfunction addRow(sectionIndex: number) {\n const current = listContent.value\n const max = props.maxRowsPerSection ?? defaultProps.maxRowsPerSection\n\n if (!current || current.sections[sectionIndex].rows.length >= max) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex\n ? {\n ...section,\n rows: [...section.rows, { id: createClientId(), title: '', description: '' }],\n }\n : section,\n ),\n })\n}\n\nfunction removeRow(sectionIndex: number, rowIndex: number) {\n const current = listContent.value\n\n if (!current || current.sections[sectionIndex].rows.length <= 1) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.map((section, index) =>\n index === sectionIndex\n ? { ...section, rows: section.rows.filter((_, currentIndex) => currentIndex !== rowIndex) }\n : section,\n ),\n })\n}\n\nfunction addSection() {\n const current = listContent.value\n\n if (!current) {\n return\n }\n\n setContent({\n ...current,\n sections: [\n ...current.sections,\n { title: '', rows: [{ id: createClientId(), title: '', description: '' }] },\n ],\n })\n}\n\nfunction removeSection(sectionIndex: number) {\n const current = listContent.value\n\n if (!current || current.sections.length <= 1) {\n return\n }\n\n setContent({\n ...current,\n sections: current.sections.filter((_, index) => index !== sectionIndex),\n })\n}\n\nfunction submit() {\n submitted.value = true\n\n if (valid.value) {\n emit('submit', content.value)\n }\n}\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('interactiveEditorRoot') }\">\n <SegmentedControl\n v-if=\"typeOptions.length > 1\"\n :model-value=\"content.type\"\n :data=\"typeOptions\"\n :disabled=\"props.disabled\"\n size=\"xs\"\n full-width\n :aria-label=\"config.labels.interactiveType\"\n @update:model-value=\"changeType($event as any)\"\n />\n\n <TextInput\n size=\"sm\"\n :label=\"config.labels.interactiveHeader\"\n :disabled=\"props.disabled\"\n :model-value=\"content.header?.text ?? ''\"\n @update:model-value=\"patch({ header: $event ? { type: 'text', text: $event } : undefined })\"\n />\n\n <Textarea\n size=\"sm\"\n autosize\n :min-rows=\"2\"\n :max-rows=\"6\"\n required\n :label=\"config.labels.interactiveBody\"\n :disabled=\"props.disabled\"\n :error=\"submitted ? errors.body : undefined\"\n :model-value=\"content.body\"\n @update:model-value=\"patch({ body: $event })\"\n />\n\n <TextInput\n size=\"sm\"\n :label=\"config.labels.interactiveFooter\"\n :disabled=\"props.disabled\"\n :model-value=\"content.footer ?? ''\"\n @update:model-value=\"patch({ footer: $event || undefined })\"\n />\n\n <Box v-if=\"buttonContent\" v-bind=\"getStyles('interactiveEditorSection')\">\n <Box v-bind=\"getStyles('interactiveEditorSectionTitle')\">\n {{ config.labels.interactiveButtons }}\n </Box>\n\n <Box\n v-for=\"(button, index) in buttonContent.buttons\"\n :key=\"button.id\"\n v-bind=\"getStyles('interactiveEditorRow')\"\n >\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveButtonText} ${index + 1}`\"\n :placeholder=\"config.labels.interactiveButtonText\"\n :disabled=\"props.disabled\"\n :model-value=\"button.title\"\n @update:model-value=\"setButtonTitle(index, $event)\"\n />\n\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || buttonContent.buttons.length <= 1\"\n :aria-label=\"`${config.labels.interactiveRemoveButton} ${index + 1}`\"\n @click=\"removeButton(index)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Text v-if=\"submitted && errors.buttons\" size=\"xs\" c=\"red\">{{ errors.buttons }}</Text>\n\n <Button\n variant=\"subtle\"\n size=\"xs\"\n :disabled=\"props.disabled || buttonContent.buttons.length >= (props.maxButtons ?? 3)\"\n @click=\"addButton\"\n >\n <WhatsAppIcon name=\"plus\" size=\"14\" />\n {{ config.labels.interactiveAddButton }}\n </Button>\n </Box>\n\n <Box v-else-if=\"ctaContent\" v-bind=\"getStyles('interactiveEditorSection')\">\n <TextInput\n size=\"sm\"\n required\n :label=\"config.labels.interactiveCtaDisplayText\"\n :disabled=\"props.disabled\"\n :model-value=\"ctaContent.action.displayText\"\n @update:model-value=\"setAction({ displayText: $event })\"\n />\n\n <TextInput\n size=\"sm\"\n required\n type=\"url\"\n placeholder=\"https://\"\n :label=\"config.labels.interactiveCtaUrl\"\n :disabled=\"props.disabled\"\n :error=\"submitted ? errors.url : undefined\"\n :model-value=\"ctaContent.action.url\"\n @update:model-value=\"setAction({ url: $event })\"\n />\n </Box>\n\n <Box v-else-if=\"listContent\" v-bind=\"getStyles('interactiveEditorSection')\">\n <TextInput\n size=\"sm\"\n required\n :label=\"config.labels.interactiveListButton\"\n :disabled=\"props.disabled\"\n :model-value=\"listContent.button\"\n @update:model-value=\"patch({ button: $event } as any)\"\n />\n\n <Box v-bind=\"getStyles('interactiveEditorSectionTitle')\">\n {{ config.labels.interactiveListSections }}\n </Box>\n\n <Box\n v-for=\"(section, sectionIndex) in listContent.sections\"\n :key=\"sectionIndex\"\n v-bind=\"getStyles('interactiveEditorItem')\"\n >\n <Box v-bind=\"getStyles('interactiveEditorRow')\">\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveSectionTitle} ${sectionIndex + 1}`\"\n :placeholder=\"config.labels.interactiveSectionTitle\"\n :disabled=\"props.disabled\"\n :model-value=\"section.title ?? ''\"\n @update:model-value=\"setSectionTitle(sectionIndex, $event)\"\n />\n\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || listContent.sections.length <= 1\"\n :aria-label=\"`${config.labels.interactiveRemoveSection} ${sectionIndex + 1}`\"\n @click=\"removeSection(sectionIndex)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Box\n v-for=\"(row, rowIndex) in section.rows\"\n :key=\"row.id\"\n v-bind=\"getStyles('interactiveEditorRow')\"\n >\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveRowTitle} ${rowIndex + 1}`\"\n :placeholder=\"config.labels.interactiveRowTitle\"\n :disabled=\"props.disabled\"\n :model-value=\"row.title\"\n @update:model-value=\"setRow(sectionIndex, rowIndex, { title: $event })\"\n />\n\n <TextInput\n size=\"sm\"\n style=\"flex: 1\"\n :aria-label=\"`${config.labels.interactiveRowDescription} ${rowIndex + 1}`\"\n :placeholder=\"config.labels.interactiveRowDescription\"\n :disabled=\"props.disabled\"\n :model-value=\"row.description ?? ''\"\n @update:model-value=\"setRow(sectionIndex, rowIndex, { description: $event })\"\n />\n\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || section.rows.length <= 1\"\n :aria-label=\"`${config.labels.interactiveRemoveRow} ${rowIndex + 1}`\"\n @click=\"removeRow(sectionIndex, rowIndex)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Button variant=\"subtle\" size=\"xs\" :disabled=\"props.disabled\" @click=\"addRow(sectionIndex)\">\n <WhatsAppIcon name=\"plus\" size=\"14\" />\n {{ config.labels.interactiveAddRow }}\n </Button>\n </Box>\n\n <Text v-if=\"submitted && errors.rows\" size=\"xs\" c=\"red\">{{ errors.rows }}</Text>\n\n <Button variant=\"subtle\" size=\"xs\" :disabled=\"props.disabled\" @click=\"addSection\">\n <WhatsAppIcon name=\"plus\" size=\"14\" />\n {{ config.labels.interactiveAddSection }}\n </Button>\n </Box>\n\n <Box v-bind=\"getStyles('interactiveEditorFooter')\">\n <Button variant=\"subtle\" size=\"sm\" :disabled=\"props.disabled\" @click=\"emit('cancel')\">\n {{ config.labels.cancel }}\n </Button>\n\n <Button size=\"sm\" :disabled=\"props.disabled\" @click=\"submit\">\n {{ config.labels.interactiveSubmit }}\n </Button>\n </Box>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppInteractiveMessageEditorComponent from './WhatsAppInteractiveMessageEditor.vue'\nimport type { WhatsAppInteractiveMessageEditorFactory } from './WhatsAppInteractiveMessageEditor.types'\nimport classes from './WhatsAppInteractiveMessageEditor.module.css'\n\nexport const WhatsAppInteractiveMessageEditor = factory<WhatsAppInteractiveMessageEditorFactory>(\n WhatsAppInteractiveMessageEditorComponent,\n {\n classes,\n },\n)\n\nexport type {\n WhatsAppInteractiveMessageEditorEmits,\n WhatsAppInteractiveMessageEditorFactory,\n WhatsAppInteractiveMessageEditorOwnProps,\n WhatsAppInteractiveMessageEditorProps,\n WhatsAppInteractiveMessageEditorStylesNames,\n} from './WhatsAppInteractiveMessageEditor.types'\n",".windowNoticeRoot {\n display: flex;\n align-items: flex-start;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-sm);\n border-radius: var(--mantine-radius-md);\n background-color: var(--mantine-color-yellow-light);\n color: var(--mantine-color-yellow-light-color);\n}\n\n.windowNoticeIcon {\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.windowNoticeBody {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.windowNoticeTitle {\n font-size: var(--mantine-font-size-sm);\n font-weight: 600;\n}\n\n.windowNoticeDescription {\n font-size: var(--mantine-font-size-xs);\n}\n\n.windowNoticeAction {\n flex-shrink: 0;\n align-self: center;\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n withTemplateAction: true,\n templatesAvailable: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Box, Button, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppMessagingWindowNoticeEmits,\n WhatsAppMessagingWindowNoticeOwnProps,\n WhatsAppMessagingWindowNoticeSlots,\n} from './WhatsAppMessagingWindowNotice.types'\nimport classes from './WhatsAppMessagingWindowNotice.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessagingWindowNotice',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessagingWindowNoticeOwnProps>(), {\n messagingWindow: undefined,\n withTemplateAction: undefined,\n templatesAvailable: undefined,\n title: undefined,\n description: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessagingWindowNoticeEmits>()\ndefineSlots<WhatsAppMessagingWindowNoticeSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessagingWindowNotice', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessagingWindowNotice',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'windowNoticeRoot',\n})\n\nconst closed = computed(() => props.messagingWindow?.state === 'closed')\n\nconst title = computed(() => props.title ?? config.labels.windowClosedTitle)\n\n/**\n * Backend copy wins over the built-in sentence: the reason a window is closed is a policy\n * decision the server makes, and it is the only side that can explain it accurately.\n */\nconst description = computed(\n () => props.description ?? props.messagingWindow?.reason ?? config.labels.windowClosedDescription,\n)\n\nconst showAction = computed(() => props.withTemplateAction && props.templatesAvailable)\n</script>\n\n<template>\n <Box\n v-if=\"closed\"\n v-bind=\"{ ...attrs, ...getStyles('windowNoticeRoot') }\"\n role=\"status\"\n :data-reason-code=\"props.messagingWindow?.reasonCode\"\n >\n <slot v-if=\"slots.default\" :messaging-window=\"props.messagingWindow!\" />\n\n <template v-else>\n <Box v-bind=\"getStyles('windowNoticeIcon')\">\n <WhatsAppIcon name=\"lock\" size=\"18\" />\n </Box>\n\n <Box v-bind=\"getStyles('windowNoticeBody')\">\n <Box v-bind=\"getStyles('windowNoticeTitle')\">{{ title }}</Box>\n <Box v-bind=\"getStyles('windowNoticeDescription')\">{{ description }}</Box>\n </Box>\n\n <Box v-if=\"slots.action || showAction\" v-bind=\"getStyles('windowNoticeAction')\">\n <slot v-if=\"slots.action\" name=\"action\" />\n <Button v-else size=\"xs\" variant=\"light\" @click=\"emit('templateAction')\">\n {{ config.labels.sendTemplateInstead }}\n </Button>\n </Box>\n </template>\n </Box>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n withTemplateAction: true,\n templatesAvailable: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Box, Button, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppMessagingWindowNoticeEmits,\n WhatsAppMessagingWindowNoticeOwnProps,\n WhatsAppMessagingWindowNoticeSlots,\n} from './WhatsAppMessagingWindowNotice.types'\nimport classes from './WhatsAppMessagingWindowNotice.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessagingWindowNotice',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessagingWindowNoticeOwnProps>(), {\n messagingWindow: undefined,\n withTemplateAction: undefined,\n templatesAvailable: undefined,\n title: undefined,\n description: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessagingWindowNoticeEmits>()\ndefineSlots<WhatsAppMessagingWindowNoticeSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessagingWindowNotice', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessagingWindowNotice',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'windowNoticeRoot',\n})\n\nconst closed = computed(() => props.messagingWindow?.state === 'closed')\n\nconst title = computed(() => props.title ?? config.labels.windowClosedTitle)\n\n/**\n * Backend copy wins over the built-in sentence: the reason a window is closed is a policy\n * decision the server makes, and it is the only side that can explain it accurately.\n */\nconst description = computed(\n () => props.description ?? props.messagingWindow?.reason ?? config.labels.windowClosedDescription,\n)\n\nconst showAction = computed(() => props.withTemplateAction && props.templatesAvailable)\n</script>\n\n<template>\n <Box\n v-if=\"closed\"\n v-bind=\"{ ...attrs, ...getStyles('windowNoticeRoot') }\"\n role=\"status\"\n :data-reason-code=\"props.messagingWindow?.reasonCode\"\n >\n <slot v-if=\"slots.default\" :messaging-window=\"props.messagingWindow!\" />\n\n <template v-else>\n <Box v-bind=\"getStyles('windowNoticeIcon')\">\n <WhatsAppIcon name=\"lock\" size=\"18\" />\n </Box>\n\n <Box v-bind=\"getStyles('windowNoticeBody')\">\n <Box v-bind=\"getStyles('windowNoticeTitle')\">{{ title }}</Box>\n <Box v-bind=\"getStyles('windowNoticeDescription')\">{{ description }}</Box>\n </Box>\n\n <Box v-if=\"slots.action || showAction\" v-bind=\"getStyles('windowNoticeAction')\">\n <slot v-if=\"slots.action\" name=\"action\" />\n <Button v-else size=\"xs\" variant=\"light\" @click=\"emit('templateAction')\">\n {{ config.labels.sendTemplateInstead }}\n </Button>\n </Box>\n </template>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppMessagingWindowNoticeComponent from './WhatsAppMessagingWindowNotice.vue'\nimport type { WhatsAppMessagingWindowNoticeFactory } from './WhatsAppMessagingWindowNotice.types'\nimport classes from './WhatsAppMessagingWindowNotice.module.css'\n\nexport const WhatsAppMessagingWindowNotice = factory<WhatsAppMessagingWindowNoticeFactory>(\n WhatsAppMessagingWindowNoticeComponent,\n { classes },\n)\n\nexport type {\n WhatsAppMessagingWindowNoticeEmits,\n WhatsAppMessagingWindowNoticeFactory,\n WhatsAppMessagingWindowNoticeOwnProps,\n WhatsAppMessagingWindowNoticeProps,\n WhatsAppMessagingWindowNoticeSlots,\n WhatsAppMessagingWindowNoticeStylesNames,\n} from './WhatsAppMessagingWindowNotice.types'\n",".templatePreviewRoot {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.templatePreviewMeta {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.templatePreviewHeader {\n font-weight: 600;\n font-size: var(--mantine-font-size-sm);\n}\n\n.templatePreviewHeaderMedia {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n padding: 6px 8px;\n border-radius: var(--mantine-radius-sm);\n background-color: var(--mantine-color-default-hover);\n}\n\n.templatePreviewBody {\n font-size: var(--mantine-font-size-sm);\n line-height: 1.4;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.templatePreviewFooter {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n}\n\n.templatePreviewButtons {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: 4px;\n border-top: 1px solid var(--mantine-color-default-border);\n padding-top: 4px;\n}\n\n.templatePreviewButton {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: var(--mantine-font-size-sm);\n color: var(--mantine-color-anchor);\n padding: 4px;\n text-align: center;\n}\n\n.templatePreviewFallback {\n font-size: var(--mantine-font-size-sm);\n white-space: pre-wrap;\n}\n","<script lang=\"ts\">\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppTemplateButton } from '../../types'\n\nconst defaultProps = {\n withMeta: false,\n withButtons: true,\n} as const\n\nconst BUTTON_ICONS: Record<WhatsAppTemplateButton['type'], WhatsAppIconName> = {\n quick_reply: 'reply',\n url: 'externalLink',\n phone_number: 'phone',\n copy_code: 'file',\n}\n\nexport { defaultProps, BUTTON_ICONS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { Badge, Box, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport {\n getTemplateBody,\n getTemplateButtons,\n getTemplateFooter,\n getTemplateHeader,\n renderTemplateText,\n} from '../../utils'\nimport type { WhatsAppTemplatePreviewOwnProps } from './WhatsAppTemplatePreview.types'\nimport classes from './WhatsAppTemplatePreview.module.css'\n\ndefineOptions({\n name: 'WhatsAppTemplatePreview',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppTemplatePreviewOwnProps>(), {\n template: undefined,\n values: undefined,\n fallbackText: undefined,\n withMeta: undefined,\n withButtons: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppTemplatePreview', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppTemplatePreview',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'templatePreviewRoot',\n})\n\nconst header = computed(() => getTemplateHeader(props.template))\nconst body = computed(() => getTemplateBody(props.template))\nconst footer = computed(() => getTemplateFooter(props.template))\nconst buttons = computed(() => getTemplateButtons(props.template)?.buttons ?? [])\n\nconst headerFormat = computed(() => header.value?.format ?? 'text')\nconst headerIsMedia = computed(() =>\n ['image', 'video', 'document'].includes(headerFormat.value as string),\n)\n\nconst headerText = computed(() =>\n headerIsMedia.value ? '' : renderTemplateText(header.value?.text, props.values?.header),\n)\n\nconst headerMediaLabel = computed(() => {\n const chosen = props.values?.headerMedia ?? header.value?.example\n\n if (chosen?.fileName) {\n return chosen.fileName\n }\n\n switch (headerFormat.value) {\n case 'image':\n return config.labels.messageTypeImage\n case 'video':\n return config.labels.messageTypeVideo\n default:\n return config.labels.messageTypeDocument\n }\n})\n\nconst bodyText = computed(() => renderTemplateText(body.value?.text, props.values?.body))\n\nconst languageLabel = computed(\n () => props.template?.languageLabel ?? props.template?.language ?? '',\n)\n\nfunction buttonHint(button: WhatsAppTemplateButton, index: number): string {\n if (button.type === 'url') {\n return renderTemplateText(button.url, props.values?.buttons?.[String(index)])\n }\n\n if (button.type === 'phone_number') {\n return button.phoneNumber\n }\n\n return ''\n}\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('templatePreviewRoot') }\">\n <template v-if=\"props.template\">\n <Box v-if=\"props.withMeta\" v-bind=\"getStyles('templatePreviewMeta')\">\n <Badge v-if=\"props.template.category\" size=\"sm\" variant=\"light\">\n {{ props.template.category }}\n </Badge>\n <Badge v-if=\"languageLabel\" size=\"sm\" variant=\"default\">{{ languageLabel }}</Badge>\n <Badge\n v-if=\"props.template.status && props.template.status !== 'approved'\"\n size=\"sm\"\n color=\"orange\"\n variant=\"light\"\n >\n {{ props.template.status }}\n </Badge>\n </Box>\n\n <Box v-if=\"headerIsMedia\" v-bind=\"getStyles('templatePreviewHeaderMedia')\">\n <WhatsAppIcon\n :name=\"headerFormat === 'image' ? 'photo' : headerFormat === 'video' ? 'video' : 'file'\"\n size=\"16\"\n />\n {{ headerMediaLabel }}\n </Box>\n\n <Box v-else-if=\"headerText\" v-bind=\"getStyles('templatePreviewHeader')\">\n {{ headerText }}\n </Box>\n\n <Box v-if=\"bodyText\" v-bind=\"getStyles('templatePreviewBody')\">{{ bodyText }}</Box>\n\n <Box v-if=\"footer\" v-bind=\"getStyles('templatePreviewFooter')\">{{ footer.text }}</Box>\n\n <Box\n v-if=\"props.withButtons && buttons.length > 0\"\n v-bind=\"getStyles('templatePreviewButtons')\"\n >\n <Box\n v-for=\"(button, index) in buttons\"\n :key=\"`${button.type}-${index}`\"\n v-bind=\"getStyles('templatePreviewButton')\"\n :data-button-type=\"button.type\"\n :title=\"buttonHint(button, index)\"\n >\n <WhatsAppIcon :name=\"BUTTON_ICONS[button.type]\" size=\"14\" />\n {{ button.text }}\n </Box>\n </Box>\n </template>\n\n <Box v-else-if=\"props.fallbackText\" v-bind=\"getStyles('templatePreviewFallback')\">\n {{ props.fallbackText }}\n </Box>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppTemplateButton } from '../../types'\n\nconst defaultProps = {\n withMeta: false,\n withButtons: true,\n} as const\n\nconst BUTTON_ICONS: Record<WhatsAppTemplateButton['type'], WhatsAppIconName> = {\n quick_reply: 'reply',\n url: 'externalLink',\n phone_number: 'phone',\n copy_code: 'file',\n}\n\nexport { defaultProps, BUTTON_ICONS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { Badge, Box, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport {\n getTemplateBody,\n getTemplateButtons,\n getTemplateFooter,\n getTemplateHeader,\n renderTemplateText,\n} from '../../utils'\nimport type { WhatsAppTemplatePreviewOwnProps } from './WhatsAppTemplatePreview.types'\nimport classes from './WhatsAppTemplatePreview.module.css'\n\ndefineOptions({\n name: 'WhatsAppTemplatePreview',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppTemplatePreviewOwnProps>(), {\n template: undefined,\n values: undefined,\n fallbackText: undefined,\n withMeta: undefined,\n withButtons: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppTemplatePreview', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppTemplatePreview',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'templatePreviewRoot',\n})\n\nconst header = computed(() => getTemplateHeader(props.template))\nconst body = computed(() => getTemplateBody(props.template))\nconst footer = computed(() => getTemplateFooter(props.template))\nconst buttons = computed(() => getTemplateButtons(props.template)?.buttons ?? [])\n\nconst headerFormat = computed(() => header.value?.format ?? 'text')\nconst headerIsMedia = computed(() =>\n ['image', 'video', 'document'].includes(headerFormat.value as string),\n)\n\nconst headerText = computed(() =>\n headerIsMedia.value ? '' : renderTemplateText(header.value?.text, props.values?.header),\n)\n\nconst headerMediaLabel = computed(() => {\n const chosen = props.values?.headerMedia ?? header.value?.example\n\n if (chosen?.fileName) {\n return chosen.fileName\n }\n\n switch (headerFormat.value) {\n case 'image':\n return config.labels.messageTypeImage\n case 'video':\n return config.labels.messageTypeVideo\n default:\n return config.labels.messageTypeDocument\n }\n})\n\nconst bodyText = computed(() => renderTemplateText(body.value?.text, props.values?.body))\n\nconst languageLabel = computed(\n () => props.template?.languageLabel ?? props.template?.language ?? '',\n)\n\nfunction buttonHint(button: WhatsAppTemplateButton, index: number): string {\n if (button.type === 'url') {\n return renderTemplateText(button.url, props.values?.buttons?.[String(index)])\n }\n\n if (button.type === 'phone_number') {\n return button.phoneNumber\n }\n\n return ''\n}\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('templatePreviewRoot') }\">\n <template v-if=\"props.template\">\n <Box v-if=\"props.withMeta\" v-bind=\"getStyles('templatePreviewMeta')\">\n <Badge v-if=\"props.template.category\" size=\"sm\" variant=\"light\">\n {{ props.template.category }}\n </Badge>\n <Badge v-if=\"languageLabel\" size=\"sm\" variant=\"default\">{{ languageLabel }}</Badge>\n <Badge\n v-if=\"props.template.status && props.template.status !== 'approved'\"\n size=\"sm\"\n color=\"orange\"\n variant=\"light\"\n >\n {{ props.template.status }}\n </Badge>\n </Box>\n\n <Box v-if=\"headerIsMedia\" v-bind=\"getStyles('templatePreviewHeaderMedia')\">\n <WhatsAppIcon\n :name=\"headerFormat === 'image' ? 'photo' : headerFormat === 'video' ? 'video' : 'file'\"\n size=\"16\"\n />\n {{ headerMediaLabel }}\n </Box>\n\n <Box v-else-if=\"headerText\" v-bind=\"getStyles('templatePreviewHeader')\">\n {{ headerText }}\n </Box>\n\n <Box v-if=\"bodyText\" v-bind=\"getStyles('templatePreviewBody')\">{{ bodyText }}</Box>\n\n <Box v-if=\"footer\" v-bind=\"getStyles('templatePreviewFooter')\">{{ footer.text }}</Box>\n\n <Box\n v-if=\"props.withButtons && buttons.length > 0\"\n v-bind=\"getStyles('templatePreviewButtons')\"\n >\n <Box\n v-for=\"(button, index) in buttons\"\n :key=\"`${button.type}-${index}`\"\n v-bind=\"getStyles('templatePreviewButton')\"\n :data-button-type=\"button.type\"\n :title=\"buttonHint(button, index)\"\n >\n <WhatsAppIcon :name=\"BUTTON_ICONS[button.type]\" size=\"14\" />\n {{ button.text }}\n </Box>\n </Box>\n </template>\n\n <Box v-else-if=\"props.fallbackText\" v-bind=\"getStyles('templatePreviewFallback')\">\n {{ props.fallbackText }}\n </Box>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppTemplatePreviewComponent from './WhatsAppTemplatePreview.vue'\nimport type { WhatsAppTemplatePreviewFactory } from './WhatsAppTemplatePreview.types'\nimport classes from './WhatsAppTemplatePreview.module.css'\n\nexport const WhatsAppTemplatePreview = factory<WhatsAppTemplatePreviewFactory>(\n WhatsAppTemplatePreviewComponent,\n { classes },\n)\n\nexport type {\n WhatsAppTemplatePreviewFactory,\n WhatsAppTemplatePreviewOwnProps,\n WhatsAppTemplatePreviewProps,\n WhatsAppTemplatePreviewStylesNames,\n} from './WhatsAppTemplatePreview.types'\n",".templateSelectorRoot {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-sm);\n min-height: 0;\n}\n\n.templateSelectorControls {\n display: flex;\n gap: var(--mantine-spacing-xs);\n flex-wrap: wrap;\n}\n\n.templateSelectorList {\n display: flex;\n flex-direction: column;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n overflow-y: auto;\n max-height: var(--wa-template-list-max-height, 360px);\n}\n\n.templateSelectorItem {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 100%;\n text-align: start;\n padding: var(--mantine-spacing-xs);\n border-radius: var(--mantine-radius-md);\n border: 1px solid var(--mantine-color-default-border);\n}\n\n.templateSelectorItem:where(:not([data-disabled])) {\n @mixin hover {\n background-color: var(--mantine-color-default-hover);\n }\n}\n\n.templateSelectorItem:where([data-disabled]) {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.templateSelectorItem:where([data-selected]) {\n border-color: var(--mantine-primary-color-filled);\n}\n\n.templateSelectorItemName {\n font-size: var(--mantine-font-size-sm);\n font-weight: 600;\n}\n\n.templateSelectorItemMeta {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.templateSelectorItemBody {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.templateSelectorState {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-lg);\n text-align: center;\n}\n\n.templateSelectorDetail {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-sm);\n min-height: 0;\n overflow-y: auto;\n max-height: var(--wa-template-list-max-height, 360px);\n}\n\n.templateSelectorPreview {\n padding: var(--mantine-spacing-sm);\n border-radius: var(--mantine-radius-md);\n background-color: var(--mantine-color-default);\n}\n\n.templateSelectorForm {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-sm);\n}\n\n.templateSelectorSection {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-xs);\n}\n\n.templateSelectorSectionTitle {\n font-size: var(--mantine-font-size-xs);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mantine-color-dimmed);\n}\n\n.templateSelectorFooter {\n display: flex;\n justify-content: space-between;\n gap: var(--mantine-spacing-xs);\n padding-top: var(--mantine-spacing-xs);\n border-top: 1px solid var(--mantine-color-default-border);\n}\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n withSearch: true,\n withCategoryFilter: true,\n withUnavailable: true,\n} as const\n\nconst varsResolver = createVarsResolver<any>((_, { listMaxHeight }) => ({\n templateSelectorRoot: {\n '--wa-template-list-max-height':\n listMaxHeight === undefined\n ? undefined\n : typeof listMaxHeight === 'number'\n ? `${listMaxHeight}px`\n : listMaxHeight,\n },\n}))\n\nexport { defaultProps, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, useSlots, watch } from 'vue'\nimport {\n Alert,\n Badge,\n Box,\n Button,\n Center,\n Loader,\n Select,\n Text,\n TextInput,\n Textarea,\n UnstyledButton,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppAttachment,\n WhatsAppTemplate,\n WhatsAppTemplateParameter,\n WhatsAppTemplateValues,\n} from '../../types'\nimport {\n createEmptyTemplateValues,\n filterTemplates,\n getTemplateBody,\n getTemplateParameters,\n isTemplateSendable,\n validateTemplateValues,\n type WhatsAppTemplateErrors,\n} from '../../utils'\nimport { WhatsAppTemplatePreview } from '../WhatsAppTemplatePreview'\nimport type {\n WhatsAppTemplateSelectorEmits,\n WhatsAppTemplateSelectorOwnProps,\n WhatsAppTemplateSelectorSlots,\n} from './WhatsAppTemplateSelector.types'\nimport classes from './WhatsAppTemplateSelector.module.css'\n\ndefineOptions({\n name: 'WhatsAppTemplateSelector',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppTemplateSelectorOwnProps>(), {\n templates: undefined,\n loading: undefined,\n error: undefined,\n query: undefined,\n defaultQuery: undefined,\n category: undefined,\n defaultCategory: undefined,\n selectedTemplateId: undefined,\n defaultSelectedTemplateId: undefined,\n values: undefined,\n withSearch: undefined,\n withCategoryFilter: undefined,\n withUnavailable: undefined,\n listMaxHeight: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppTemplateSelectorEmits>()\ndefineSlots<WhatsAppTemplateSelectorSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppTemplateSelector', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppTemplateSelector',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'templateSelectorRoot',\n})\n\nconst [query, setQuery] = useUncontrolled<string>({\n value: () => props.query,\n defaultValue: props.defaultQuery,\n finalValue: '',\n onChange: (value) => emit('update:query', value),\n})\n\nconst [category, setCategory] = useUncontrolled<string | null>({\n value: () => props.category,\n defaultValue: props.defaultCategory,\n finalValue: null,\n onChange: (value) => emit('update:category', value),\n})\n\nconst [selectedId, setSelectedId] = useUncontrolled<string | null>({\n value: () => props.selectedTemplateId,\n defaultValue: props.defaultSelectedTemplateId,\n finalValue: null,\n onChange: (value) => emit('update:selectedTemplateId', value),\n})\n\n/**\n * Parameter values are only uncontrolled until the consumer passes `values`. Keeping the local\n * copy in a plain ref rather than in `useUncontrolled` lets a template change reset it without\n * emitting an update the consumer never asked for.\n */\nconst localValues = ref<WhatsAppTemplateValues>({})\n\nconst templates = computed(() => props.templates ?? [])\n\nconst selectedTemplate = computed(() =>\n selectedId.value\n ? templates.value.find((template) => template.id === selectedId.value)\n : undefined,\n)\n\nconst values = computed<WhatsAppTemplateValues>(() => props.values ?? localValues.value)\n\nfunction setValues(next: WhatsAppTemplateValues) {\n if (props.values === undefined) {\n localValues.value = next\n }\n\n emit('update:values', next)\n}\n\nconst errors = ref<WhatsAppTemplateErrors>({ header: {}, body: {}, buttons: {} })\n\nfunction resetErrors() {\n errors.value = { header: {}, body: {}, buttons: {} }\n}\n\n// A different template has a different set of placeholders, so the draft cannot carry over.\nwatch(selectedTemplate, (template) => {\n resetErrors()\n\n if (props.values === undefined) {\n localValues.value = createEmptyTemplateValues(template)\n }\n})\n\nconst categories = computed(() => {\n const found = new Set<string>()\n\n for (const template of templates.value) {\n if (template.category) {\n found.add(template.category)\n }\n }\n\n return [...found].map((value) => ({ value, label: value }))\n})\n\nconst visibleTemplates = computed(() => {\n const byQuery = filterTemplates(templates.value, query.value)\n const byCategory = category.value\n ? byQuery.filter((template) => template.category === category.value)\n : byQuery\n\n return props.withUnavailable ? byCategory : byCategory.filter(isTemplateSendable)\n})\n\nconst parameters = computed(() => getTemplateParameters(selectedTemplate.value))\n\nconst hasTemplates = computed(() => visibleTemplates.value.length > 0)\nconst showLoading = computed(() => Boolean(props.loading) && templates.value.length === 0)\nconst showError = computed(() => Boolean(props.error) && templates.value.length === 0)\n\nfunction bodyPreview(template: WhatsAppTemplate): string {\n return getTemplateBody(template)?.text ?? template.description ?? ''\n}\n\nfunction selectTemplate(template: WhatsAppTemplate) {\n if (!isTemplateSendable(template)) {\n return\n }\n\n setSelectedId(template.id)\n emit('select', template)\n}\n\nfunction back() {\n setSelectedId(null)\n}\n\ntype ParameterSection = 'header' | 'body'\n\nfunction sectionValue(section: ParameterSection, key: string): string {\n return values.value[section]?.[key] ?? ''\n}\n\nfunction setSectionValue(section: ParameterSection, key: string, value: string) {\n setValues({\n ...values.value,\n [section]: { ...values.value[section], [key]: value },\n })\n}\n\nfunction buttonValue(index: number, key: string): string {\n return values.value.buttons?.[String(index)]?.[key] ?? ''\n}\n\nfunction setButtonValue(index: number, key: string, value: string) {\n const buttonKey = String(index)\n\n setValues({\n ...values.value,\n buttons: {\n ...values.value.buttons,\n [buttonKey]: { ...values.value.buttons?.[buttonKey], [key]: value },\n },\n })\n}\n\nfunction setHeaderMedia(attachment: WhatsAppAttachment | null) {\n setValues({ ...values.value, headerMedia: attachment })\n}\n\nfunction parameterLabel(parameter: WhatsAppTemplateParameter): string {\n return parameter.label ?? `{{${parameter.key}}}`\n}\n\nfunction submit() {\n const template = selectedTemplate.value\n\n if (!template) {\n return\n }\n\n const validation = validateTemplateValues(template, values.value, config.labels)\n errors.value = validation.errors\n\n if (validation.valid) {\n emit('submit', { template, values: values.value })\n }\n}\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('templateSelectorRoot') }\">\n <template v-if=\"!selectedTemplate\">\n <Box\n v-if=\"props.withSearch || (props.withCategoryFilter && categories.length > 0)\"\n v-bind=\"getStyles('templateSelectorControls')\"\n >\n <TextInput\n v-if=\"props.withSearch\"\n :model-value=\"query\"\n :placeholder=\"config.labels.templateSearchPlaceholder\"\n :aria-label=\"config.labels.templateSearchPlaceholder\"\n size=\"sm\"\n style=\"flex: 1\"\n @update:model-value=\"setQuery($event)\"\n >\n <template #leftSection>\n <WhatsAppIcon name=\"search\" size=\"16\" />\n </template>\n </TextInput>\n\n <Select\n v-if=\"props.withCategoryFilter && categories.length > 0\"\n :model-value=\"category\"\n :data=\"categories\"\n :placeholder=\"config.labels.templateCategoryLabel\"\n :aria-label=\"config.labels.templateCategoryLabel\"\n size=\"sm\"\n clearable\n @update:model-value=\"setCategory($event as string | null)\"\n />\n </Box>\n\n <Center v-if=\"showLoading\" v-bind=\"getStyles('templateSelectorState')\">\n <Loader size=\"sm\" />\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.templatesLoading }}</Text>\n </Center>\n\n <Alert\n v-else-if=\"showError\"\n color=\"red\"\n variant=\"light\"\n :title=\"config.labels.templatesError\"\n >\n <Text size=\"sm\">{{ props.error }}</Text>\n <Button mt=\"sm\" size=\"xs\" variant=\"light\" color=\"red\" @click=\"emit('retryLoad')\">\n {{ config.labels.retry }}\n </Button>\n </Alert>\n\n <Box v-else-if=\"!hasTemplates\" v-bind=\"getStyles('templateSelectorState')\">\n <slot v-if=\"slots.emptyTemplates\" name=\"emptyTemplates\" />\n <Text v-else size=\"sm\" c=\"dimmed\">{{ config.labels.templatesEmpty }}</Text>\n </Box>\n\n <Box\n v-else\n component=\"ul\"\n v-bind=\"getStyles('templateSelectorList')\"\n :aria-label=\"config.labels.templateSelectorTitle\"\n >\n <Box v-for=\"template in visibleTemplates\" :key=\"template.id\" component=\"li\">\n <slot\n v-if=\"slots.templateItem\"\n name=\"templateItem\"\n :template=\"template\"\n :selected=\"template.id === selectedId\"\n />\n\n <UnstyledButton\n v-else\n v-bind=\"getStyles('templateSelectorItem')\"\n type=\"button\"\n :disabled=\"!isTemplateSendable(template)\"\n :data-disabled=\"isTemplateSendable(template) ? undefined : ''\"\n :data-selected=\"template.id === selectedId ? '' : undefined\"\n :aria-describedby=\"\n isTemplateSendable(template) ? undefined : `${template.id}-unavailable`\n \"\n @click=\"selectTemplate(template)\"\n >\n <Box v-bind=\"getStyles('templateSelectorItemName')\">{{ template.name }}</Box>\n\n <Box v-bind=\"getStyles('templateSelectorItemMeta')\">\n <Badge v-if=\"template.category\" size=\"xs\" variant=\"light\">\n {{ template.category }}\n </Badge>\n <Badge size=\"xs\" variant=\"default\">\n {{ template.languageLabel ?? template.language }}\n </Badge>\n <Badge\n v-if=\"!isTemplateSendable(template)\"\n :id=\"`${template.id}-unavailable`\"\n size=\"xs\"\n color=\"orange\"\n variant=\"light\"\n >\n {{ template.status }}\n </Badge>\n </Box>\n\n <Box v-bind=\"getStyles('templateSelectorItemBody')\">{{ bodyPreview(template) }}</Box>\n </UnstyledButton>\n </Box>\n </Box>\n </template>\n\n <template v-else>\n <Box v-bind=\"getStyles('templateSelectorDetail')\">\n <Box v-bind=\"getStyles('templateSelectorPreview')\">\n <slot v-if=\"slots.templatePreview\" name=\"templatePreview\" :template=\"selectedTemplate\" />\n <WhatsAppTemplatePreview\n v-else\n :template=\"selectedTemplate\"\n :values=\"values\"\n with-meta\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n />\n </Box>\n\n <Box\n v-if=\"parameters.hasParameters\"\n component=\"form\"\n v-bind=\"getStyles('templateSelectorForm')\"\n :aria-label=\"config.labels.templateParameters\"\n @submit.prevent=\"submit\"\n >\n <Box v-if=\"parameters.requiresHeaderMedia\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateHeaderMedia }}\n </Box>\n\n <slot\n v-if=\"slots.headerMedia\"\n name=\"headerMedia\"\n :value=\"values.headerMedia ?? null\"\n :set-value=\"setHeaderMedia\"\n :error=\"errors.headerMedia\"\n />\n <Text v-else-if=\"errors.headerMedia\" size=\"xs\" c=\"red\">\n {{ errors.headerMedia }}\n </Text>\n </Box>\n\n <Box v-if=\"parameters.header.length > 0\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateHeaderVariables }}\n </Box>\n\n <TextInput\n v-for=\"parameter in parameters.header\"\n :key=\"parameter.key\"\n size=\"sm\"\n :label=\"parameterLabel(parameter)\"\n :description=\"parameter.description\"\n :placeholder=\"parameter.placeholder ?? parameter.example\"\n :maxlength=\"parameter.maxLength\"\n :required=\"parameter.required ?? true\"\n :error=\"errors.header[parameter.key]\"\n :model-value=\"sectionValue('header', parameter.key)\"\n @update:model-value=\"setSectionValue('header', parameter.key, $event)\"\n />\n </Box>\n\n <Box v-if=\"parameters.body.length > 0\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateBodyVariables }}\n </Box>\n\n <Textarea\n v-for=\"parameter in parameters.body\"\n :key=\"parameter.key\"\n size=\"sm\"\n autosize\n :min-rows=\"1\"\n :max-rows=\"4\"\n :label=\"parameterLabel(parameter)\"\n :description=\"parameter.description\"\n :placeholder=\"parameter.placeholder ?? parameter.example\"\n :maxlength=\"parameter.maxLength\"\n :required=\"parameter.required ?? true\"\n :error=\"errors.body[parameter.key]\"\n :model-value=\"sectionValue('body', parameter.key)\"\n @update:model-value=\"setSectionValue('body', parameter.key, $event)\"\n />\n </Box>\n\n <Box v-if=\"parameters.buttons.length > 0\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateButtonVariables }}\n </Box>\n\n <template v-for=\"entry in parameters.buttons\" :key=\"entry.index\">\n <TextInput\n v-for=\"parameter in entry.parameters\"\n :key=\"`${entry.index}-${parameter.key}`\"\n size=\"sm\"\n :label=\"`${entry.button.text} — ${parameterLabel(parameter)}`\"\n :description=\"parameter.description\"\n :placeholder=\"parameter.placeholder ?? parameter.example\"\n :maxlength=\"parameter.maxLength\"\n :required=\"parameter.required ?? true\"\n :error=\"errors.buttons[String(entry.index)]?.[parameter.key]\"\n :model-value=\"buttonValue(entry.index, parameter.key)\"\n @update:model-value=\"setButtonValue(entry.index, parameter.key, $event)\"\n />\n </template>\n </Box>\n </Box>\n </Box>\n\n <Box v-bind=\"getStyles('templateSelectorFooter')\">\n <Button variant=\"subtle\" size=\"sm\" @click=\"back\">\n <WhatsAppIcon name=\"arrowLeft\" size=\"16\" />\n {{ config.labels.templateBack }}\n </Button>\n\n <Button size=\"sm\" :disabled=\"!isTemplateSendable(selectedTemplate)\" @click=\"submit\">\n {{ config.labels.templateSubmit }}\n </Button>\n </Box>\n </template>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n withSearch: true,\n withCategoryFilter: true,\n withUnavailable: true,\n} as const\n\nconst varsResolver = createVarsResolver<any>((_, { listMaxHeight }) => ({\n templateSelectorRoot: {\n '--wa-template-list-max-height':\n listMaxHeight === undefined\n ? undefined\n : typeof listMaxHeight === 'number'\n ? `${listMaxHeight}px`\n : listMaxHeight,\n },\n}))\n\nexport { defaultProps, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, useSlots, watch } from 'vue'\nimport {\n Alert,\n Badge,\n Box,\n Button,\n Center,\n Loader,\n Select,\n Text,\n TextInput,\n Textarea,\n UnstyledButton,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type {\n WhatsAppAttachment,\n WhatsAppTemplate,\n WhatsAppTemplateParameter,\n WhatsAppTemplateValues,\n} from '../../types'\nimport {\n createEmptyTemplateValues,\n filterTemplates,\n getTemplateBody,\n getTemplateParameters,\n isTemplateSendable,\n validateTemplateValues,\n type WhatsAppTemplateErrors,\n} from '../../utils'\nimport { WhatsAppTemplatePreview } from '../WhatsAppTemplatePreview'\nimport type {\n WhatsAppTemplateSelectorEmits,\n WhatsAppTemplateSelectorOwnProps,\n WhatsAppTemplateSelectorSlots,\n} from './WhatsAppTemplateSelector.types'\nimport classes from './WhatsAppTemplateSelector.module.css'\n\ndefineOptions({\n name: 'WhatsAppTemplateSelector',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppTemplateSelectorOwnProps>(), {\n templates: undefined,\n loading: undefined,\n error: undefined,\n query: undefined,\n defaultQuery: undefined,\n category: undefined,\n defaultCategory: undefined,\n selectedTemplateId: undefined,\n defaultSelectedTemplateId: undefined,\n values: undefined,\n withSearch: undefined,\n withCategoryFilter: undefined,\n withUnavailable: undefined,\n listMaxHeight: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppTemplateSelectorEmits>()\ndefineSlots<WhatsAppTemplateSelectorSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppTemplateSelector', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppTemplateSelector',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'templateSelectorRoot',\n})\n\nconst [query, setQuery] = useUncontrolled<string>({\n value: () => props.query,\n defaultValue: props.defaultQuery,\n finalValue: '',\n onChange: (value) => emit('update:query', value),\n})\n\nconst [category, setCategory] = useUncontrolled<string | null>({\n value: () => props.category,\n defaultValue: props.defaultCategory,\n finalValue: null,\n onChange: (value) => emit('update:category', value),\n})\n\nconst [selectedId, setSelectedId] = useUncontrolled<string | null>({\n value: () => props.selectedTemplateId,\n defaultValue: props.defaultSelectedTemplateId,\n finalValue: null,\n onChange: (value) => emit('update:selectedTemplateId', value),\n})\n\n/**\n * Parameter values are only uncontrolled until the consumer passes `values`. Keeping the local\n * copy in a plain ref rather than in `useUncontrolled` lets a template change reset it without\n * emitting an update the consumer never asked for.\n */\nconst localValues = ref<WhatsAppTemplateValues>({})\n\nconst templates = computed(() => props.templates ?? [])\n\nconst selectedTemplate = computed(() =>\n selectedId.value\n ? templates.value.find((template) => template.id === selectedId.value)\n : undefined,\n)\n\nconst values = computed<WhatsAppTemplateValues>(() => props.values ?? localValues.value)\n\nfunction setValues(next: WhatsAppTemplateValues) {\n if (props.values === undefined) {\n localValues.value = next\n }\n\n emit('update:values', next)\n}\n\nconst errors = ref<WhatsAppTemplateErrors>({ header: {}, body: {}, buttons: {} })\n\nfunction resetErrors() {\n errors.value = { header: {}, body: {}, buttons: {} }\n}\n\n// A different template has a different set of placeholders, so the draft cannot carry over.\nwatch(selectedTemplate, (template) => {\n resetErrors()\n\n if (props.values === undefined) {\n localValues.value = createEmptyTemplateValues(template)\n }\n})\n\nconst categories = computed(() => {\n const found = new Set<string>()\n\n for (const template of templates.value) {\n if (template.category) {\n found.add(template.category)\n }\n }\n\n return [...found].map((value) => ({ value, label: value }))\n})\n\nconst visibleTemplates = computed(() => {\n const byQuery = filterTemplates(templates.value, query.value)\n const byCategory = category.value\n ? byQuery.filter((template) => template.category === category.value)\n : byQuery\n\n return props.withUnavailable ? byCategory : byCategory.filter(isTemplateSendable)\n})\n\nconst parameters = computed(() => getTemplateParameters(selectedTemplate.value))\n\nconst hasTemplates = computed(() => visibleTemplates.value.length > 0)\nconst showLoading = computed(() => Boolean(props.loading) && templates.value.length === 0)\nconst showError = computed(() => Boolean(props.error) && templates.value.length === 0)\n\nfunction bodyPreview(template: WhatsAppTemplate): string {\n return getTemplateBody(template)?.text ?? template.description ?? ''\n}\n\nfunction selectTemplate(template: WhatsAppTemplate) {\n if (!isTemplateSendable(template)) {\n return\n }\n\n setSelectedId(template.id)\n emit('select', template)\n}\n\nfunction back() {\n setSelectedId(null)\n}\n\ntype ParameterSection = 'header' | 'body'\n\nfunction sectionValue(section: ParameterSection, key: string): string {\n return values.value[section]?.[key] ?? ''\n}\n\nfunction setSectionValue(section: ParameterSection, key: string, value: string) {\n setValues({\n ...values.value,\n [section]: { ...values.value[section], [key]: value },\n })\n}\n\nfunction buttonValue(index: number, key: string): string {\n return values.value.buttons?.[String(index)]?.[key] ?? ''\n}\n\nfunction setButtonValue(index: number, key: string, value: string) {\n const buttonKey = String(index)\n\n setValues({\n ...values.value,\n buttons: {\n ...values.value.buttons,\n [buttonKey]: { ...values.value.buttons?.[buttonKey], [key]: value },\n },\n })\n}\n\nfunction setHeaderMedia(attachment: WhatsAppAttachment | null) {\n setValues({ ...values.value, headerMedia: attachment })\n}\n\nfunction parameterLabel(parameter: WhatsAppTemplateParameter): string {\n return parameter.label ?? `{{${parameter.key}}}`\n}\n\nfunction submit() {\n const template = selectedTemplate.value\n\n if (!template) {\n return\n }\n\n const validation = validateTemplateValues(template, values.value, config.labels)\n errors.value = validation.errors\n\n if (validation.valid) {\n emit('submit', { template, values: values.value })\n }\n}\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('templateSelectorRoot') }\">\n <template v-if=\"!selectedTemplate\">\n <Box\n v-if=\"props.withSearch || (props.withCategoryFilter && categories.length > 0)\"\n v-bind=\"getStyles('templateSelectorControls')\"\n >\n <TextInput\n v-if=\"props.withSearch\"\n :model-value=\"query\"\n :placeholder=\"config.labels.templateSearchPlaceholder\"\n :aria-label=\"config.labels.templateSearchPlaceholder\"\n size=\"sm\"\n style=\"flex: 1\"\n @update:model-value=\"setQuery($event)\"\n >\n <template #leftSection>\n <WhatsAppIcon name=\"search\" size=\"16\" />\n </template>\n </TextInput>\n\n <Select\n v-if=\"props.withCategoryFilter && categories.length > 0\"\n :model-value=\"category\"\n :data=\"categories\"\n :placeholder=\"config.labels.templateCategoryLabel\"\n :aria-label=\"config.labels.templateCategoryLabel\"\n size=\"sm\"\n clearable\n @update:model-value=\"setCategory($event as string | null)\"\n />\n </Box>\n\n <Center v-if=\"showLoading\" v-bind=\"getStyles('templateSelectorState')\">\n <Loader size=\"sm\" />\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.templatesLoading }}</Text>\n </Center>\n\n <Alert\n v-else-if=\"showError\"\n color=\"red\"\n variant=\"light\"\n :title=\"config.labels.templatesError\"\n >\n <Text size=\"sm\">{{ props.error }}</Text>\n <Button mt=\"sm\" size=\"xs\" variant=\"light\" color=\"red\" @click=\"emit('retryLoad')\">\n {{ config.labels.retry }}\n </Button>\n </Alert>\n\n <Box v-else-if=\"!hasTemplates\" v-bind=\"getStyles('templateSelectorState')\">\n <slot v-if=\"slots.emptyTemplates\" name=\"emptyTemplates\" />\n <Text v-else size=\"sm\" c=\"dimmed\">{{ config.labels.templatesEmpty }}</Text>\n </Box>\n\n <Box\n v-else\n component=\"ul\"\n v-bind=\"getStyles('templateSelectorList')\"\n :aria-label=\"config.labels.templateSelectorTitle\"\n >\n <Box v-for=\"template in visibleTemplates\" :key=\"template.id\" component=\"li\">\n <slot\n v-if=\"slots.templateItem\"\n name=\"templateItem\"\n :template=\"template\"\n :selected=\"template.id === selectedId\"\n />\n\n <UnstyledButton\n v-else\n v-bind=\"getStyles('templateSelectorItem')\"\n type=\"button\"\n :disabled=\"!isTemplateSendable(template)\"\n :data-disabled=\"isTemplateSendable(template) ? undefined : ''\"\n :data-selected=\"template.id === selectedId ? '' : undefined\"\n :aria-describedby=\"\n isTemplateSendable(template) ? undefined : `${template.id}-unavailable`\n \"\n @click=\"selectTemplate(template)\"\n >\n <Box v-bind=\"getStyles('templateSelectorItemName')\">{{ template.name }}</Box>\n\n <Box v-bind=\"getStyles('templateSelectorItemMeta')\">\n <Badge v-if=\"template.category\" size=\"xs\" variant=\"light\">\n {{ template.category }}\n </Badge>\n <Badge size=\"xs\" variant=\"default\">\n {{ template.languageLabel ?? template.language }}\n </Badge>\n <Badge\n v-if=\"!isTemplateSendable(template)\"\n :id=\"`${template.id}-unavailable`\"\n size=\"xs\"\n color=\"orange\"\n variant=\"light\"\n >\n {{ template.status }}\n </Badge>\n </Box>\n\n <Box v-bind=\"getStyles('templateSelectorItemBody')\">{{ bodyPreview(template) }}</Box>\n </UnstyledButton>\n </Box>\n </Box>\n </template>\n\n <template v-else>\n <Box v-bind=\"getStyles('templateSelectorDetail')\">\n <Box v-bind=\"getStyles('templateSelectorPreview')\">\n <slot v-if=\"slots.templatePreview\" name=\"templatePreview\" :template=\"selectedTemplate\" />\n <WhatsAppTemplatePreview\n v-else\n :template=\"selectedTemplate\"\n :values=\"values\"\n with-meta\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n />\n </Box>\n\n <Box\n v-if=\"parameters.hasParameters\"\n component=\"form\"\n v-bind=\"getStyles('templateSelectorForm')\"\n :aria-label=\"config.labels.templateParameters\"\n @submit.prevent=\"submit\"\n >\n <Box v-if=\"parameters.requiresHeaderMedia\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateHeaderMedia }}\n </Box>\n\n <slot\n v-if=\"slots.headerMedia\"\n name=\"headerMedia\"\n :value=\"values.headerMedia ?? null\"\n :set-value=\"setHeaderMedia\"\n :error=\"errors.headerMedia\"\n />\n <Text v-else-if=\"errors.headerMedia\" size=\"xs\" c=\"red\">\n {{ errors.headerMedia }}\n </Text>\n </Box>\n\n <Box v-if=\"parameters.header.length > 0\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateHeaderVariables }}\n </Box>\n\n <TextInput\n v-for=\"parameter in parameters.header\"\n :key=\"parameter.key\"\n size=\"sm\"\n :label=\"parameterLabel(parameter)\"\n :description=\"parameter.description\"\n :placeholder=\"parameter.placeholder ?? parameter.example\"\n :maxlength=\"parameter.maxLength\"\n :required=\"parameter.required ?? true\"\n :error=\"errors.header[parameter.key]\"\n :model-value=\"sectionValue('header', parameter.key)\"\n @update:model-value=\"setSectionValue('header', parameter.key, $event)\"\n />\n </Box>\n\n <Box v-if=\"parameters.body.length > 0\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateBodyVariables }}\n </Box>\n\n <Textarea\n v-for=\"parameter in parameters.body\"\n :key=\"parameter.key\"\n size=\"sm\"\n autosize\n :min-rows=\"1\"\n :max-rows=\"4\"\n :label=\"parameterLabel(parameter)\"\n :description=\"parameter.description\"\n :placeholder=\"parameter.placeholder ?? parameter.example\"\n :maxlength=\"parameter.maxLength\"\n :required=\"parameter.required ?? true\"\n :error=\"errors.body[parameter.key]\"\n :model-value=\"sectionValue('body', parameter.key)\"\n @update:model-value=\"setSectionValue('body', parameter.key, $event)\"\n />\n </Box>\n\n <Box v-if=\"parameters.buttons.length > 0\" v-bind=\"getStyles('templateSelectorSection')\">\n <Box v-bind=\"getStyles('templateSelectorSectionTitle')\">\n {{ config.labels.templateButtonVariables }}\n </Box>\n\n <template v-for=\"entry in parameters.buttons\" :key=\"entry.index\">\n <TextInput\n v-for=\"parameter in entry.parameters\"\n :key=\"`${entry.index}-${parameter.key}`\"\n size=\"sm\"\n :label=\"`${entry.button.text} — ${parameterLabel(parameter)}`\"\n :description=\"parameter.description\"\n :placeholder=\"parameter.placeholder ?? parameter.example\"\n :maxlength=\"parameter.maxLength\"\n :required=\"parameter.required ?? true\"\n :error=\"errors.buttons[String(entry.index)]?.[parameter.key]\"\n :model-value=\"buttonValue(entry.index, parameter.key)\"\n @update:model-value=\"setButtonValue(entry.index, parameter.key, $event)\"\n />\n </template>\n </Box>\n </Box>\n </Box>\n\n <Box v-bind=\"getStyles('templateSelectorFooter')\">\n <Button variant=\"subtle\" size=\"sm\" @click=\"back\">\n <WhatsAppIcon name=\"arrowLeft\" size=\"16\" />\n {{ config.labels.templateBack }}\n </Button>\n\n <Button size=\"sm\" :disabled=\"!isTemplateSendable(selectedTemplate)\" @click=\"submit\">\n {{ config.labels.templateSubmit }}\n </Button>\n </Box>\n </template>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppTemplateSelectorComponent from './WhatsAppTemplateSelector.vue'\nimport type { WhatsAppTemplateSelectorFactory } from './WhatsAppTemplateSelector.types'\nimport classes from './WhatsAppTemplateSelector.module.css'\n\nexport const WhatsAppTemplateSelector = factory<WhatsAppTemplateSelectorFactory>(\n WhatsAppTemplateSelectorComponent,\n { classes },\n)\n\nexport type {\n WhatsAppTemplateSelectorEmits,\n WhatsAppTemplateSelectorFactory,\n WhatsAppTemplateSelectorOwnProps,\n WhatsAppTemplateSelectorProps,\n WhatsAppTemplateSelectorSlots,\n WhatsAppTemplateSelectorStylesNames,\n WhatsAppTemplateSubmitPayload,\n} from './WhatsAppTemplateSelector.types'\n",".composerRoot {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-sm);\n border-top: 1px solid var(--mantine-color-default-border);\n background-color: var(--mantine-color-body);\n}\n\n.composerNotice {\n width: 100%;\n}\n\n.composerReply {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n padding: 6px 8px;\n border-radius: var(--mantine-radius-sm);\n border-inline-start: 3px solid var(--mantine-color-anchor);\n background-color: var(--mantine-color-default-hover);\n}\n\n.composerReplyBody {\n flex: 1;\n min-width: 0;\n}\n\n.composerReplyAuthor {\n font-size: var(--mantine-font-size-xs);\n font-weight: 600;\n color: var(--mantine-color-anchor);\n}\n\n.composerReplyText {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.composerAttachments {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mantine-spacing-xs);\n}\n\n.composerError {\n width: 100%;\n}\n\n.composerInputRow {\n display: flex;\n align-items: flex-end;\n gap: 4px;\n}\n\n.composerInput {\n flex: 1;\n min-width: 0;\n}\n\n.composerActions {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.composerAction {\n flex-shrink: 0;\n}\n\n.composerSend {\n flex-shrink: 0;\n}\n\n.composerFooter {\n display: flex;\n justify-content: flex-end;\n}\n\n.composerCount {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n}\n\n.composerCount:where([data-exceeded]) {\n color: var(--mantine-color-error);\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n sendOnEnter: true,\n withEmojiPicker: true,\n minRows: 1,\n maxRows: 6,\n withCharacterCount: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots } from 'vue'\nimport {\n ActionIcon,\n Alert,\n Box,\n Button,\n FileButton,\n Loader,\n Modal,\n Popover,\n Textarea,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useResolvedCapabilities, useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppEmoji } from '../../emoji'\nimport type {\n WhatsAppInteractiveContent,\n WhatsAppOutgoingMessage,\n WhatsAppUpload,\n} from '../../types'\nimport { createClientId, getAcceptAttribute, validateFiles } from '../../utils'\nimport { WhatsAppAttachmentPreview } from '../WhatsAppAttachmentPreview'\nimport { WhatsAppEmojiPicker } from '../WhatsAppEmojiPicker'\nimport { WhatsAppInteractiveMessageEditor } from '../WhatsAppInteractiveMessageEditor'\nimport { WhatsAppMessagingWindowNotice } from '../WhatsAppMessagingWindowNotice'\nimport { WhatsAppTemplateSelector } from '../WhatsAppTemplateSelector'\nimport type { WhatsAppTemplateSubmitPayload } from '../WhatsAppTemplateSelector'\nimport type {\n WhatsAppComposerEmits,\n WhatsAppComposerOwnProps,\n WhatsAppComposerSlots,\n} from './WhatsAppComposer.types'\nimport classes from './WhatsAppComposer.module.css'\n\ndefineOptions({\n name: 'WhatsAppComposer',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppComposerOwnProps>(), {\n conversationId: undefined,\n modelValue: undefined,\n defaultValue: undefined,\n capabilities: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n templatesOpened: undefined,\n interactiveOpened: undefined,\n sending: undefined,\n disabled: undefined,\n error: undefined,\n replyTo: undefined,\n placeholder: undefined,\n sendOnEnter: undefined,\n minRows: undefined,\n maxRows: undefined,\n autofocus: undefined,\n withAttachments: undefined,\n withTemplates: undefined,\n withEmoji: undefined,\n withEmojiPicker: undefined,\n emojiPickerProps: undefined,\n withInteractive: undefined,\n withCharacterCount: undefined,\n templateModalProps: undefined,\n interactiveModalProps: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppComposerEmits>()\ndefineSlots<WhatsAppComposerSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppComposer', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst capabilities = useResolvedCapabilities(() => props.capabilities)\n\nconst getStyles = useStyles({\n name: 'WhatsAppComposer',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'composerRoot',\n})\n\nconst [text, setText] = useUncontrolled<string>({\n value: () => props.modelValue,\n defaultValue: props.defaultValue,\n finalValue: '',\n onChange: (value) => {\n emit('update:modelValue', value)\n emit('typing', value)\n },\n})\n\nconst [templatesOpened, setTemplatesOpened] = useUncontrolled<boolean>({\n value: () => props.templatesOpened,\n finalValue: false,\n onChange: (value) => emit('update:templatesOpened', value),\n})\n\nconst [interactiveOpened, setInteractiveOpened] = useUncontrolled<boolean>({\n value: () => props.interactiveOpened,\n finalValue: false,\n onChange: (value) => emit('update:interactiveOpened', value),\n})\n\nconst inputElement = ref<HTMLTextAreaElement | null>(null)\n\n/**\n * `Textarea.rootRef` provides the native element needed for caret-aware emoji insertion.\n */\nconst setInputElement = (node: Element | null) => {\n inputElement.value = node as HTMLTextAreaElement | null\n}\nconst emojiOpened = ref(false)\nconst validationMessage = ref<string | null>(null)\nconst interactiveDraft = ref<WhatsAppInteractiveContent | undefined>(undefined)\n\nconst uploads = computed<WhatsAppUpload[]>(() => props.uploads ?? [])\nconst readyAttachments = computed(() =>\n uploads.value\n .filter((upload) => upload.status === 'uploaded' && upload.attachment)\n .map((upload) => upload.attachment!),\n)\nconst uploadsInFlight = computed(() =>\n uploads.value.some((upload) => upload.status === 'pending' || upload.status === 'uploading'),\n)\n\n/**\n * Explicit `with*` props win over the capabilities so a single screen can hide a control the\n * backend would otherwise allow; when they are unset the capabilities decide, which is the\n * normal path.\n */\nconst showAttachments = computed(() => props.withAttachments ?? capabilities.value.canSendMedia)\nconst showTemplates = computed(() => props.withTemplates ?? capabilities.value.canSendTemplates)\nconst useCustomPicker = computed(() => Boolean(slots.emojiPicker))\nconst useBuiltInPicker = computed(() => !useCustomPicker.value && props.withEmojiPicker !== false)\n\n/*\n * The control needs the capability and something to put in the popover. With the built-in picker\n * turned off and no slot supplied there is nothing to show, so the button stays hidden rather\n * than opening an empty popover.\n */\nconst showEmoji = computed(\n () =>\n (props.withEmoji ?? capabilities.value.canUseEmoji) &&\n (useCustomPicker.value || useBuiltInPicker.value),\n)\nconst showInteractive = computed(\n () =>\n props.withInteractive ??\n (capabilities.value.canSendInteractive && capabilities.value.interactiveTypes.length > 0),\n)\n\nconst windowClosed = computed(() => capabilities.value.windowClosed)\n\nconst inputDisabled = computed(() => Boolean(props.disabled) || !capabilities.value.canSendFreeForm)\n\nconst maxTextLength = computed(() => capabilities.value.maxTextLength)\nconst exceeded = computed(\n () => maxTextLength.value !== undefined && text.value.length > maxTextLength.value,\n)\n\nconst hasContent = computed(() => text.value.trim().length > 0 || readyAttachments.value.length > 0)\n\nconst canSend = computed(\n () =>\n !props.disabled &&\n !props.sending &&\n !uploadsInFlight.value &&\n !exceeded.value &&\n hasContent.value &&\n (capabilities.value.canSendFreeForm || readyAttachments.value.length > 0),\n)\n\nconst placeholder = computed(() => {\n if (props.placeholder) {\n return props.placeholder\n }\n\n if (windowClosed.value) {\n return config.labels.windowClosedTitle\n }\n\n if (inputDisabled.value) {\n return capabilities.value.disabledReason ?? config.labels.composerDisabled\n }\n\n return config.labels.composerPlaceholder\n})\n\nconst acceptAttribute = computed(() =>\n getAcceptAttribute(capabilities.value.allowedMediaTypes, capabilities.value.mediaConstraints),\n)\n\nfunction focus() {\n inputElement.value?.focus()\n}\n\n/** Inserts at the caret so an emoji lands where the user is typing, not at the end. */\nfunction insert(value: string) {\n const element = inputElement.value\n\n if (!element) {\n setText(text.value + value)\n return\n }\n\n const start = element.selectionStart ?? text.value.length\n const end = element.selectionEnd ?? start\n\n setText(`${text.value.slice(0, start)}${value}${text.value.slice(end)}`)\n\n void nextTick(() => {\n element.focus()\n const caret = start + value.length\n element.setSelectionRange(caret, caret)\n })\n}\n\nfunction selectEmoji(emoji: WhatsAppEmoji) {\n // Keep the popover open so users can insert multiple emoji.\n insert(emoji.emoji)\n}\n\nfunction openTemplates() {\n setTemplatesOpened(true)\n}\n\nfunction fail(message: string) {\n validationMessage.value = message\n emit('validationError', message)\n}\n\nfunction basePayload() {\n return {\n conversationId: props.conversationId ?? '',\n clientId: createClientId(),\n replyTo: props.replyTo?.id,\n }\n}\n\nfunction clearDraft() {\n validationMessage.value = null\n setText('')\n emit('update:replyTo', null)\n}\n\nfunction send() {\n if (props.disabled || props.sending) {\n return\n }\n\n if (uploadsInFlight.value) {\n fail(config.labels.uploading)\n return\n }\n\n if (exceeded.value && maxTextLength.value !== undefined) {\n fail(config.labels.messageTooLong(maxTextLength.value))\n return\n }\n\n if (!hasContent.value) {\n fail(config.labels.emptyMessage)\n return\n }\n\n const payload: WhatsAppOutgoingMessage =\n readyAttachments.value.length > 0\n ? {\n ...basePayload(),\n kind: 'media',\n attachments: readyAttachments.value,\n caption: text.value.trim() || undefined,\n }\n : { ...basePayload(), kind: 'text', text: text.value.trim() }\n\n emit('send', payload)\n clearDraft()\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter' || !props.sendOnEnter) {\n return\n }\n\n // Shift+Enter is a newline, and IME composition must never be interrupted by a send.\n if (event.shiftKey || event.isComposing) {\n return\n }\n\n event.preventDefault()\n send()\n}\n\nfunction handleFiles(picked: File | File[] | null) {\n const files = picked === null ? [] : Array.isArray(picked) ? picked : [picked]\n\n if (files.length === 0) {\n return\n }\n\n const { accepted, rejected } = validateFiles({\n files,\n allowedMediaTypes: capabilities.value.allowedMediaTypes,\n constraints: capabilities.value.mediaConstraints,\n existingCount: uploads.value.length,\n labels: config.labels,\n })\n\n if (rejected.length > 0) {\n emit('attachmentsReject', rejected)\n fail(rejected[0].message)\n }\n\n if (accepted.length > 0) {\n validationMessage.value = rejected.length > 0 ? validationMessage.value : null\n emit('attachmentsAdd', {\n conversationId: props.conversationId,\n files: accepted,\n rejected,\n })\n }\n}\n\nfunction submitTemplate({ template, values }: WhatsAppTemplateSubmitPayload) {\n emit('send', {\n ...basePayload(),\n kind: 'template',\n templateId: template.id,\n name: template.name,\n language: template.language,\n values,\n template,\n })\n\n setTemplatesOpened(false)\n emit('update:replyTo', null)\n}\n\nfunction submitInteractive(interactive: WhatsAppInteractiveContent) {\n emit('send', { ...basePayload(), kind: 'interactive', interactive })\n setInteractiveOpened(false)\n interactiveDraft.value = undefined\n emit('update:replyTo', null)\n}\n\nconst errorMessage = computed(() => props.error || validationMessage.value)\n\ndefineExpose({ focus, insert, openTemplates })\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('composerRoot') }\">\n <WhatsAppMessagingWindowNotice\n v-bind=\"getStyles('composerNotice')\"\n :messaging-window=\"capabilities.messagingWindow\"\n :templates-available=\"showTemplates\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @template-action=\"openTemplates\"\n />\n\n <Alert\n v-if=\"!windowClosed && capabilities.disabledReason\"\n v-bind=\"getStyles('composerNotice')\"\n color=\"gray\"\n variant=\"light\"\n >\n {{ capabilities.disabledReason }}\n </Alert>\n\n <Box v-if=\"props.replyTo\" v-bind=\"getStyles('composerReply')\">\n <WhatsAppIcon name=\"reply\" size=\"16\" />\n <Box v-bind=\"getStyles('composerReplyBody')\">\n <Box v-bind=\"getStyles('composerReplyAuthor')\">\n {{ props.replyTo.author ?? config.labels.replyingTo }}\n </Box>\n <Box v-bind=\"getStyles('composerReplyText')\">{{ props.replyTo.text }}</Box>\n </Box>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n :aria-label=\"config.labels.cancelReply\"\n @click=\"emit('update:replyTo', null)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Box\n v-if=\"uploads.length > 0\"\n v-bind=\"getStyles('composerAttachments')\"\n :aria-label=\"config.labels.attachmentsLabel\"\n role=\"group\"\n >\n <template v-for=\"upload in uploads\" :key=\"upload.id\">\n <slot v-if=\"slots.attachmentPreview\" name=\"attachmentPreview\" :upload=\"upload\" />\n <WhatsAppAttachmentPreview\n v-else\n :upload=\"upload\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @remove=\"emit('attachmentRemove', $event)\"\n @retry=\"emit('attachmentRetry', $event)\"\n @cancel=\"emit('attachmentCancel', $event)\"\n />\n </template>\n </Box>\n\n <Alert\n v-if=\"errorMessage\"\n v-bind=\"getStyles('composerError')\"\n color=\"red\"\n variant=\"light\"\n role=\"alert\"\n :with-close-button=\"!props.error\"\n @close=\"validationMessage = null\"\n >\n {{ errorMessage }}\n <Button\n v-if=\"props.error\"\n ml=\"sm\"\n size=\"compact-xs\"\n variant=\"light\"\n color=\"red\"\n @click=\"emit('retrySend')\"\n >\n {{ config.labels.retry }}\n </Button>\n </Alert>\n\n <Box v-bind=\"getStyles('composerInputRow')\">\n <slot v-if=\"slots.composerActions\" name=\"composerActions\" />\n\n <template v-else>\n <Box v-bind=\"getStyles('composerActions')\">\n <FileButton\n v-if=\"showAttachments\"\n multiple\n :accept=\"acceptAttribute\"\n :disabled=\"props.disabled || !capabilities.canSendMedia\"\n @change=\"handleFiles\"\n >\n <template #default=\"fileProps\">\n <ActionIcon\n v-bind=\"{ ...fileProps, ...getStyles('composerAction') }\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || !capabilities.canSendMedia\"\n :aria-label=\"config.labels.attachFile\"\n >\n <WhatsAppIcon name=\"paperclip\" size=\"20\" />\n </ActionIcon>\n </template>\n </FileButton>\n\n <Popover\n v-if=\"showEmoji\"\n v-model:opened=\"emojiOpened\"\n position=\"top-start\"\n trap-focus\n shadow=\"md\"\n >\n <Popover.Target>\n <ActionIcon\n v-bind=\"getStyles('composerAction')\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"inputDisabled\"\n :aria-label=\"config.labels.emoji\"\n :aria-expanded=\"emojiOpened\"\n @click=\"emojiOpened = !emojiOpened\"\n >\n <WhatsAppIcon name=\"emoji\" size=\"20\" />\n </ActionIcon>\n </Popover.Target>\n\n <Popover.Dropdown p=\"xs\">\n <slot\n v-if=\"useCustomPicker\"\n name=\"emojiPicker\"\n :insert=\"insert\"\n :close=\"() => (emojiOpened = false)\"\n />\n\n <WhatsAppEmojiPicker\n v-else\n v-bind=\"props.emojiPickerProps\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @select=\"selectEmoji\"\n />\n </Popover.Dropdown>\n </Popover>\n </Box>\n\n <slot name=\"composerPrefix\" />\n\n <Textarea\n v-bind=\"getStyles('composerInput')\"\n :model-value=\"text\"\n :placeholder=\"placeholder\"\n :aria-label=\"config.labels.composerLabel\"\n :disabled=\"inputDisabled\"\n :maxlength=\"maxTextLength\"\n :autofocus=\"props.autofocus\"\n :min-rows=\"props.minRows\"\n :max-rows=\"props.maxRows\"\n autosize\n :root-ref=\"setInputElement\"\n @update:model-value=\"setText($event)\"\n @keydown=\"handleKeydown\"\n />\n\n <slot name=\"composerSuffix\" />\n\n <Box v-bind=\"getStyles('composerActions')\">\n <ActionIcon\n v-if=\"showTemplates\"\n v-bind=\"getStyles('composerAction')\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || !capabilities.canSendTemplates\"\n :aria-label=\"config.labels.templates\"\n @click=\"openTemplates\"\n >\n <WhatsAppIcon name=\"template\" size=\"20\" />\n </ActionIcon>\n\n <ActionIcon\n v-if=\"showInteractive\"\n v-bind=\"getStyles('composerAction')\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || !capabilities.canSendInteractive\"\n :aria-label=\"config.labels.interactiveMessage\"\n @click=\"setInteractiveOpened(true)\"\n >\n <WhatsAppIcon name=\"interactive\" size=\"20\" />\n </ActionIcon>\n\n <ActionIcon\n v-bind=\"getStyles('composerSend')\"\n variant=\"filled\"\n radius=\"xl\"\n :disabled=\"!canSend\"\n :aria-label=\"props.sending ? config.labels.sending : config.labels.send\"\n @click=\"send\"\n >\n <Loader v-if=\"props.sending\" size=\"xs\" color=\"white\" />\n <WhatsAppIcon v-else name=\"send\" size=\"18\" />\n </ActionIcon>\n </Box>\n </template>\n </Box>\n\n <Box\n v-if=\"props.withCharacterCount && maxTextLength !== undefined\"\n v-bind=\"getStyles('composerFooter')\"\n >\n <Box\n component=\"span\"\n v-bind=\"getStyles('composerCount')\"\n :data-exceeded=\"exceeded ? '' : undefined\"\n aria-live=\"polite\"\n >\n {{ config.labels.characterCount(text.length, maxTextLength) }}\n </Box>\n </Box>\n\n <Modal\n v-bind=\"props.templateModalProps\"\n :opened=\"templatesOpened\"\n :title=\"config.labels.templateSelectorTitle\"\n size=\"lg\"\n @close=\"setTemplatesOpened(false)\"\n >\n <WhatsAppTemplateSelector\n :templates=\"props.templates\"\n :loading=\"props.templatesLoading\"\n :error=\"props.templatesError\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @submit=\"submitTemplate\"\n @retry-load=\"emit('templatesRetryLoad')\"\n >\n <template v-if=\"slots.templatePreview\" #templatePreview=\"previewProps\">\n <slot name=\"templatePreview\" v-bind=\"previewProps\" />\n </template>\n </WhatsAppTemplateSelector>\n </Modal>\n\n <Modal\n v-bind=\"props.interactiveModalProps\"\n :opened=\"interactiveOpened\"\n :title=\"config.labels.interactiveTitle\"\n size=\"lg\"\n @close=\"setInteractiveOpened(false)\"\n >\n <WhatsAppInteractiveMessageEditor\n v-model=\"interactiveDraft\"\n :interactive-types=\"capabilities.interactiveTypes\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @submit=\"submitInteractive\"\n @cancel=\"setInteractiveOpened(false)\"\n />\n </Modal>\n </Box>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n sendOnEnter: true,\n withEmojiPicker: true,\n minRows: 1,\n maxRows: 6,\n withCharacterCount: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots } from 'vue'\nimport {\n ActionIcon,\n Alert,\n Box,\n Button,\n FileButton,\n Loader,\n Modal,\n Popover,\n Textarea,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useResolvedCapabilities, useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppEmoji } from '../../emoji'\nimport type {\n WhatsAppInteractiveContent,\n WhatsAppOutgoingMessage,\n WhatsAppUpload,\n} from '../../types'\nimport { createClientId, getAcceptAttribute, validateFiles } from '../../utils'\nimport { WhatsAppAttachmentPreview } from '../WhatsAppAttachmentPreview'\nimport { WhatsAppEmojiPicker } from '../WhatsAppEmojiPicker'\nimport { WhatsAppInteractiveMessageEditor } from '../WhatsAppInteractiveMessageEditor'\nimport { WhatsAppMessagingWindowNotice } from '../WhatsAppMessagingWindowNotice'\nimport { WhatsAppTemplateSelector } from '../WhatsAppTemplateSelector'\nimport type { WhatsAppTemplateSubmitPayload } from '../WhatsAppTemplateSelector'\nimport type {\n WhatsAppComposerEmits,\n WhatsAppComposerOwnProps,\n WhatsAppComposerSlots,\n} from './WhatsAppComposer.types'\nimport classes from './WhatsAppComposer.module.css'\n\ndefineOptions({\n name: 'WhatsAppComposer',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppComposerOwnProps>(), {\n conversationId: undefined,\n modelValue: undefined,\n defaultValue: undefined,\n capabilities: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n templatesOpened: undefined,\n interactiveOpened: undefined,\n sending: undefined,\n disabled: undefined,\n error: undefined,\n replyTo: undefined,\n placeholder: undefined,\n sendOnEnter: undefined,\n minRows: undefined,\n maxRows: undefined,\n autofocus: undefined,\n withAttachments: undefined,\n withTemplates: undefined,\n withEmoji: undefined,\n withEmojiPicker: undefined,\n emojiPickerProps: undefined,\n withInteractive: undefined,\n withCharacterCount: undefined,\n templateModalProps: undefined,\n interactiveModalProps: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppComposerEmits>()\ndefineSlots<WhatsAppComposerSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppComposer', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst capabilities = useResolvedCapabilities(() => props.capabilities)\n\nconst getStyles = useStyles({\n name: 'WhatsAppComposer',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'composerRoot',\n})\n\nconst [text, setText] = useUncontrolled<string>({\n value: () => props.modelValue,\n defaultValue: props.defaultValue,\n finalValue: '',\n onChange: (value) => {\n emit('update:modelValue', value)\n emit('typing', value)\n },\n})\n\nconst [templatesOpened, setTemplatesOpened] = useUncontrolled<boolean>({\n value: () => props.templatesOpened,\n finalValue: false,\n onChange: (value) => emit('update:templatesOpened', value),\n})\n\nconst [interactiveOpened, setInteractiveOpened] = useUncontrolled<boolean>({\n value: () => props.interactiveOpened,\n finalValue: false,\n onChange: (value) => emit('update:interactiveOpened', value),\n})\n\nconst inputElement = ref<HTMLTextAreaElement | null>(null)\n\n/**\n * `Textarea.rootRef` provides the native element needed for caret-aware emoji insertion.\n */\nconst setInputElement = (node: Element | null) => {\n inputElement.value = node as HTMLTextAreaElement | null\n}\nconst emojiOpened = ref(false)\nconst validationMessage = ref<string | null>(null)\nconst interactiveDraft = ref<WhatsAppInteractiveContent | undefined>(undefined)\n\nconst uploads = computed<WhatsAppUpload[]>(() => props.uploads ?? [])\nconst readyAttachments = computed(() =>\n uploads.value\n .filter((upload) => upload.status === 'uploaded' && upload.attachment)\n .map((upload) => upload.attachment!),\n)\nconst uploadsInFlight = computed(() =>\n uploads.value.some((upload) => upload.status === 'pending' || upload.status === 'uploading'),\n)\n\n/**\n * Explicit `with*` props win over the capabilities so a single screen can hide a control the\n * backend would otherwise allow; when they are unset the capabilities decide, which is the\n * normal path.\n */\nconst showAttachments = computed(() => props.withAttachments ?? capabilities.value.canSendMedia)\nconst showTemplates = computed(() => props.withTemplates ?? capabilities.value.canSendTemplates)\nconst useCustomPicker = computed(() => Boolean(slots.emojiPicker))\nconst useBuiltInPicker = computed(() => !useCustomPicker.value && props.withEmojiPicker !== false)\n\n/*\n * The control needs the capability and something to put in the popover. With the built-in picker\n * turned off and no slot supplied there is nothing to show, so the button stays hidden rather\n * than opening an empty popover.\n */\nconst showEmoji = computed(\n () =>\n (props.withEmoji ?? capabilities.value.canUseEmoji) &&\n (useCustomPicker.value || useBuiltInPicker.value),\n)\nconst showInteractive = computed(\n () =>\n props.withInteractive ??\n (capabilities.value.canSendInteractive && capabilities.value.interactiveTypes.length > 0),\n)\n\nconst windowClosed = computed(() => capabilities.value.windowClosed)\n\nconst inputDisabled = computed(() => Boolean(props.disabled) || !capabilities.value.canSendFreeForm)\n\nconst maxTextLength = computed(() => capabilities.value.maxTextLength)\nconst exceeded = computed(\n () => maxTextLength.value !== undefined && text.value.length > maxTextLength.value,\n)\n\nconst hasContent = computed(() => text.value.trim().length > 0 || readyAttachments.value.length > 0)\n\nconst canSend = computed(\n () =>\n !props.disabled &&\n !props.sending &&\n !uploadsInFlight.value &&\n !exceeded.value &&\n hasContent.value &&\n (capabilities.value.canSendFreeForm || readyAttachments.value.length > 0),\n)\n\nconst placeholder = computed(() => {\n if (props.placeholder) {\n return props.placeholder\n }\n\n if (windowClosed.value) {\n return config.labels.windowClosedTitle\n }\n\n if (inputDisabled.value) {\n return capabilities.value.disabledReason ?? config.labels.composerDisabled\n }\n\n return config.labels.composerPlaceholder\n})\n\nconst acceptAttribute = computed(() =>\n getAcceptAttribute(capabilities.value.allowedMediaTypes, capabilities.value.mediaConstraints),\n)\n\nfunction focus() {\n inputElement.value?.focus()\n}\n\n/** Inserts at the caret so an emoji lands where the user is typing, not at the end. */\nfunction insert(value: string) {\n const element = inputElement.value\n\n if (!element) {\n setText(text.value + value)\n return\n }\n\n const start = element.selectionStart ?? text.value.length\n const end = element.selectionEnd ?? start\n\n setText(`${text.value.slice(0, start)}${value}${text.value.slice(end)}`)\n\n void nextTick(() => {\n element.focus()\n const caret = start + value.length\n element.setSelectionRange(caret, caret)\n })\n}\n\nfunction selectEmoji(emoji: WhatsAppEmoji) {\n // Keep the popover open so users can insert multiple emoji.\n insert(emoji.emoji)\n}\n\nfunction openTemplates() {\n setTemplatesOpened(true)\n}\n\nfunction fail(message: string) {\n validationMessage.value = message\n emit('validationError', message)\n}\n\nfunction basePayload() {\n return {\n conversationId: props.conversationId ?? '',\n clientId: createClientId(),\n replyTo: props.replyTo?.id,\n }\n}\n\nfunction clearDraft() {\n validationMessage.value = null\n setText('')\n emit('update:replyTo', null)\n}\n\nfunction send() {\n if (props.disabled || props.sending) {\n return\n }\n\n if (uploadsInFlight.value) {\n fail(config.labels.uploading)\n return\n }\n\n if (exceeded.value && maxTextLength.value !== undefined) {\n fail(config.labels.messageTooLong(maxTextLength.value))\n return\n }\n\n if (!hasContent.value) {\n fail(config.labels.emptyMessage)\n return\n }\n\n const payload: WhatsAppOutgoingMessage =\n readyAttachments.value.length > 0\n ? {\n ...basePayload(),\n kind: 'media',\n attachments: readyAttachments.value,\n caption: text.value.trim() || undefined,\n }\n : { ...basePayload(), kind: 'text', text: text.value.trim() }\n\n emit('send', payload)\n clearDraft()\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter' || !props.sendOnEnter) {\n return\n }\n\n // Shift+Enter is a newline, and IME composition must never be interrupted by a send.\n if (event.shiftKey || event.isComposing) {\n return\n }\n\n event.preventDefault()\n send()\n}\n\nfunction handleFiles(picked: File | File[] | null) {\n const files = picked === null ? [] : Array.isArray(picked) ? picked : [picked]\n\n if (files.length === 0) {\n return\n }\n\n const { accepted, rejected } = validateFiles({\n files,\n allowedMediaTypes: capabilities.value.allowedMediaTypes,\n constraints: capabilities.value.mediaConstraints,\n existingCount: uploads.value.length,\n labels: config.labels,\n })\n\n if (rejected.length > 0) {\n emit('attachmentsReject', rejected)\n fail(rejected[0].message)\n }\n\n if (accepted.length > 0) {\n validationMessage.value = rejected.length > 0 ? validationMessage.value : null\n emit('attachmentsAdd', {\n conversationId: props.conversationId,\n files: accepted,\n rejected,\n })\n }\n}\n\nfunction submitTemplate({ template, values }: WhatsAppTemplateSubmitPayload) {\n emit('send', {\n ...basePayload(),\n kind: 'template',\n templateId: template.id,\n name: template.name,\n language: template.language,\n values,\n template,\n })\n\n setTemplatesOpened(false)\n emit('update:replyTo', null)\n}\n\nfunction submitInteractive(interactive: WhatsAppInteractiveContent) {\n emit('send', { ...basePayload(), kind: 'interactive', interactive })\n setInteractiveOpened(false)\n interactiveDraft.value = undefined\n emit('update:replyTo', null)\n}\n\nconst errorMessage = computed(() => props.error || validationMessage.value)\n\ndefineExpose({ focus, insert, openTemplates })\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('composerRoot') }\">\n <WhatsAppMessagingWindowNotice\n v-bind=\"getStyles('composerNotice')\"\n :messaging-window=\"capabilities.messagingWindow\"\n :templates-available=\"showTemplates\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @template-action=\"openTemplates\"\n />\n\n <Alert\n v-if=\"!windowClosed && capabilities.disabledReason\"\n v-bind=\"getStyles('composerNotice')\"\n color=\"gray\"\n variant=\"light\"\n >\n {{ capabilities.disabledReason }}\n </Alert>\n\n <Box v-if=\"props.replyTo\" v-bind=\"getStyles('composerReply')\">\n <WhatsAppIcon name=\"reply\" size=\"16\" />\n <Box v-bind=\"getStyles('composerReplyBody')\">\n <Box v-bind=\"getStyles('composerReplyAuthor')\">\n {{ props.replyTo.author ?? config.labels.replyingTo }}\n </Box>\n <Box v-bind=\"getStyles('composerReplyText')\">{{ props.replyTo.text }}</Box>\n </Box>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n :aria-label=\"config.labels.cancelReply\"\n @click=\"emit('update:replyTo', null)\"\n >\n <WhatsAppIcon name=\"close\" size=\"16\" />\n </ActionIcon>\n </Box>\n\n <Box\n v-if=\"uploads.length > 0\"\n v-bind=\"getStyles('composerAttachments')\"\n :aria-label=\"config.labels.attachmentsLabel\"\n role=\"group\"\n >\n <template v-for=\"upload in uploads\" :key=\"upload.id\">\n <slot v-if=\"slots.attachmentPreview\" name=\"attachmentPreview\" :upload=\"upload\" />\n <WhatsAppAttachmentPreview\n v-else\n :upload=\"upload\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @remove=\"emit('attachmentRemove', $event)\"\n @retry=\"emit('attachmentRetry', $event)\"\n @cancel=\"emit('attachmentCancel', $event)\"\n />\n </template>\n </Box>\n\n <Alert\n v-if=\"errorMessage\"\n v-bind=\"getStyles('composerError')\"\n color=\"red\"\n variant=\"light\"\n role=\"alert\"\n :with-close-button=\"!props.error\"\n @close=\"validationMessage = null\"\n >\n {{ errorMessage }}\n <Button\n v-if=\"props.error\"\n ml=\"sm\"\n size=\"compact-xs\"\n variant=\"light\"\n color=\"red\"\n @click=\"emit('retrySend')\"\n >\n {{ config.labels.retry }}\n </Button>\n </Alert>\n\n <Box v-bind=\"getStyles('composerInputRow')\">\n <slot v-if=\"slots.composerActions\" name=\"composerActions\" />\n\n <template v-else>\n <Box v-bind=\"getStyles('composerActions')\">\n <FileButton\n v-if=\"showAttachments\"\n multiple\n :accept=\"acceptAttribute\"\n :disabled=\"props.disabled || !capabilities.canSendMedia\"\n @change=\"handleFiles\"\n >\n <template #default=\"fileProps\">\n <ActionIcon\n v-bind=\"{ ...fileProps, ...getStyles('composerAction') }\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || !capabilities.canSendMedia\"\n :aria-label=\"config.labels.attachFile\"\n >\n <WhatsAppIcon name=\"paperclip\" size=\"20\" />\n </ActionIcon>\n </template>\n </FileButton>\n\n <Popover\n v-if=\"showEmoji\"\n v-model:opened=\"emojiOpened\"\n position=\"top-start\"\n trap-focus\n shadow=\"md\"\n >\n <Popover.Target>\n <ActionIcon\n v-bind=\"getStyles('composerAction')\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"inputDisabled\"\n :aria-label=\"config.labels.emoji\"\n :aria-expanded=\"emojiOpened\"\n @click=\"emojiOpened = !emojiOpened\"\n >\n <WhatsAppIcon name=\"emoji\" size=\"20\" />\n </ActionIcon>\n </Popover.Target>\n\n <Popover.Dropdown p=\"xs\">\n <slot\n v-if=\"useCustomPicker\"\n name=\"emojiPicker\"\n :insert=\"insert\"\n :close=\"() => (emojiOpened = false)\"\n />\n\n <WhatsAppEmojiPicker\n v-else\n v-bind=\"props.emojiPickerProps\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @select=\"selectEmoji\"\n />\n </Popover.Dropdown>\n </Popover>\n </Box>\n\n <slot name=\"composerPrefix\" />\n\n <Textarea\n v-bind=\"getStyles('composerInput')\"\n :model-value=\"text\"\n :placeholder=\"placeholder\"\n :aria-label=\"config.labels.composerLabel\"\n :disabled=\"inputDisabled\"\n :maxlength=\"maxTextLength\"\n :autofocus=\"props.autofocus\"\n :min-rows=\"props.minRows\"\n :max-rows=\"props.maxRows\"\n autosize\n :root-ref=\"setInputElement\"\n @update:model-value=\"setText($event)\"\n @keydown=\"handleKeydown\"\n />\n\n <slot name=\"composerSuffix\" />\n\n <Box v-bind=\"getStyles('composerActions')\">\n <ActionIcon\n v-if=\"showTemplates\"\n v-bind=\"getStyles('composerAction')\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || !capabilities.canSendTemplates\"\n :aria-label=\"config.labels.templates\"\n @click=\"openTemplates\"\n >\n <WhatsAppIcon name=\"template\" size=\"20\" />\n </ActionIcon>\n\n <ActionIcon\n v-if=\"showInteractive\"\n v-bind=\"getStyles('composerAction')\"\n variant=\"subtle\"\n color=\"gray\"\n :disabled=\"props.disabled || !capabilities.canSendInteractive\"\n :aria-label=\"config.labels.interactiveMessage\"\n @click=\"setInteractiveOpened(true)\"\n >\n <WhatsAppIcon name=\"interactive\" size=\"20\" />\n </ActionIcon>\n\n <ActionIcon\n v-bind=\"getStyles('composerSend')\"\n variant=\"filled\"\n radius=\"xl\"\n :disabled=\"!canSend\"\n :aria-label=\"props.sending ? config.labels.sending : config.labels.send\"\n @click=\"send\"\n >\n <Loader v-if=\"props.sending\" size=\"xs\" color=\"white\" />\n <WhatsAppIcon v-else name=\"send\" size=\"18\" />\n </ActionIcon>\n </Box>\n </template>\n </Box>\n\n <Box\n v-if=\"props.withCharacterCount && maxTextLength !== undefined\"\n v-bind=\"getStyles('composerFooter')\"\n >\n <Box\n component=\"span\"\n v-bind=\"getStyles('composerCount')\"\n :data-exceeded=\"exceeded ? '' : undefined\"\n aria-live=\"polite\"\n >\n {{ config.labels.characterCount(text.length, maxTextLength) }}\n </Box>\n </Box>\n\n <Modal\n v-bind=\"props.templateModalProps\"\n :opened=\"templatesOpened\"\n :title=\"config.labels.templateSelectorTitle\"\n size=\"lg\"\n @close=\"setTemplatesOpened(false)\"\n >\n <WhatsAppTemplateSelector\n :templates=\"props.templates\"\n :loading=\"props.templatesLoading\"\n :error=\"props.templatesError\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @submit=\"submitTemplate\"\n @retry-load=\"emit('templatesRetryLoad')\"\n >\n <template v-if=\"slots.templatePreview\" #templatePreview=\"previewProps\">\n <slot name=\"templatePreview\" v-bind=\"previewProps\" />\n </template>\n </WhatsAppTemplateSelector>\n </Modal>\n\n <Modal\n v-bind=\"props.interactiveModalProps\"\n :opened=\"interactiveOpened\"\n :title=\"config.labels.interactiveTitle\"\n size=\"lg\"\n @close=\"setInteractiveOpened(false)\"\n >\n <WhatsAppInteractiveMessageEditor\n v-model=\"interactiveDraft\"\n :interactive-types=\"capabilities.interactiveTypes\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @submit=\"submitInteractive\"\n @cancel=\"setInteractiveOpened(false)\"\n />\n </Modal>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppComposerComponent from './WhatsAppComposer.vue'\nimport type { WhatsAppComposerFactory } from './WhatsAppComposer.types'\nimport classes from './WhatsAppComposer.module.css'\n\nexport const WhatsAppComposer = factory<WhatsAppComposerFactory>(WhatsAppComposerComponent, {\n classes,\n})\n\nexport type {\n WhatsAppComposerEmits,\n WhatsAppComposerExposed,\n WhatsAppComposerFactory,\n WhatsAppComposerOwnProps,\n WhatsAppComposerProps,\n WhatsAppComposerSlots,\n WhatsAppComposerStylesNames,\n} from './WhatsAppComposer.types'\n",".conversationHeaderRoot {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-sm);\n padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);\n /*\n * Shared with the contact panel header so the two bottom borders line up across the\n * inbox, whatever each header happens to contain.\n */\n min-height: var(--wa-header-height, 64px);\n border-bottom: 1px solid var(--mantine-color-default-border);\n background-color: var(--mantine-color-body);\n flex-shrink: 0;\n}\n\n.conversationHeaderBack {\n flex-shrink: 0;\n}\n\n.conversationHeaderAvatar {\n flex-shrink: 0;\n}\n\n.conversationHeaderBody {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n text-align: start;\n}\n\n.conversationHeaderName {\n font-size: var(--mantine-font-size-sm);\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.conversationHeaderSubtitle {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.conversationHeaderActions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n withBack: false,\n withContactToggle: false,\n contactPanelOpened: false,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { ActionIcon, Avatar, Box, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { getContactDisplayName } from '../../utils'\nimport type {\n WhatsAppConversationHeaderEmits,\n WhatsAppConversationHeaderOwnProps,\n WhatsAppConversationHeaderSlots,\n} from './WhatsAppConversationHeader.types'\nimport classes from './WhatsAppConversationHeader.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversationHeader',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationHeaderOwnProps>(), {\n conversation: undefined,\n withBack: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n subtitle: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationHeaderEmits>()\ndefineSlots<WhatsAppConversationHeaderSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversationHeader', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversationHeader',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationHeaderRoot',\n})\n\nconst displayName = computed(() =>\n props.conversation ? getContactDisplayName(props.conversation) : '',\n)\n\nconst subtitle = computed(() => {\n if (props.subtitle !== undefined) {\n return props.subtitle\n }\n\n const phoneNumber = props.conversation?.contact.phoneNumber\n\n return phoneNumber && phoneNumber !== displayName.value ? phoneNumber : ''\n})\n\nfunction openContact() {\n if (props.conversation) {\n emit('contactClick', props.conversation)\n }\n}\n</script>\n\n<template>\n <Box component=\"header\" v-bind=\"{ ...attrs, ...getStyles('conversationHeaderRoot') }\">\n <slot v-if=\"slots.default\" :conversation=\"props.conversation\" />\n\n <template v-else>\n <ActionIcon\n v-if=\"props.withBack\"\n v-bind=\"getStyles('conversationHeaderBack')\"\n variant=\"subtle\"\n color=\"gray\"\n :aria-label=\"config.labels.backToConversations\"\n @click=\"emit('back')\"\n >\n <WhatsAppIcon name=\"arrowLeft\" size=\"20\" />\n </ActionIcon>\n\n <Avatar\n v-if=\"props.conversation\"\n v-bind=\"getStyles('conversationHeaderAvatar')\"\n :src=\"props.conversation.contact.avatarUrl\"\n :name=\"displayName\"\n color=\"initials\"\n radius=\"xl\"\n size=\"md\"\n aria-hidden=\"true\"\n />\n\n <UnstyledButton\n v-bind=\"getStyles('conversationHeaderBody')\"\n type=\"button\"\n :aria-label=\"displayName\"\n @click=\"openContact\"\n >\n <Box v-bind=\"getStyles('conversationHeaderName')\">{{ displayName }}</Box>\n <Box v-if=\"subtitle\" v-bind=\"getStyles('conversationHeaderSubtitle')\">{{ subtitle }}</Box>\n </UnstyledButton>\n\n <Box v-bind=\"getStyles('conversationHeaderActions')\">\n <slot name=\"headerActions\" :conversation=\"props.conversation\" />\n\n <ActionIcon\n v-if=\"props.withContactToggle\"\n variant=\"subtle\"\n color=\"gray\"\n :aria-label=\"config.labels.contactPanelToggle\"\n :aria-expanded=\"props.contactPanelOpened\"\n @click=\"emit('toggleContactPanel', !props.contactPanelOpened)\"\n >\n <WhatsAppIcon name=\"info\" size=\"20\" />\n </ActionIcon>\n </Box>\n </template>\n </Box>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n withBack: false,\n withContactToggle: false,\n contactPanelOpened: false,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { ActionIcon, Avatar, Box, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { getContactDisplayName } from '../../utils'\nimport type {\n WhatsAppConversationHeaderEmits,\n WhatsAppConversationHeaderOwnProps,\n WhatsAppConversationHeaderSlots,\n} from './WhatsAppConversationHeader.types'\nimport classes from './WhatsAppConversationHeader.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversationHeader',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationHeaderOwnProps>(), {\n conversation: undefined,\n withBack: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n subtitle: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationHeaderEmits>()\ndefineSlots<WhatsAppConversationHeaderSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversationHeader', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversationHeader',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationHeaderRoot',\n})\n\nconst displayName = computed(() =>\n props.conversation ? getContactDisplayName(props.conversation) : '',\n)\n\nconst subtitle = computed(() => {\n if (props.subtitle !== undefined) {\n return props.subtitle\n }\n\n const phoneNumber = props.conversation?.contact.phoneNumber\n\n return phoneNumber && phoneNumber !== displayName.value ? phoneNumber : ''\n})\n\nfunction openContact() {\n if (props.conversation) {\n emit('contactClick', props.conversation)\n }\n}\n</script>\n\n<template>\n <Box component=\"header\" v-bind=\"{ ...attrs, ...getStyles('conversationHeaderRoot') }\">\n <slot v-if=\"slots.default\" :conversation=\"props.conversation\" />\n\n <template v-else>\n <ActionIcon\n v-if=\"props.withBack\"\n v-bind=\"getStyles('conversationHeaderBack')\"\n variant=\"subtle\"\n color=\"gray\"\n :aria-label=\"config.labels.backToConversations\"\n @click=\"emit('back')\"\n >\n <WhatsAppIcon name=\"arrowLeft\" size=\"20\" />\n </ActionIcon>\n\n <Avatar\n v-if=\"props.conversation\"\n v-bind=\"getStyles('conversationHeaderAvatar')\"\n :src=\"props.conversation.contact.avatarUrl\"\n :name=\"displayName\"\n color=\"initials\"\n radius=\"xl\"\n size=\"md\"\n aria-hidden=\"true\"\n />\n\n <UnstyledButton\n v-bind=\"getStyles('conversationHeaderBody')\"\n type=\"button\"\n :aria-label=\"displayName\"\n @click=\"openContact\"\n >\n <Box v-bind=\"getStyles('conversationHeaderName')\">{{ displayName }}</Box>\n <Box v-if=\"subtitle\" v-bind=\"getStyles('conversationHeaderSubtitle')\">{{ subtitle }}</Box>\n </UnstyledButton>\n\n <Box v-bind=\"getStyles('conversationHeaderActions')\">\n <slot name=\"headerActions\" :conversation=\"props.conversation\" />\n\n <ActionIcon\n v-if=\"props.withContactToggle\"\n variant=\"subtle\"\n color=\"gray\"\n :aria-label=\"config.labels.contactPanelToggle\"\n :aria-expanded=\"props.contactPanelOpened\"\n @click=\"emit('toggleContactPanel', !props.contactPanelOpened)\"\n >\n <WhatsAppIcon name=\"info\" size=\"20\" />\n </ActionIcon>\n </Box>\n </template>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppConversationHeaderComponent from './WhatsAppConversationHeader.vue'\nimport type { WhatsAppConversationHeaderFactory } from './WhatsAppConversationHeader.types'\nimport classes from './WhatsAppConversationHeader.module.css'\n\nexport const WhatsAppConversationHeader = factory<WhatsAppConversationHeaderFactory>(\n WhatsAppConversationHeaderComponent,\n { classes },\n)\n\nexport type {\n WhatsAppConversationHeaderEmits,\n WhatsAppConversationHeaderFactory,\n WhatsAppConversationHeaderOwnProps,\n WhatsAppConversationHeaderProps,\n WhatsAppConversationHeaderSlots,\n WhatsAppConversationHeaderStylesNames,\n} from './WhatsAppConversationHeader.types'\n",".mediaRoot {\n display: block;\n max-width: 100%;\n}\n\n.mediaImageControl {\n display: block;\n padding: 0;\n border-radius: var(--mantine-radius-md);\n overflow: hidden;\n max-width: 100%;\n cursor: zoom-in;\n}\n\n.mediaImage {\n display: block;\n max-width: min(var(--wa-media-max-width, 320px), 100%);\n height: auto;\n border-radius: var(--mantine-radius-md);\n object-fit: cover;\n}\n\n.mediaRoot:where([data-media-type='sticker']) .mediaImage {\n max-width: 140px;\n border-radius: 0;\n}\n\n.mediaVideo {\n display: block;\n max-width: min(var(--wa-media-max-width, 320px), 100%);\n height: auto;\n border-radius: var(--mantine-radius-md);\n background-color: var(--mantine-color-black);\n}\n\n.mediaAudio {\n display: block;\n width: min(var(--wa-media-max-width, 320px), 100%);\n}\n\n.mediaDocument {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-xs);\n border-radius: var(--mantine-radius-md);\n background-color: var(--wa-document-bg, var(--mantine-color-default-hover));\n max-width: min(var(--wa-media-max-width, 320px), 100%);\n}\n\n.mediaDocumentIcon {\n flex-shrink: 0;\n display: flex;\n color: var(--mantine-color-dimmed);\n}\n\n.mediaDocumentBody {\n min-width: 0;\n flex: 1;\n}\n\n.mediaDocumentName {\n font-size: var(--mantine-font-size-sm);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.mediaDocumentMeta {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n}\n\n.mediaAction {\n flex-shrink: 0;\n}\n\n.mediaFallback {\n font-size: var(--mantine-font-size-sm);\n color: var(--mantine-color-dimmed);\n font-style: italic;\n}\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppMediaType } from '../../types'\n\nconst defaultProps = {\n withDownload: true,\n withPreview: true,\n} as const\n\nconst MEDIA_ICONS: Record<WhatsAppMediaType, WhatsAppIconName> = {\n image: 'photo',\n video: 'video',\n audio: 'microphone',\n document: 'file',\n sticker: 'photo',\n}\n\nconst varsResolver = createVarsResolver<any>((_, { maxWidth }) => ({\n mediaRoot: {\n '--wa-media-max-width':\n maxWidth === undefined\n ? undefined\n : typeof maxWidth === 'number'\n ? `${maxWidth}px`\n : maxWidth,\n },\n}))\n\nexport { defaultProps, MEDIA_ICONS, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { ActionIcon, Box, Text, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { formatDuration } from '../../utils'\nimport type {\n WhatsAppMediaAttachmentEmits,\n WhatsAppMediaAttachmentOwnProps,\n} from './WhatsAppMediaAttachment.types'\nimport classes from './WhatsAppMediaAttachment.module.css'\n\ndefineOptions({\n name: 'WhatsAppMediaAttachment',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMediaAttachmentOwnProps>(), {\n direction: undefined,\n withDownload: undefined,\n withPreview: undefined,\n maxWidth: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMediaAttachmentEmits>()\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMediaAttachment', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMediaAttachment',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'mediaRoot',\n})\n\nconst mediaType = computed(() => props.attachment.mediaType)\nconst url = computed(() => props.attachment.url)\n\n/** Label used in place of a missing file name, so every control still has an accessible name. */\nconst typeLabel = computed(() => {\n switch (mediaType.value) {\n case 'image':\n return config.labels.messageTypeImage\n case 'video':\n return config.labels.messageTypeVideo\n case 'audio':\n return config.labels.messageTypeAudio\n case 'sticker':\n return config.labels.messageTypeSticker\n default:\n return config.labels.messageTypeDocument\n }\n})\n\nconst fileName = computed(() => props.attachment.fileName || typeLabel.value)\n\nconst metaText = computed(() => {\n const parts = [\n config.fileSize(props.attachment.size),\n formatDuration(props.attachment.durationSeconds),\n ].filter(Boolean)\n\n return parts.join(' · ')\n})\n\n/**\n * Images and videos only get their rich renderer when there is something to render. A missing\n * `url` falls through to the document row, which still shows the file name and the download\n * action rather than an empty frame.\n */\nconst renderer = computed(() => {\n if (!props.withPreview || !url.value) {\n return 'document' as const\n }\n\n switch (mediaType.value) {\n case 'image':\n case 'sticker':\n return 'image' as const\n case 'video':\n return 'video' as const\n case 'audio':\n return 'audio' as const\n default:\n return 'document' as const\n }\n})\n\nconst downloadDescription = computed(() => `${config.labels.download}: ${fileName.value}`)\n\nfunction handleDownload() {\n emit('download', props.attachment)\n}\n\nfunction handlePreview() {\n emit('preview', props.attachment)\n}\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('mediaRoot') }\"\n :data-media-type=\"mediaType\"\n :data-direction=\"props.direction\"\n >\n <UnstyledButton\n v-if=\"renderer === 'image'\"\n v-bind=\"getStyles('mediaImageControl')\"\n type=\"button\"\n :aria-label=\"`${config.labels.openInNewTab}: ${fileName}`\"\n @click=\"handlePreview\"\n >\n <img\n v-bind=\"getStyles('mediaImage')\"\n :src=\"url\"\n :alt=\"fileName\"\n :width=\"props.attachment.width\"\n :height=\"props.attachment.height\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </UnstyledButton>\n\n <video\n v-else-if=\"renderer === 'video'\"\n v-bind=\"getStyles('mediaVideo')\"\n :src=\"url\"\n :poster=\"props.attachment.thumbnailUrl\"\n controls\n preload=\"metadata\"\n />\n\n <audio\n v-else-if=\"renderer === 'audio'\"\n v-bind=\"getStyles('mediaAudio')\"\n :src=\"url\"\n controls\n preload=\"metadata\"\n :aria-label=\"config.labels.playAudio\"\n />\n\n <Box v-else v-bind=\"getStyles('mediaDocument')\">\n <Box v-bind=\"getStyles('mediaDocumentIcon')\">\n <WhatsAppIcon :name=\"MEDIA_ICONS[mediaType]\" size=\"24\" />\n </Box>\n\n <Box v-bind=\"getStyles('mediaDocumentBody')\">\n <Box v-bind=\"getStyles('mediaDocumentName')\" :title=\"fileName\">{{ fileName }}</Box>\n <Box v-if=\"metaText\" v-bind=\"getStyles('mediaDocumentMeta')\">{{ metaText }}</Box>\n </Box>\n\n <ActionIcon\n v-if=\"props.withDownload && url\"\n v-bind=\"getStyles('mediaAction')\"\n component=\"a\"\n variant=\"subtle\"\n color=\"gray\"\n :href=\"url\"\n :download=\"props.attachment.fileName ?? ''\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :aria-label=\"downloadDescription\"\n @click=\"handleDownload\"\n >\n <WhatsAppIcon name=\"download\" size=\"18\" />\n </ActionIcon>\n\n <Text v-else-if=\"!url\" v-bind=\"getStyles('mediaFallback')\" component=\"span\">\n {{ config.labels.mediaUnavailable }}\n </Text>\n </Box>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppMediaType } from '../../types'\n\nconst defaultProps = {\n withDownload: true,\n withPreview: true,\n} as const\n\nconst MEDIA_ICONS: Record<WhatsAppMediaType, WhatsAppIconName> = {\n image: 'photo',\n video: 'video',\n audio: 'microphone',\n document: 'file',\n sticker: 'photo',\n}\n\nconst varsResolver = createVarsResolver<any>((_, { maxWidth }) => ({\n mediaRoot: {\n '--wa-media-max-width':\n maxWidth === undefined\n ? undefined\n : typeof maxWidth === 'number'\n ? `${maxWidth}px`\n : maxWidth,\n },\n}))\n\nexport { defaultProps, MEDIA_ICONS, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { ActionIcon, Box, Text, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { formatDuration } from '../../utils'\nimport type {\n WhatsAppMediaAttachmentEmits,\n WhatsAppMediaAttachmentOwnProps,\n} from './WhatsAppMediaAttachment.types'\nimport classes from './WhatsAppMediaAttachment.module.css'\n\ndefineOptions({\n name: 'WhatsAppMediaAttachment',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMediaAttachmentOwnProps>(), {\n direction: undefined,\n withDownload: undefined,\n withPreview: undefined,\n maxWidth: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMediaAttachmentEmits>()\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMediaAttachment', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMediaAttachment',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'mediaRoot',\n})\n\nconst mediaType = computed(() => props.attachment.mediaType)\nconst url = computed(() => props.attachment.url)\n\n/** Label used in place of a missing file name, so every control still has an accessible name. */\nconst typeLabel = computed(() => {\n switch (mediaType.value) {\n case 'image':\n return config.labels.messageTypeImage\n case 'video':\n return config.labels.messageTypeVideo\n case 'audio':\n return config.labels.messageTypeAudio\n case 'sticker':\n return config.labels.messageTypeSticker\n default:\n return config.labels.messageTypeDocument\n }\n})\n\nconst fileName = computed(() => props.attachment.fileName || typeLabel.value)\n\nconst metaText = computed(() => {\n const parts = [\n config.fileSize(props.attachment.size),\n formatDuration(props.attachment.durationSeconds),\n ].filter(Boolean)\n\n return parts.join(' · ')\n})\n\n/**\n * Images and videos only get their rich renderer when there is something to render. A missing\n * `url` falls through to the document row, which still shows the file name and the download\n * action rather than an empty frame.\n */\nconst renderer = computed(() => {\n if (!props.withPreview || !url.value) {\n return 'document' as const\n }\n\n switch (mediaType.value) {\n case 'image':\n case 'sticker':\n return 'image' as const\n case 'video':\n return 'video' as const\n case 'audio':\n return 'audio' as const\n default:\n return 'document' as const\n }\n})\n\nconst downloadDescription = computed(() => `${config.labels.download}: ${fileName.value}`)\n\nfunction handleDownload() {\n emit('download', props.attachment)\n}\n\nfunction handlePreview() {\n emit('preview', props.attachment)\n}\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('mediaRoot') }\"\n :data-media-type=\"mediaType\"\n :data-direction=\"props.direction\"\n >\n <UnstyledButton\n v-if=\"renderer === 'image'\"\n v-bind=\"getStyles('mediaImageControl')\"\n type=\"button\"\n :aria-label=\"`${config.labels.openInNewTab}: ${fileName}`\"\n @click=\"handlePreview\"\n >\n <img\n v-bind=\"getStyles('mediaImage')\"\n :src=\"url\"\n :alt=\"fileName\"\n :width=\"props.attachment.width\"\n :height=\"props.attachment.height\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </UnstyledButton>\n\n <video\n v-else-if=\"renderer === 'video'\"\n v-bind=\"getStyles('mediaVideo')\"\n :src=\"url\"\n :poster=\"props.attachment.thumbnailUrl\"\n controls\n preload=\"metadata\"\n />\n\n <audio\n v-else-if=\"renderer === 'audio'\"\n v-bind=\"getStyles('mediaAudio')\"\n :src=\"url\"\n controls\n preload=\"metadata\"\n :aria-label=\"config.labels.playAudio\"\n />\n\n <Box v-else v-bind=\"getStyles('mediaDocument')\">\n <Box v-bind=\"getStyles('mediaDocumentIcon')\">\n <WhatsAppIcon :name=\"MEDIA_ICONS[mediaType]\" size=\"24\" />\n </Box>\n\n <Box v-bind=\"getStyles('mediaDocumentBody')\">\n <Box v-bind=\"getStyles('mediaDocumentName')\" :title=\"fileName\">{{ fileName }}</Box>\n <Box v-if=\"metaText\" v-bind=\"getStyles('mediaDocumentMeta')\">{{ metaText }}</Box>\n </Box>\n\n <ActionIcon\n v-if=\"props.withDownload && url\"\n v-bind=\"getStyles('mediaAction')\"\n component=\"a\"\n variant=\"subtle\"\n color=\"gray\"\n :href=\"url\"\n :download=\"props.attachment.fileName ?? ''\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :aria-label=\"downloadDescription\"\n @click=\"handleDownload\"\n >\n <WhatsAppIcon name=\"download\" size=\"18\" />\n </ActionIcon>\n\n <Text v-else-if=\"!url\" v-bind=\"getStyles('mediaFallback')\" component=\"span\">\n {{ config.labels.mediaUnavailable }}\n </Text>\n </Box>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppMediaAttachmentComponent from './WhatsAppMediaAttachment.vue'\nimport type { WhatsAppMediaAttachmentFactory } from './WhatsAppMediaAttachment.types'\nimport classes from './WhatsAppMediaAttachment.module.css'\n\nexport const WhatsAppMediaAttachment = factory<WhatsAppMediaAttachmentFactory>(\n WhatsAppMediaAttachmentComponent,\n { classes },\n)\n\nexport type {\n WhatsAppMediaAttachmentEmits,\n WhatsAppMediaAttachmentFactory,\n WhatsAppMediaAttachmentOwnProps,\n WhatsAppMediaAttachmentProps,\n WhatsAppMediaAttachmentStylesNames,\n} from './WhatsAppMediaAttachment.types'\n",".statusRoot {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n line-height: 1;\n color: var(--wa-status-color, var(--mantine-color-dimmed));\n}\n\n.statusRoot:where([data-status='read']) {\n --wa-status-color: var(--mantine-color-blue-5);\n}\n\n.statusRoot:where([data-status='failed']) {\n --wa-status-color: var(--mantine-color-error);\n}\n\n.statusIcon {\n display: block;\n}\n\n.statusLabel {\n font-size: var(--mantine-font-size-xs);\n}\n","<script lang=\"ts\">\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppInboxLabels } from '../../labels'\nimport type { WhatsAppDeliveryStatus as WhatsAppMessageStatusValue } from '../../types'\n\nconst defaultProps = {\n withLabel: false,\n size: '1em',\n} as const\n\n/**\n * Each state gets its own glyph, not only its own colour: WhatsApp's own single/double tick\n * distinction is the accessible part of the indicator, and the blue of `read` is decoration on\n * top of it.\n */\nconst STATUS_ICONS: Record<WhatsAppMessageStatusValue, WhatsAppIconName> = {\n pending: 'clock',\n sent: 'check',\n delivered: 'checks',\n read: 'checks',\n failed: 'alert',\n}\n\nconst STATUS_LABEL_KEYS = {\n pending: 'statusPending',\n sent: 'statusSent',\n delivered: 'statusDelivered',\n read: 'statusRead',\n failed: 'statusFailed',\n} as const satisfies Record<WhatsAppMessageStatusValue, keyof WhatsAppInboxLabels>\n\nexport { defaultProps, STATUS_ICONS, STATUS_LABEL_KEYS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { Box, useProps, useStyles, VisuallyHidden } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppMessageStatusOwnProps } from './WhatsAppMessageStatus.types'\nimport classes from './WhatsAppMessageStatus.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessageStatus',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageStatusOwnProps>(), {\n status: undefined,\n withLabel: undefined,\n size: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessageStatus', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessageStatus',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'statusRoot',\n})\n\nconst icon = computed(() => (props.status ? STATUS_ICONS[props.status] : undefined))\n\nconst label = computed(() => (props.status ? config.labels[STATUS_LABEL_KEYS[props.status]] : ''))\n\n/** Screen readers read the state as a sentence rather than the bare word. */\nconst accessibleLabel = computed(() =>\n props.status ? config.labels.messageStatusLabel(label.value) : '',\n)\n</script>\n\n<template>\n <Box\n v-if=\"props.status && icon\"\n component=\"span\"\n v-bind=\"{ ...attrs, ...getStyles('statusRoot') }\"\n :data-status=\"props.status\"\n >\n <WhatsAppIcon\n :name=\"icon\"\n :size=\"props.size\"\n :stroke-width=\"props.status === 'pending' || props.status === 'failed' ? 2 : 3\"\n v-bind=\"getStyles('statusIcon')\"\n />\n\n <Box v-if=\"props.withLabel\" component=\"span\" v-bind=\"getStyles('statusLabel')\">\n {{ label }}\n </Box>\n\n <VisuallyHidden v-else>{{ accessibleLabel }}</VisuallyHidden>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport type { WhatsAppIconName } from '../../icons'\nimport type { WhatsAppInboxLabels } from '../../labels'\nimport type { WhatsAppDeliveryStatus as WhatsAppMessageStatusValue } from '../../types'\n\nconst defaultProps = {\n withLabel: false,\n size: '1em',\n} as const\n\n/**\n * Each state gets its own glyph, not only its own colour: WhatsApp's own single/double tick\n * distinction is the accessible part of the indicator, and the blue of `read` is decoration on\n * top of it.\n */\nconst STATUS_ICONS: Record<WhatsAppMessageStatusValue, WhatsAppIconName> = {\n pending: 'clock',\n sent: 'check',\n delivered: 'checks',\n read: 'checks',\n failed: 'alert',\n}\n\nconst STATUS_LABEL_KEYS = {\n pending: 'statusPending',\n sent: 'statusSent',\n delivered: 'statusDelivered',\n read: 'statusRead',\n failed: 'statusFailed',\n} as const satisfies Record<WhatsAppMessageStatusValue, keyof WhatsAppInboxLabels>\n\nexport { defaultProps, STATUS_ICONS, STATUS_LABEL_KEYS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport { Box, useProps, useStyles, VisuallyHidden } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppMessageStatusOwnProps } from './WhatsAppMessageStatus.types'\nimport classes from './WhatsAppMessageStatus.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessageStatus',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageStatusOwnProps>(), {\n status: undefined,\n withLabel: undefined,\n size: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessageStatus', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessageStatus',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'statusRoot',\n})\n\nconst icon = computed(() => (props.status ? STATUS_ICONS[props.status] : undefined))\n\nconst label = computed(() => (props.status ? config.labels[STATUS_LABEL_KEYS[props.status]] : ''))\n\n/** Screen readers read the state as a sentence rather than the bare word. */\nconst accessibleLabel = computed(() =>\n props.status ? config.labels.messageStatusLabel(label.value) : '',\n)\n</script>\n\n<template>\n <Box\n v-if=\"props.status && icon\"\n component=\"span\"\n v-bind=\"{ ...attrs, ...getStyles('statusRoot') }\"\n :data-status=\"props.status\"\n >\n <WhatsAppIcon\n :name=\"icon\"\n :size=\"props.size\"\n :stroke-width=\"props.status === 'pending' || props.status === 'failed' ? 2 : 3\"\n v-bind=\"getStyles('statusIcon')\"\n />\n\n <Box v-if=\"props.withLabel\" component=\"span\" v-bind=\"getStyles('statusLabel')\">\n {{ label }}\n </Box>\n\n <VisuallyHidden v-else>{{ accessibleLabel }}</VisuallyHidden>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppMessageStatusComponent from './WhatsAppMessageStatus.vue'\nimport type { WhatsAppMessageStatusFactory } from './WhatsAppMessageStatus.types'\nimport classes from './WhatsAppMessageStatus.module.css'\n\nexport const WhatsAppMessageStatus = factory<WhatsAppMessageStatusFactory>(\n WhatsAppMessageStatusComponent,\n { classes },\n)\n\nexport type {\n WhatsAppMessageStatusFactory,\n WhatsAppMessageStatusOwnProps,\n WhatsAppMessageStatusProps,\n WhatsAppMessageStatusStylesNames,\n} from './WhatsAppMessageStatus.types'\n",".bubbleRoot {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n /* Spans the row so `align-items` can place the bubble on the correct side. */\n width: 100%;\n max-width: 100%;\n}\n\n.bubbleRoot:where([data-direction='outbound']) {\n align-items: flex-end;\n}\n\n.bubbleRoot:where([data-variant='system']) {\n align-items: center;\n}\n\n.bubble {\n position: relative;\n max-width: var(--wa-bubble-max-width, 75%);\n min-width: 0;\n padding: 6px 9px 6px 9px;\n border-radius: var(--wa-bubble-radius, var(--mantine-radius-lg));\n background-color: var(--wa-bubble-bg);\n color: var(--wa-bubble-color, var(--mantine-color-text));\n box-shadow: var(--wa-bubble-shadow, 0 1px 0.5px rgba(0, 0, 0, 0.13));\n overflow-wrap: anywhere;\n}\n\n.bubbleRoot:where([data-direction='inbound']) .bubble {\n --wa-bubble-bg: var(--wa-inbound-bg, var(--mantine-color-body));\n border-start-start-radius: var(--wa-bubble-corner);\n}\n\n.bubbleRoot:where([data-direction='outbound']) .bubble {\n --wa-bubble-bg: var(--wa-outbound-bg, var(--mantine-color-teal-light));\n border-start-end-radius: var(--wa-bubble-corner);\n}\n\n.bubbleRoot:where([data-with-tail]) {\n --wa-bubble-corner: var(--mantine-radius-xs);\n}\n\n.bubbleAuthor {\n font-size: var(--mantine-font-size-xs);\n font-weight: 600;\n color: var(--mantine-color-anchor);\n margin-bottom: 2px;\n}\n\n.bubbleQuote {\n display: block;\n width: 100%;\n text-align: start;\n border-inline-start: 3px solid var(--mantine-color-anchor);\n border-radius: var(--mantine-radius-sm);\n background-color: var(--mantine-color-default-hover);\n padding: 4px 8px;\n margin-bottom: 4px;\n}\n\n.bubbleQuoteAuthor {\n font-size: var(--mantine-font-size-xs);\n font-weight: 600;\n color: var(--mantine-color-anchor);\n}\n\n.bubbleQuoteText {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bubbleForwarded {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n font-style: italic;\n margin-bottom: 2px;\n}\n\n.bubbleContent {\n font-size: var(--mantine-font-size-sm);\n line-height: 1.4;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.bubbleFooter {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 4px;\n margin-top: 2px;\n line-height: 1;\n}\n\n.bubbleTime {\n font-size: 11px;\n color: var(--mantine-color-dimmed);\n white-space: nowrap;\n}\n\n.bubbleStatus {\n font-size: 14px;\n}\n\n.bubbleError {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 2px;\n max-width: var(--wa-bubble-max-width, 75%);\n}\n\n.bubbleErrorText {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-error);\n}\n\n.bubbleRetry {\n font-size: var(--mantine-font-size-xs);\n}\n\n.bubbleReactions {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: -6px;\n z-index: 1;\n}\n\n.bubbleReaction {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n font-size: var(--mantine-font-size-xs);\n padding: 1px 6px;\n border-radius: var(--mantine-radius-xl);\n background-color: var(--mantine-color-body);\n border: 1px solid var(--mantine-color-default-border);\n}\n\n.systemMessage {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n background-color: var(--mantine-color-default-hover);\n border-radius: var(--mantine-radius-sm);\n padding: 4px 10px;\n text-align: center;\n max-width: 90%;\n}\n","<script lang=\"ts\">\nimport { createVarsResolver, getRadius } from '@mantine-vue/core'\n\nconst defaultProps = {\n variant: 'bubble',\n withTail: true,\n withRetry: true,\n radius: 'lg',\n maxWidth: '75%',\n} as const\n\nconst varsResolver = createVarsResolver<any>((_, { radius, maxWidth }) => ({\n bubbleRoot: {\n '--wa-bubble-radius': radius === undefined ? undefined : getRadius(radius),\n '--wa-bubble-max-width':\n maxWidth === undefined\n ? undefined\n : typeof maxWidth === 'number'\n ? `${maxWidth}px`\n : maxWidth,\n },\n}))\n\nexport { defaultProps, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Box, Button, useProps, useStyles, VisuallyHidden } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { WhatsAppMessageStatus } from '../WhatsAppMessageStatus'\nimport type {\n WhatsAppMessageBubbleEmits,\n WhatsAppMessageBubbleOwnProps,\n WhatsAppMessageBubbleSlots,\n} from './WhatsAppMessageBubble.types'\nimport classes from './WhatsAppMessageBubble.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessageBubble',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageBubbleOwnProps>(), {\n variant: undefined,\n status: undefined,\n timestamp: undefined,\n author: undefined,\n replyTo: undefined,\n forwarded: undefined,\n error: undefined,\n withRetry: undefined,\n reactions: undefined,\n withTail: undefined,\n radius: undefined,\n maxWidth: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessageBubbleEmits>()\ndefineSlots<WhatsAppMessageBubbleSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessageBubble', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessageBubble',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'bubbleRoot',\n})\n\nconst isSystem = computed(() => props.variant === 'system')\n\nconst time = computed(() =>\n props.timestamp === undefined ? '' : config.messageTime(props.timestamp),\n)\n\nconst fullTime = computed(() =>\n props.timestamp === undefined ? '' : config.fullTimestamp(props.timestamp),\n)\n\n/**\n * A sent/received announcement in front of every bubble. Colour and side carry that information\n * for sighted users; without this a screen reader would read both sides as one flat stream.\n */\nconst directionLabel = computed(() =>\n props.direction === 'inbound'\n ? config.labels.inboundMessageLabel\n : config.labels.outboundMessageLabel,\n)\n\nconst failed = computed(() => props.status === 'failed' || props.error !== undefined)\n\nconst canRetry = computed(() => failed.value && props.withRetry && (props.error?.retryable ?? true))\n\nconst errorText = computed(() => {\n if (!failed.value) {\n return ''\n }\n\n const message = props.error?.message || config.labels.sendFailed\n\n return props.error?.code ? `${message} (${props.error.code})` : message\n})\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('bubbleRoot') }\"\n :data-direction=\"props.direction\"\n :data-variant=\"props.variant\"\n :data-status=\"props.status\"\n :data-with-tail=\"props.withTail && !isSystem ? '' : undefined\"\n >\n <Box v-if=\"isSystem\" v-bind=\"getStyles('systemMessage')\">\n <slot />\n </Box>\n\n <template v-else>\n <Box v-bind=\"getStyles('bubble')\">\n <VisuallyHidden>{{ directionLabel }}</VisuallyHidden>\n\n <Box v-if=\"props.author\" v-bind=\"getStyles('bubbleAuthor')\">{{ props.author.name }}</Box>\n\n <Box v-if=\"props.forwarded\" v-bind=\"getStyles('bubbleForwarded')\">\n <WhatsAppIcon name=\"reply\" size=\"12\" />\n {{ config.labels.forwarded }}\n </Box>\n\n <template v-if=\"props.replyTo\">\n <slot v-if=\"slots.quote\" name=\"quote\" :reply-to=\"props.replyTo\" />\n <Box v-else v-bind=\"getStyles('bubbleQuote')\">\n <Box v-if=\"props.replyTo.author\" v-bind=\"getStyles('bubbleQuoteAuthor')\">\n {{ props.replyTo.author }}\n </Box>\n <Box v-bind=\"getStyles('bubbleQuoteText')\">{{ props.replyTo.text }}</Box>\n </Box>\n </template>\n\n <Box v-bind=\"getStyles('bubbleContent')\">\n <slot />\n </Box>\n\n <slot name=\"footer\" />\n\n <Box v-if=\"time || props.status\" v-bind=\"getStyles('bubbleFooter')\">\n <Box\n v-if=\"time\"\n component=\"time\"\n v-bind=\"getStyles('bubbleTime')\"\n :title=\"fullTime\"\n :aria-label=\"fullTime\"\n >\n {{ time }}\n </Box>\n\n <WhatsAppMessageStatus\n v-if=\"props.status\"\n v-bind=\"getStyles('bubbleStatus')\"\n :status=\"props.status\"\n :labels=\"props.labels\"\n />\n </Box>\n </Box>\n\n <Box v-if=\"props.reactions?.length\" v-bind=\"getStyles('bubbleReactions')\">\n <Box\n v-for=\"reaction in props.reactions\"\n :key=\"reaction.emoji\"\n component=\"span\"\n v-bind=\"getStyles('bubbleReaction')\"\n :data-reacted=\"reaction.reacted ? '' : undefined\"\n >\n <span>{{ reaction.emoji }}</span>\n <span v-if=\"reaction.count && reaction.count > 1\">{{ reaction.count }}</span>\n </Box>\n </Box>\n\n <Box v-if=\"failed\" v-bind=\"getStyles('bubbleError')\" role=\"alert\">\n <WhatsAppIcon name=\"alert\" size=\"14\" :style=\"{ color: 'var(--mantine-color-error)' }\" />\n <Box component=\"span\" v-bind=\"getStyles('bubbleErrorText')\">{{ errorText }}</Box>\n\n <Button\n v-if=\"canRetry\"\n v-bind=\"getStyles('bubbleRetry')\"\n variant=\"subtle\"\n size=\"compact-xs\"\n color=\"red\"\n @click=\"emit('retry')\"\n >\n {{ config.labels.retrySend }}\n </Button>\n </Box>\n </template>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport { createVarsResolver, getRadius } from '@mantine-vue/core'\n\nconst defaultProps = {\n variant: 'bubble',\n withTail: true,\n withRetry: true,\n radius: 'lg',\n maxWidth: '75%',\n} as const\n\nconst varsResolver = createVarsResolver<any>((_, { radius, maxWidth }) => ({\n bubbleRoot: {\n '--wa-bubble-radius': radius === undefined ? undefined : getRadius(radius),\n '--wa-bubble-max-width':\n maxWidth === undefined\n ? undefined\n : typeof maxWidth === 'number'\n ? `${maxWidth}px`\n : maxWidth,\n },\n}))\n\nexport { defaultProps, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Box, Button, useProps, useStyles, VisuallyHidden } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { WhatsAppMessageStatus } from '../WhatsAppMessageStatus'\nimport type {\n WhatsAppMessageBubbleEmits,\n WhatsAppMessageBubbleOwnProps,\n WhatsAppMessageBubbleSlots,\n} from './WhatsAppMessageBubble.types'\nimport classes from './WhatsAppMessageBubble.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessageBubble',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageBubbleOwnProps>(), {\n variant: undefined,\n status: undefined,\n timestamp: undefined,\n author: undefined,\n replyTo: undefined,\n forwarded: undefined,\n error: undefined,\n withRetry: undefined,\n reactions: undefined,\n withTail: undefined,\n radius: undefined,\n maxWidth: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessageBubbleEmits>()\ndefineSlots<WhatsAppMessageBubbleSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessageBubble', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessageBubble',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'bubbleRoot',\n})\n\nconst isSystem = computed(() => props.variant === 'system')\n\nconst time = computed(() =>\n props.timestamp === undefined ? '' : config.messageTime(props.timestamp),\n)\n\nconst fullTime = computed(() =>\n props.timestamp === undefined ? '' : config.fullTimestamp(props.timestamp),\n)\n\n/**\n * A sent/received announcement in front of every bubble. Colour and side carry that information\n * for sighted users; without this a screen reader would read both sides as one flat stream.\n */\nconst directionLabel = computed(() =>\n props.direction === 'inbound'\n ? config.labels.inboundMessageLabel\n : config.labels.outboundMessageLabel,\n)\n\nconst failed = computed(() => props.status === 'failed' || props.error !== undefined)\n\nconst canRetry = computed(() => failed.value && props.withRetry && (props.error?.retryable ?? true))\n\nconst errorText = computed(() => {\n if (!failed.value) {\n return ''\n }\n\n const message = props.error?.message || config.labels.sendFailed\n\n return props.error?.code ? `${message} (${props.error.code})` : message\n})\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('bubbleRoot') }\"\n :data-direction=\"props.direction\"\n :data-variant=\"props.variant\"\n :data-status=\"props.status\"\n :data-with-tail=\"props.withTail && !isSystem ? '' : undefined\"\n >\n <Box v-if=\"isSystem\" v-bind=\"getStyles('systemMessage')\">\n <slot />\n </Box>\n\n <template v-else>\n <Box v-bind=\"getStyles('bubble')\">\n <VisuallyHidden>{{ directionLabel }}</VisuallyHidden>\n\n <Box v-if=\"props.author\" v-bind=\"getStyles('bubbleAuthor')\">{{ props.author.name }}</Box>\n\n <Box v-if=\"props.forwarded\" v-bind=\"getStyles('bubbleForwarded')\">\n <WhatsAppIcon name=\"reply\" size=\"12\" />\n {{ config.labels.forwarded }}\n </Box>\n\n <template v-if=\"props.replyTo\">\n <slot v-if=\"slots.quote\" name=\"quote\" :reply-to=\"props.replyTo\" />\n <Box v-else v-bind=\"getStyles('bubbleQuote')\">\n <Box v-if=\"props.replyTo.author\" v-bind=\"getStyles('bubbleQuoteAuthor')\">\n {{ props.replyTo.author }}\n </Box>\n <Box v-bind=\"getStyles('bubbleQuoteText')\">{{ props.replyTo.text }}</Box>\n </Box>\n </template>\n\n <Box v-bind=\"getStyles('bubbleContent')\">\n <slot />\n </Box>\n\n <slot name=\"footer\" />\n\n <Box v-if=\"time || props.status\" v-bind=\"getStyles('bubbleFooter')\">\n <Box\n v-if=\"time\"\n component=\"time\"\n v-bind=\"getStyles('bubbleTime')\"\n :title=\"fullTime\"\n :aria-label=\"fullTime\"\n >\n {{ time }}\n </Box>\n\n <WhatsAppMessageStatus\n v-if=\"props.status\"\n v-bind=\"getStyles('bubbleStatus')\"\n :status=\"props.status\"\n :labels=\"props.labels\"\n />\n </Box>\n </Box>\n\n <Box v-if=\"props.reactions?.length\" v-bind=\"getStyles('bubbleReactions')\">\n <Box\n v-for=\"reaction in props.reactions\"\n :key=\"reaction.emoji\"\n component=\"span\"\n v-bind=\"getStyles('bubbleReaction')\"\n :data-reacted=\"reaction.reacted ? '' : undefined\"\n >\n <span>{{ reaction.emoji }}</span>\n <span v-if=\"reaction.count && reaction.count > 1\">{{ reaction.count }}</span>\n </Box>\n </Box>\n\n <Box v-if=\"failed\" v-bind=\"getStyles('bubbleError')\" role=\"alert\">\n <WhatsAppIcon name=\"alert\" size=\"14\" :style=\"{ color: 'var(--mantine-color-error)' }\" />\n <Box component=\"span\" v-bind=\"getStyles('bubbleErrorText')\">{{ errorText }}</Box>\n\n <Button\n v-if=\"canRetry\"\n v-bind=\"getStyles('bubbleRetry')\"\n variant=\"subtle\"\n size=\"compact-xs\"\n color=\"red\"\n @click=\"emit('retry')\"\n >\n {{ config.labels.retrySend }}\n </Button>\n </Box>\n </template>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppMessageBubbleComponent from './WhatsAppMessageBubble.vue'\nimport type { WhatsAppMessageBubbleFactory } from './WhatsAppMessageBubble.types'\nimport classes from './WhatsAppMessageBubble.module.css'\n\nexport const WhatsAppMessageBubble = factory<WhatsAppMessageBubbleFactory>(\n WhatsAppMessageBubbleComponent,\n { classes },\n)\n\nexport type {\n WhatsAppMessageBubbleEmits,\n WhatsAppMessageBubbleFactory,\n WhatsAppMessageBubbleOwnProps,\n WhatsAppMessageBubbleProps,\n WhatsAppMessageBubbleSlots,\n WhatsAppMessageBubbleStylesNames,\n WhatsAppMessageBubbleVariant,\n} from './WhatsAppMessageBubble.types'\n",".messageRoot {\n /*\n * This class lands on the same element as `bubbleRoot`, so it must not declare layout:\n * a `display` here would override the bubble's own flex alignment and push every\n * message to the same side.\n */\n width: 100%;\n}\n\n.messageCaption {\n margin-top: 4px;\n font-size: var(--mantine-font-size-sm);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.messageInteractive {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n.messageInteractiveBody {\n font-size: var(--mantine-font-size-sm);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.messageInteractiveFooter {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n}\n\n.messageInteractiveButtons {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: 4px;\n border-top: 1px solid var(--mantine-color-default-border);\n padding-top: 4px;\n}\n\n.messageInteractiveButton {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: var(--mantine-font-size-sm);\n color: var(--mantine-color-anchor);\n padding: 4px;\n text-align: center;\n}\n\n.messageInteractiveReply {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n}\n\n.messageLocation {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n font-size: var(--mantine-font-size-sm);\n}\n\n.messageLocationName {\n font-weight: 600;\n}\n\n.messageLocationAddress {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n}\n\n.messageContactCard {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n font-size: var(--mantine-font-size-sm);\n padding-block: 2px;\n}\n\n.messageContactName {\n font-weight: 600;\n}\n\n.messageContactDetail {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n}\n\n.messageUnsupported {\n font-size: var(--mantine-font-size-sm);\n font-style: italic;\n color: var(--mantine-color-dimmed);\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n withRetry: true,\n withTail: true,\n} as const\n\nconst MEDIA_TYPES = ['image', 'video', 'audio', 'document', 'sticker'] as const\n\nexport { defaultProps, MEDIA_TYPES }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots, type VNodeChild } from 'vue'\nimport { Anchor, Box, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppMessageSlots } from '../../component-props'\nimport type { WhatsAppAttachment, WhatsAppMediaMessage } from '../../types'\nimport { WhatsAppMediaAttachment } from '../WhatsAppMediaAttachment'\nimport { WhatsAppMessageBubble } from '../WhatsAppMessageBubble'\nimport { WhatsAppTemplatePreview } from '../WhatsAppTemplatePreview'\nimport type { WhatsAppMessageEmits, WhatsAppMessageOwnProps } from './WhatsAppMessage.types'\nimport classes from './WhatsAppMessage.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessage',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageOwnProps>(), {\n withRetry: undefined,\n withTail: undefined,\n maxWidth: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessageEmits>()\ndefineSlots<WhatsAppMessageSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessage', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessage',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'messageRoot',\n})\n\nconst message = computed(() => props.message)\n\n/**\n * The union is narrowed here rather than in the template: a `v-if` chain whose branches test\n * different expressions gives `vue-tsc` nothing to narrow on, so each variant is resolved once\n * into a typed computed and the template only reads the one that matches.\n */\nconst mediaMessage = computed(() =>\n (MEDIA_TYPES as readonly string[]).includes(message.value.type)\n ? (message.value as WhatsAppMediaMessage)\n : undefined,\n)\n\nconst textContent = computed(() =>\n message.value.type === 'text' || message.value.type === 'system' ? message.value.text : undefined,\n)\n\nconst templateInstance = computed(() =>\n message.value.type === 'template' ? message.value.template : undefined,\n)\n\nconst interactiveMessage = computed(() =>\n message.value.type === 'interactive' ? message.value : undefined,\n)\n\nconst locationMessage = computed(() =>\n message.value.type === 'location' ? message.value : undefined,\n)\n\nconst contactCards = computed(() =>\n message.value.type === 'contacts' ? message.value.contacts : undefined,\n)\n\nconst unsupportedText = computed(() =>\n message.value.type === 'unsupported'\n ? message.value.text || config.labels.messageTypeUnsupported\n : config.labels.messageTypeUnsupported,\n)\n\n/**\n * Returning `undefined` from `renderMessage` uses the built-in renderer.\n */\nconst customMessage = computed<VNodeChild>(() => props.renderMessage?.(message.value) ?? null)\nconst renderCustomMessage = () => customMessage.value\n\nconst customContent = computed<VNodeChild>(\n () => props.renderMessageContent?.(message.value) ?? null,\n)\nconst renderCustomContent = () => customContent.value\n\nconst hasCustomFooter = computed(() => Boolean(slots.messageFooter))\n\nfunction handleMediaDownload(attachment: WhatsAppAttachment) {\n emit('mediaDownload', attachment, message.value)\n}\n\nfunction handleMediaPreview(attachment: WhatsAppAttachment) {\n emit('mediaPreview', attachment, message.value)\n}\n\nconst locationHref = computed(() => {\n const location = locationMessage.value?.location\n\n if (!location) {\n return undefined\n }\n\n return (\n location.url ??\n `https://www.openstreetmap.org/?mlat=${location.latitude}&mlon=${location.longitude}`\n )\n})\n</script>\n\n<template>\n <component :is=\"renderCustomMessage\" v-if=\"customMessage\" />\n\n <WhatsAppMessageBubble\n v-else\n v-bind=\"{ ...attrs, ...getStyles('messageRoot') }\"\n :direction=\"message.direction\"\n :variant=\"message.type === 'system' ? 'system' : 'bubble'\"\n :status=\"message.type === 'system' ? undefined : message.status\"\n :timestamp=\"message.timestamp\"\n :author=\"message.author\"\n :reply-to=\"message.replyTo\"\n :forwarded=\"message.forwarded\"\n :error=\"message.error\"\n :with-retry=\"props.withRetry\"\n :reactions=\"message.reactions\"\n :with-tail=\"props.withTail\"\n :max-width=\"props.maxWidth\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n :data-message-id=\"message.id\"\n :data-message-type=\"message.type\"\n @retry=\"emit('retry', message)\"\n >\n <slot v-if=\"slots.messageContent\" name=\"messageContent\" :message=\"message\" />\n\n <component :is=\"renderCustomContent\" v-else-if=\"customContent\" />\n\n <template v-else-if=\"textContent !== undefined\">{{ textContent }}</template>\n\n <template v-else-if=\"mediaMessage\">\n <slot\n v-if=\"slots.mediaAttachment\"\n name=\"mediaAttachment\"\n :attachment=\"mediaMessage.attachment\"\n :message=\"message\"\n />\n <WhatsAppMediaAttachment\n v-else\n :attachment=\"mediaMessage.attachment\"\n :direction=\"message.direction\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @download=\"handleMediaDownload\"\n @preview=\"handleMediaPreview\"\n />\n\n <Box v-if=\"mediaMessage.caption\" v-bind=\"getStyles('messageCaption')\">\n {{ mediaMessage.caption }}\n </Box>\n </template>\n\n <WhatsAppTemplatePreview\n v-else-if=\"templateInstance\"\n :template=\"templateInstance.template\"\n :values=\"templateInstance.values\"\n :fallback-text=\"templateInstance.text ?? templateInstance.name\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n />\n\n <Box v-else-if=\"interactiveMessage\" v-bind=\"getStyles('messageInteractive')\">\n <Box v-if=\"interactiveMessage.reply\" v-bind=\"getStyles('messageInteractiveReply')\">\n {{ interactiveMessage.reply.title ?? interactiveMessage.reply.id }}\n </Box>\n\n <Box v-bind=\"getStyles('messageInteractiveBody')\">\n {{ interactiveMessage.interactive.body }}\n </Box>\n\n <Box\n v-if=\"interactiveMessage.interactive.footer\"\n v-bind=\"getStyles('messageInteractiveFooter')\"\n >\n {{ interactiveMessage.interactive.footer }}\n </Box>\n\n <Box\n v-if=\"interactiveMessage.interactive.type === 'button'\"\n v-bind=\"getStyles('messageInteractiveButtons')\"\n >\n <Box\n v-for=\"button in interactiveMessage.interactive.buttons\"\n :key=\"button.id\"\n v-bind=\"getStyles('messageInteractiveButton')\"\n >\n <WhatsAppIcon name=\"reply\" size=\"14\" />\n {{ button.title }}\n </Box>\n </Box>\n\n <Box\n v-else-if=\"interactiveMessage.interactive.type === 'cta_url'\"\n v-bind=\"getStyles('messageInteractiveButtons')\"\n >\n <Anchor\n v-bind=\"getStyles('messageInteractiveButton')\"\n :href=\"interactiveMessage.interactive.action.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <WhatsAppIcon name=\"externalLink\" size=\"14\" />\n {{ interactiveMessage.interactive.action.displayText }}\n </Anchor>\n </Box>\n\n <Box\n v-else-if=\"interactiveMessage.interactive.type === 'list'\"\n v-bind=\"getStyles('messageInteractiveButtons')\"\n >\n <Box v-bind=\"getStyles('messageInteractiveButton')\">\n <WhatsAppIcon name=\"interactive\" size=\"14\" />\n {{ interactiveMessage.interactive.button }}\n </Box>\n </Box>\n </Box>\n\n <Box v-else-if=\"locationMessage\" v-bind=\"getStyles('messageLocation')\">\n <WhatsAppIcon name=\"mapPin\" size=\"18\" />\n <Box>\n <Box v-if=\"locationMessage.location.name\" v-bind=\"getStyles('messageLocationName')\">\n {{ locationMessage.location.name }}\n </Box>\n <Box v-if=\"locationMessage.location.address\" v-bind=\"getStyles('messageLocationAddress')\">\n {{ locationMessage.location.address }}\n </Box>\n <Anchor :href=\"locationHref\" target=\"_blank\" rel=\"noopener noreferrer\" size=\"xs\">\n {{ config.labels.openInNewTab }}\n </Anchor>\n </Box>\n </Box>\n\n <template v-else-if=\"contactCards\">\n <Box\n v-for=\"(contact, index) in contactCards\"\n :key=\"`${contact.name}-${index}`\"\n v-bind=\"getStyles('messageContactCard')\"\n >\n <WhatsAppIcon name=\"user\" size=\"18\" />\n <Box>\n <Box v-bind=\"getStyles('messageContactName')\">{{ contact.name }}</Box>\n <Box\n v-for=\"phoneNumber in contact.phoneNumbers ?? []\"\n :key=\"phoneNumber\"\n v-bind=\"getStyles('messageContactDetail')\"\n >\n {{ phoneNumber }}\n </Box>\n </Box>\n </Box>\n </template>\n\n <Box v-else v-bind=\"getStyles('messageUnsupported')\">{{ unsupportedText }}</Box>\n\n <template v-if=\"hasCustomFooter\" #footer>\n <slot name=\"messageFooter\" :message=\"message\" />\n </template>\n </WhatsAppMessageBubble>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n withRetry: true,\n withTail: true,\n} as const\n\nconst MEDIA_TYPES = ['image', 'video', 'audio', 'document', 'sticker'] as const\n\nexport { defaultProps, MEDIA_TYPES }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots, type VNodeChild } from 'vue'\nimport { Anchor, Box, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppMessageSlots } from '../../component-props'\nimport type { WhatsAppAttachment, WhatsAppMediaMessage } from '../../types'\nimport { WhatsAppMediaAttachment } from '../WhatsAppMediaAttachment'\nimport { WhatsAppMessageBubble } from '../WhatsAppMessageBubble'\nimport { WhatsAppTemplatePreview } from '../WhatsAppTemplatePreview'\nimport type { WhatsAppMessageEmits, WhatsAppMessageOwnProps } from './WhatsAppMessage.types'\nimport classes from './WhatsAppMessage.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessage',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageOwnProps>(), {\n withRetry: undefined,\n withTail: undefined,\n maxWidth: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessageEmits>()\ndefineSlots<WhatsAppMessageSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessage', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessage',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'messageRoot',\n})\n\nconst message = computed(() => props.message)\n\n/**\n * The union is narrowed here rather than in the template: a `v-if` chain whose branches test\n * different expressions gives `vue-tsc` nothing to narrow on, so each variant is resolved once\n * into a typed computed and the template only reads the one that matches.\n */\nconst mediaMessage = computed(() =>\n (MEDIA_TYPES as readonly string[]).includes(message.value.type)\n ? (message.value as WhatsAppMediaMessage)\n : undefined,\n)\n\nconst textContent = computed(() =>\n message.value.type === 'text' || message.value.type === 'system' ? message.value.text : undefined,\n)\n\nconst templateInstance = computed(() =>\n message.value.type === 'template' ? message.value.template : undefined,\n)\n\nconst interactiveMessage = computed(() =>\n message.value.type === 'interactive' ? message.value : undefined,\n)\n\nconst locationMessage = computed(() =>\n message.value.type === 'location' ? message.value : undefined,\n)\n\nconst contactCards = computed(() =>\n message.value.type === 'contacts' ? message.value.contacts : undefined,\n)\n\nconst unsupportedText = computed(() =>\n message.value.type === 'unsupported'\n ? message.value.text || config.labels.messageTypeUnsupported\n : config.labels.messageTypeUnsupported,\n)\n\n/**\n * Returning `undefined` from `renderMessage` uses the built-in renderer.\n */\nconst customMessage = computed<VNodeChild>(() => props.renderMessage?.(message.value) ?? null)\nconst renderCustomMessage = () => customMessage.value\n\nconst customContent = computed<VNodeChild>(\n () => props.renderMessageContent?.(message.value) ?? null,\n)\nconst renderCustomContent = () => customContent.value\n\nconst hasCustomFooter = computed(() => Boolean(slots.messageFooter))\n\nfunction handleMediaDownload(attachment: WhatsAppAttachment) {\n emit('mediaDownload', attachment, message.value)\n}\n\nfunction handleMediaPreview(attachment: WhatsAppAttachment) {\n emit('mediaPreview', attachment, message.value)\n}\n\nconst locationHref = computed(() => {\n const location = locationMessage.value?.location\n\n if (!location) {\n return undefined\n }\n\n return (\n location.url ??\n `https://www.openstreetmap.org/?mlat=${location.latitude}&mlon=${location.longitude}`\n )\n})\n</script>\n\n<template>\n <component :is=\"renderCustomMessage\" v-if=\"customMessage\" />\n\n <WhatsAppMessageBubble\n v-else\n v-bind=\"{ ...attrs, ...getStyles('messageRoot') }\"\n :direction=\"message.direction\"\n :variant=\"message.type === 'system' ? 'system' : 'bubble'\"\n :status=\"message.type === 'system' ? undefined : message.status\"\n :timestamp=\"message.timestamp\"\n :author=\"message.author\"\n :reply-to=\"message.replyTo\"\n :forwarded=\"message.forwarded\"\n :error=\"message.error\"\n :with-retry=\"props.withRetry\"\n :reactions=\"message.reactions\"\n :with-tail=\"props.withTail\"\n :max-width=\"props.maxWidth\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n :data-message-id=\"message.id\"\n :data-message-type=\"message.type\"\n @retry=\"emit('retry', message)\"\n >\n <slot v-if=\"slots.messageContent\" name=\"messageContent\" :message=\"message\" />\n\n <component :is=\"renderCustomContent\" v-else-if=\"customContent\" />\n\n <template v-else-if=\"textContent !== undefined\">{{ textContent }}</template>\n\n <template v-else-if=\"mediaMessage\">\n <slot\n v-if=\"slots.mediaAttachment\"\n name=\"mediaAttachment\"\n :attachment=\"mediaMessage.attachment\"\n :message=\"message\"\n />\n <WhatsAppMediaAttachment\n v-else\n :attachment=\"mediaMessage.attachment\"\n :direction=\"message.direction\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @download=\"handleMediaDownload\"\n @preview=\"handleMediaPreview\"\n />\n\n <Box v-if=\"mediaMessage.caption\" v-bind=\"getStyles('messageCaption')\">\n {{ mediaMessage.caption }}\n </Box>\n </template>\n\n <WhatsAppTemplatePreview\n v-else-if=\"templateInstance\"\n :template=\"templateInstance.template\"\n :values=\"templateInstance.values\"\n :fallback-text=\"templateInstance.text ?? templateInstance.name\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n />\n\n <Box v-else-if=\"interactiveMessage\" v-bind=\"getStyles('messageInteractive')\">\n <Box v-if=\"interactiveMessage.reply\" v-bind=\"getStyles('messageInteractiveReply')\">\n {{ interactiveMessage.reply.title ?? interactiveMessage.reply.id }}\n </Box>\n\n <Box v-bind=\"getStyles('messageInteractiveBody')\">\n {{ interactiveMessage.interactive.body }}\n </Box>\n\n <Box\n v-if=\"interactiveMessage.interactive.footer\"\n v-bind=\"getStyles('messageInteractiveFooter')\"\n >\n {{ interactiveMessage.interactive.footer }}\n </Box>\n\n <Box\n v-if=\"interactiveMessage.interactive.type === 'button'\"\n v-bind=\"getStyles('messageInteractiveButtons')\"\n >\n <Box\n v-for=\"button in interactiveMessage.interactive.buttons\"\n :key=\"button.id\"\n v-bind=\"getStyles('messageInteractiveButton')\"\n >\n <WhatsAppIcon name=\"reply\" size=\"14\" />\n {{ button.title }}\n </Box>\n </Box>\n\n <Box\n v-else-if=\"interactiveMessage.interactive.type === 'cta_url'\"\n v-bind=\"getStyles('messageInteractiveButtons')\"\n >\n <Anchor\n v-bind=\"getStyles('messageInteractiveButton')\"\n :href=\"interactiveMessage.interactive.action.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <WhatsAppIcon name=\"externalLink\" size=\"14\" />\n {{ interactiveMessage.interactive.action.displayText }}\n </Anchor>\n </Box>\n\n <Box\n v-else-if=\"interactiveMessage.interactive.type === 'list'\"\n v-bind=\"getStyles('messageInteractiveButtons')\"\n >\n <Box v-bind=\"getStyles('messageInteractiveButton')\">\n <WhatsAppIcon name=\"interactive\" size=\"14\" />\n {{ interactiveMessage.interactive.button }}\n </Box>\n </Box>\n </Box>\n\n <Box v-else-if=\"locationMessage\" v-bind=\"getStyles('messageLocation')\">\n <WhatsAppIcon name=\"mapPin\" size=\"18\" />\n <Box>\n <Box v-if=\"locationMessage.location.name\" v-bind=\"getStyles('messageLocationName')\">\n {{ locationMessage.location.name }}\n </Box>\n <Box v-if=\"locationMessage.location.address\" v-bind=\"getStyles('messageLocationAddress')\">\n {{ locationMessage.location.address }}\n </Box>\n <Anchor :href=\"locationHref\" target=\"_blank\" rel=\"noopener noreferrer\" size=\"xs\">\n {{ config.labels.openInNewTab }}\n </Anchor>\n </Box>\n </Box>\n\n <template v-else-if=\"contactCards\">\n <Box\n v-for=\"(contact, index) in contactCards\"\n :key=\"`${contact.name}-${index}`\"\n v-bind=\"getStyles('messageContactCard')\"\n >\n <WhatsAppIcon name=\"user\" size=\"18\" />\n <Box>\n <Box v-bind=\"getStyles('messageContactName')\">{{ contact.name }}</Box>\n <Box\n v-for=\"phoneNumber in contact.phoneNumbers ?? []\"\n :key=\"phoneNumber\"\n v-bind=\"getStyles('messageContactDetail')\"\n >\n {{ phoneNumber }}\n </Box>\n </Box>\n </Box>\n </template>\n\n <Box v-else v-bind=\"getStyles('messageUnsupported')\">{{ unsupportedText }}</Box>\n\n <template v-if=\"hasCustomFooter\" #footer>\n <slot name=\"messageFooter\" :message=\"message\" />\n </template>\n </WhatsAppMessageBubble>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppMessageComponent from './WhatsAppMessage.vue'\nimport type { WhatsAppMessageFactory } from './WhatsAppMessage.types'\nimport classes from './WhatsAppMessage.module.css'\n\nexport const WhatsAppMessage = factory<WhatsAppMessageFactory>(WhatsAppMessageComponent, {\n classes,\n})\n\nexport type {\n WhatsAppMessageEmits,\n WhatsAppMessageFactory,\n WhatsAppMessageOwnProps,\n WhatsAppMessageProps,\n WhatsAppMessageStylesNames,\n} from './WhatsAppMessage.types'\n",".messageListRoot {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n background-color: var(--wa-conversation-bg, var(--mantine-color-default));\n}\n\n.messageListScrollArea {\n flex: 1;\n min-height: 0;\n}\n\n.messageListContent {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-md);\n min-height: 100%;\n justify-content: flex-end;\n}\n\n.messageListItems {\n display: flex;\n flex-direction: column;\n gap: 2px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\n * One day of messages. The divider sticks inside this box rather than inside the whole list,\n * so the label of the next day pushes the previous one out instead of stacking on top of it.\n */\n.messageListGroup {\n display: flex;\n flex-direction: column;\n}\n\n.messageListGroupItems {\n display: flex;\n flex-direction: column;\n gap: 2px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.messageListItem {\n display: flex;\n flex-direction: column;\n}\n\n.messageListItem:where([data-first-of-run]) {\n margin-top: 8px;\n}\n\n.messageListDayDivider {\n display: flex;\n justify-content: center;\n padding-block: var(--mantine-spacing-xs);\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.messageListDayLabel {\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n background-color: var(--mantine-color-body);\n border-radius: var(--mantine-radius-sm);\n padding: 3px 10px;\n box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);\n}\n\n.messageListLoadOlder {\n display: flex;\n justify-content: center;\n padding-block: var(--mantine-spacing-xs);\n}\n\n.messageListState {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mantine-spacing-sm);\n flex: 1;\n padding: var(--mantine-spacing-xl);\n text-align: center;\n}\n\n.messageListScrollToBottom {\n position: absolute;\n inset-block-end: var(--mantine-spacing-md);\n inset-inline-end: var(--mantine-spacing-md);\n z-index: 2;\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n withDayDividers: true,\n autoScroll: true,\n autoScrollThreshold: 80,\n loadOlderThreshold: 120,\n} as const\n\n/**\n * Marks the `ScrollArea` viewport so the list can find it again without depending on Mantine\n * static classes, which a consumer can turn off.\n */\nconst VIEWPORT_ATTRIBUTE = 'data-whatsapp-message-viewport'\n\nexport { defaultProps, VIEWPORT_ATTRIBUTE }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, ref, useAttrs, useSlots, watch } from 'vue'\nimport {\n ActionIcon,\n Alert,\n Box,\n Button,\n Center,\n Loader,\n ScrollArea,\n Text,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useResolvedCapabilities, useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { resolveMessageRenderers } from '../../component-props'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppMessageData } from '../../types'\nimport { groupMessagesByDay } from '../../utils'\nimport { WhatsAppMessage } from '../WhatsAppMessage'\nimport type {\n WhatsAppMessageListEmits,\n WhatsAppMessageListOwnProps,\n WhatsAppMessageListSlots,\n} from './WhatsAppMessageList.types'\nimport classes from './WhatsAppMessageList.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessageList',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageListOwnProps>(), {\n messages: undefined,\n conversationId: undefined,\n loading: undefined,\n error: undefined,\n pagination: undefined,\n withRetry: undefined,\n withDayDividers: undefined,\n autoScroll: undefined,\n autoScrollThreshold: undefined,\n loadOlderThreshold: undefined,\n bubbleMaxWidth: undefined,\n viewportProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessageListEmits>()\ndefineSlots<WhatsAppMessageListSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessageList', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\nconst capabilities = useResolvedCapabilities(\n () => undefined,\n () => false,\n)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessageList',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'messageListRoot',\n})\n\nconst messages = computed(() => props.messages ?? [])\nconst groups = computed(() => groupMessagesByDay(messages.value))\nconst messageRenderers = computed(() => resolveMessageRenderers(props, slots))\n\nconst withRetry = computed(() => props.withRetry ?? capabilities.value.canRetryFailed)\n\nconst hasMessages = computed(() => messages.value.length > 0)\nconst showLoading = computed(() => Boolean(props.loading) && !hasMessages.value)\nconst showError = computed(() => Boolean(props.error) && !hasMessages.value)\nconst showEmpty = computed(() => !showLoading.value && !showError.value && !hasMessages.value)\n\nconst canLoadOlder = computed(\n () => Boolean(props.pagination?.hasMore) && !props.pagination?.loadingMore,\n)\n\nconst contentElement = ref<HTMLDivElement | null>(null)\nconst atBottom = ref(true)\nconst pendingCount = ref(0)\n\nconst viewportProps = computed(() => ({\n ...props.viewportProps,\n [VIEWPORT_ATTRIBUTE]: '',\n}))\n\nfunction getViewport(): HTMLElement | null {\n return contentElement.value?.closest<HTMLElement>(`[${VIEWPORT_ATTRIBUTE}]`) ?? null\n}\n\nfunction scrollToBottom(behavior: ScrollBehavior = 'auto') {\n const viewport = getViewport()\n\n if (!viewport) {\n return\n }\n\n // `scrollTo` is missing in jsdom and in a few older engines; the assignment is the fallback\n // that always works, at the cost of the smooth animation.\n if (typeof viewport.scrollTo === 'function') {\n viewport.scrollTo({ top: viewport.scrollHeight, behavior })\n } else {\n viewport.scrollTop = viewport.scrollHeight\n }\n\n pendingCount.value = 0\n atBottom.value = true\n}\n\nfunction updateAtBottom() {\n const viewport = getViewport()\n\n if (!viewport) {\n return\n }\n\n const distance = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight\n const next = distance <= (props.autoScrollThreshold ?? defaultProps.autoScrollThreshold)\n\n if (next !== atBottom.value) {\n atBottom.value = next\n emit('atBottomChange', next)\n }\n\n if (next) {\n pendingCount.value = 0\n }\n}\n\nfunction requestOlder() {\n if (!canLoadOlder.value) {\n return\n }\n\n emit('loadOlder', { cursor: props.pagination?.cursor })\n}\n\nfunction handleScroll() {\n updateAtBottom()\n\n const viewport = getViewport()\n\n if (\n viewport &&\n viewport.scrollTop <= (props.loadOlderThreshold ?? defaultProps.loadOlderThreshold)\n ) {\n requestOlder()\n }\n}\n\nfunction getEdges(list: WhatsAppMessageData[]) {\n return {\n length: list.length,\n first: list[0]?.id,\n last: list[list.length - 1]?.id,\n }\n}\n\nlet previousEdges = getEdges([])\n\n/**\n * Distance from the bottom of the content, captured before Vue patches the DOM.\n *\n * Restoring this value after prepending messages preserves the reading position even though the\n * absolute scroll offset changes.\n */\nlet preservedBottomOffset: number | null = null\n\nwatch(\n () => props.messages,\n (next) => {\n const edges = getEdges(next ?? [])\n const previous = previousEdges\n previousEdges = edges\n\n if (edges.length === 0 || previous.length === 0) {\n preservedBottomOffset = null\n return\n }\n\n const prepended = edges.first !== previous.first && edges.length > previous.length\n const appended = edges.last !== previous.last\n\n if (prepended) {\n const viewport = getViewport()\n preservedBottomOffset = viewport ? viewport.scrollHeight - viewport.scrollTop : null\n return\n }\n\n if (appended && !atBottom.value) {\n pendingCount.value += edges.length - previous.length\n }\n },\n { flush: 'pre' },\n)\n\nwatch(\n () => props.messages,\n () => {\n void nextTick(() => {\n const viewport = getViewport()\n\n if (!viewport) {\n return\n }\n\n if (preservedBottomOffset !== null) {\n viewport.scrollTop = viewport.scrollHeight - preservedBottomOffset\n preservedBottomOffset = null\n return\n }\n\n if (props.autoScroll && atBottom.value) {\n scrollToBottom()\n }\n })\n },\n { flush: 'post' },\n)\n\n// Switching conversations starts a different history: jump to its newest message immediately\n// rather than inheriting the previous conversation's offset.\nwatch(\n () => props.conversationId,\n () => {\n previousEdges = getEdges(messages.value)\n preservedBottomOffset = null\n pendingCount.value = 0\n atBottom.value = true\n void nextTick(() => scrollToBottom())\n },\n)\n\nonMounted(() => {\n previousEdges = getEdges(messages.value)\n scrollToBottom()\n})\n\ndefineExpose({ scrollToBottom, getViewport })\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('messageListRoot') }\">\n <ScrollArea\n v-bind=\"getStyles('messageListScrollArea')\"\n type=\"auto\"\n scrollbars=\"y\"\n :viewport-props=\"viewportProps\"\n @scroll-position-change=\"handleScroll\"\n >\n <div ref=\"contentElement\" v-bind=\"getStyles('messageListContent')\">\n <Center v-if=\"showLoading\" v-bind=\"getStyles('messageListState')\">\n <slot v-if=\"slots.loadingMessages\" name=\"loadingMessages\" />\n <template v-else>\n <Loader size=\"sm\" />\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.loadingMessages }}</Text>\n </template>\n </Center>\n\n <Box v-else-if=\"showError\" v-bind=\"getStyles('messageListState')\">\n <slot v-if=\"slots.errorMessages\" name=\"errorMessages\" :error=\"props.error ?? ''\" />\n <Alert v-else color=\"red\" variant=\"light\" :title=\"config.labels.messagesError\">\n <Text size=\"sm\">{{ props.error }}</Text>\n <Button mt=\"sm\" size=\"xs\" variant=\"light\" color=\"red\" @click=\"emit('retryLoad')\">\n {{ config.labels.retry }}\n </Button>\n </Alert>\n </Box>\n\n <Box v-else-if=\"showEmpty\" v-bind=\"getStyles('messageListState')\">\n <slot v-if=\"slots.emptyConversation\" name=\"emptyConversation\" />\n <template v-else>\n <WhatsAppIcon\n name=\"message\"\n size=\"40\"\n :style=\"{ color: 'var(--mantine-color-dimmed)' }\"\n />\n <Text size=\"sm\" fw=\"500\">{{ config.labels.emptyConversation }}</Text>\n <Text size=\"xs\" c=\"dimmed\">{{ config.labels.emptyConversationDescription }}</Text>\n </template>\n </Box>\n\n <template v-else>\n <Box\n v-if=\"canLoadOlder || props.pagination?.loadingMore\"\n v-bind=\"getStyles('messageListLoadOlder')\"\n >\n <Loader v-if=\"props.pagination?.loadingMore\" size=\"xs\" />\n <Button v-else size=\"compact-xs\" variant=\"subtle\" @click=\"requestOlder\">\n {{ config.labels.loadOlderMessages }}\n </Button>\n </Box>\n\n <Box\n component=\"ol\"\n v-bind=\"getStyles('messageListItems')\"\n role=\"log\"\n :aria-label=\"config.labels.messageHistoryLabel\"\n aria-relevant=\"additions text\"\n >\n <Box\n v-for=\"group in groups\"\n :key=\"group.key\"\n component=\"li\"\n v-bind=\"getStyles('messageListGroup')\"\n >\n <Box\n v-if=\"props.withDayDividers && group.date\"\n v-bind=\"getStyles('messageListDayDivider')\"\n >\n <Box component=\"span\" v-bind=\"getStyles('messageListDayLabel')\">\n {{ config.dayLabel(group.date) }}\n </Box>\n </Box>\n\n <Box component=\"ol\" v-bind=\"getStyles('messageListGroupItems')\">\n <Box\n v-for=\"(message, index) in group.messages\"\n :key=\"message.id\"\n component=\"li\"\n v-bind=\"getStyles('messageListItem')\"\n :data-first-of-run=\"\n index === 0 || group.messages[index - 1].direction !== message.direction\n ? ''\n : undefined\n \"\n >\n <slot v-if=\"slots.message\" name=\"message\" :message=\"message\" />\n\n <WhatsAppMessage\n v-else\n :message=\"message\"\n :with-retry=\"withRetry\"\n :with-tail=\"\n index === 0 || group.messages[index - 1].direction !== message.direction\n \"\n :max-width=\"props.bubbleMaxWidth\"\n :labels=\"props.labels\"\n :render-message=\"messageRenderers.renderMessage\"\n :render-message-content=\"messageRenderers.renderMessageContent\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @retry=\"emit('retryMessage', $event)\"\n @media-download=\"emit('mediaDownload', $event, message)\"\n @media-preview=\"emit('mediaPreview', $event, message)\"\n >\n <template v-if=\"slots.messageFooter\" #messageFooter=\"footerProps\">\n <slot name=\"messageFooter\" v-bind=\"footerProps\" />\n </template>\n <template v-if=\"slots.mediaAttachment\" #mediaAttachment=\"mediaProps\">\n <slot name=\"mediaAttachment\" v-bind=\"mediaProps\" />\n </template>\n </WhatsAppMessage>\n </Box>\n </Box>\n </Box>\n </Box>\n </template>\n </div>\n </ScrollArea>\n\n <ActionIcon\n v-if=\"!atBottom && hasMessages\"\n v-bind=\"getStyles('messageListScrollToBottom')\"\n variant=\"default\"\n radius=\"xl\"\n size=\"lg\"\n :aria-label=\"\n pendingCount > 0 ? config.labels.newMessages(pendingCount) : config.labels.scrollToBottom\n \"\n @click=\"scrollToBottom('smooth')\"\n >\n <WhatsAppIcon name=\"chevronDown\" size=\"18\" />\n </ActionIcon>\n </Box>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n withDayDividers: true,\n autoScroll: true,\n autoScrollThreshold: 80,\n loadOlderThreshold: 120,\n} as const\n\n/**\n * Marks the `ScrollArea` viewport so the list can find it again without depending on Mantine\n * static classes, which a consumer can turn off.\n */\nconst VIEWPORT_ATTRIBUTE = 'data-whatsapp-message-viewport'\n\nexport { defaultProps, VIEWPORT_ATTRIBUTE }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, ref, useAttrs, useSlots, watch } from 'vue'\nimport {\n ActionIcon,\n Alert,\n Box,\n Button,\n Center,\n Loader,\n ScrollArea,\n Text,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useResolvedCapabilities, useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { resolveMessageRenderers } from '../../component-props'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppMessageData } from '../../types'\nimport { groupMessagesByDay } from '../../utils'\nimport { WhatsAppMessage } from '../WhatsAppMessage'\nimport type {\n WhatsAppMessageListEmits,\n WhatsAppMessageListOwnProps,\n WhatsAppMessageListSlots,\n} from './WhatsAppMessageList.types'\nimport classes from './WhatsAppMessageList.module.css'\n\ndefineOptions({\n name: 'WhatsAppMessageList',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppMessageListOwnProps>(), {\n messages: undefined,\n conversationId: undefined,\n loading: undefined,\n error: undefined,\n pagination: undefined,\n withRetry: undefined,\n withDayDividers: undefined,\n autoScroll: undefined,\n autoScrollThreshold: undefined,\n loadOlderThreshold: undefined,\n bubbleMaxWidth: undefined,\n viewportProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppMessageListEmits>()\ndefineSlots<WhatsAppMessageListSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppMessageList', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\nconst capabilities = useResolvedCapabilities(\n () => undefined,\n () => false,\n)\n\nconst getStyles = useStyles({\n name: 'WhatsAppMessageList',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'messageListRoot',\n})\n\nconst messages = computed(() => props.messages ?? [])\nconst groups = computed(() => groupMessagesByDay(messages.value))\nconst messageRenderers = computed(() => resolveMessageRenderers(props, slots))\n\nconst withRetry = computed(() => props.withRetry ?? capabilities.value.canRetryFailed)\n\nconst hasMessages = computed(() => messages.value.length > 0)\nconst showLoading = computed(() => Boolean(props.loading) && !hasMessages.value)\nconst showError = computed(() => Boolean(props.error) && !hasMessages.value)\nconst showEmpty = computed(() => !showLoading.value && !showError.value && !hasMessages.value)\n\nconst canLoadOlder = computed(\n () => Boolean(props.pagination?.hasMore) && !props.pagination?.loadingMore,\n)\n\nconst contentElement = ref<HTMLDivElement | null>(null)\nconst atBottom = ref(true)\nconst pendingCount = ref(0)\n\nconst viewportProps = computed(() => ({\n ...props.viewportProps,\n [VIEWPORT_ATTRIBUTE]: '',\n}))\n\nfunction getViewport(): HTMLElement | null {\n return contentElement.value?.closest<HTMLElement>(`[${VIEWPORT_ATTRIBUTE}]`) ?? null\n}\n\nfunction scrollToBottom(behavior: ScrollBehavior = 'auto') {\n const viewport = getViewport()\n\n if (!viewport) {\n return\n }\n\n // `scrollTo` is missing in jsdom and in a few older engines; the assignment is the fallback\n // that always works, at the cost of the smooth animation.\n if (typeof viewport.scrollTo === 'function') {\n viewport.scrollTo({ top: viewport.scrollHeight, behavior })\n } else {\n viewport.scrollTop = viewport.scrollHeight\n }\n\n pendingCount.value = 0\n atBottom.value = true\n}\n\nfunction updateAtBottom() {\n const viewport = getViewport()\n\n if (!viewport) {\n return\n }\n\n const distance = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight\n const next = distance <= (props.autoScrollThreshold ?? defaultProps.autoScrollThreshold)\n\n if (next !== atBottom.value) {\n atBottom.value = next\n emit('atBottomChange', next)\n }\n\n if (next) {\n pendingCount.value = 0\n }\n}\n\nfunction requestOlder() {\n if (!canLoadOlder.value) {\n return\n }\n\n emit('loadOlder', { cursor: props.pagination?.cursor })\n}\n\nfunction handleScroll() {\n updateAtBottom()\n\n const viewport = getViewport()\n\n if (\n viewport &&\n viewport.scrollTop <= (props.loadOlderThreshold ?? defaultProps.loadOlderThreshold)\n ) {\n requestOlder()\n }\n}\n\nfunction getEdges(list: WhatsAppMessageData[]) {\n return {\n length: list.length,\n first: list[0]?.id,\n last: list[list.length - 1]?.id,\n }\n}\n\nlet previousEdges = getEdges([])\n\n/**\n * Distance from the bottom of the content, captured before Vue patches the DOM.\n *\n * Restoring this value after prepending messages preserves the reading position even though the\n * absolute scroll offset changes.\n */\nlet preservedBottomOffset: number | null = null\n\nwatch(\n () => props.messages,\n (next) => {\n const edges = getEdges(next ?? [])\n const previous = previousEdges\n previousEdges = edges\n\n if (edges.length === 0 || previous.length === 0) {\n preservedBottomOffset = null\n return\n }\n\n const prepended = edges.first !== previous.first && edges.length > previous.length\n const appended = edges.last !== previous.last\n\n if (prepended) {\n const viewport = getViewport()\n preservedBottomOffset = viewport ? viewport.scrollHeight - viewport.scrollTop : null\n return\n }\n\n if (appended && !atBottom.value) {\n pendingCount.value += edges.length - previous.length\n }\n },\n { flush: 'pre' },\n)\n\nwatch(\n () => props.messages,\n () => {\n void nextTick(() => {\n const viewport = getViewport()\n\n if (!viewport) {\n return\n }\n\n if (preservedBottomOffset !== null) {\n viewport.scrollTop = viewport.scrollHeight - preservedBottomOffset\n preservedBottomOffset = null\n return\n }\n\n if (props.autoScroll && atBottom.value) {\n scrollToBottom()\n }\n })\n },\n { flush: 'post' },\n)\n\n// Switching conversations starts a different history: jump to its newest message immediately\n// rather than inheriting the previous conversation's offset.\nwatch(\n () => props.conversationId,\n () => {\n previousEdges = getEdges(messages.value)\n preservedBottomOffset = null\n pendingCount.value = 0\n atBottom.value = true\n void nextTick(() => scrollToBottom())\n },\n)\n\nonMounted(() => {\n previousEdges = getEdges(messages.value)\n scrollToBottom()\n})\n\ndefineExpose({ scrollToBottom, getViewport })\n</script>\n\n<template>\n <Box v-bind=\"{ ...attrs, ...getStyles('messageListRoot') }\">\n <ScrollArea\n v-bind=\"getStyles('messageListScrollArea')\"\n type=\"auto\"\n scrollbars=\"y\"\n :viewport-props=\"viewportProps\"\n @scroll-position-change=\"handleScroll\"\n >\n <div ref=\"contentElement\" v-bind=\"getStyles('messageListContent')\">\n <Center v-if=\"showLoading\" v-bind=\"getStyles('messageListState')\">\n <slot v-if=\"slots.loadingMessages\" name=\"loadingMessages\" />\n <template v-else>\n <Loader size=\"sm\" />\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.loadingMessages }}</Text>\n </template>\n </Center>\n\n <Box v-else-if=\"showError\" v-bind=\"getStyles('messageListState')\">\n <slot v-if=\"slots.errorMessages\" name=\"errorMessages\" :error=\"props.error ?? ''\" />\n <Alert v-else color=\"red\" variant=\"light\" :title=\"config.labels.messagesError\">\n <Text size=\"sm\">{{ props.error }}</Text>\n <Button mt=\"sm\" size=\"xs\" variant=\"light\" color=\"red\" @click=\"emit('retryLoad')\">\n {{ config.labels.retry }}\n </Button>\n </Alert>\n </Box>\n\n <Box v-else-if=\"showEmpty\" v-bind=\"getStyles('messageListState')\">\n <slot v-if=\"slots.emptyConversation\" name=\"emptyConversation\" />\n <template v-else>\n <WhatsAppIcon\n name=\"message\"\n size=\"40\"\n :style=\"{ color: 'var(--mantine-color-dimmed)' }\"\n />\n <Text size=\"sm\" fw=\"500\">{{ config.labels.emptyConversation }}</Text>\n <Text size=\"xs\" c=\"dimmed\">{{ config.labels.emptyConversationDescription }}</Text>\n </template>\n </Box>\n\n <template v-else>\n <Box\n v-if=\"canLoadOlder || props.pagination?.loadingMore\"\n v-bind=\"getStyles('messageListLoadOlder')\"\n >\n <Loader v-if=\"props.pagination?.loadingMore\" size=\"xs\" />\n <Button v-else size=\"compact-xs\" variant=\"subtle\" @click=\"requestOlder\">\n {{ config.labels.loadOlderMessages }}\n </Button>\n </Box>\n\n <Box\n component=\"ol\"\n v-bind=\"getStyles('messageListItems')\"\n role=\"log\"\n :aria-label=\"config.labels.messageHistoryLabel\"\n aria-relevant=\"additions text\"\n >\n <Box\n v-for=\"group in groups\"\n :key=\"group.key\"\n component=\"li\"\n v-bind=\"getStyles('messageListGroup')\"\n >\n <Box\n v-if=\"props.withDayDividers && group.date\"\n v-bind=\"getStyles('messageListDayDivider')\"\n >\n <Box component=\"span\" v-bind=\"getStyles('messageListDayLabel')\">\n {{ config.dayLabel(group.date) }}\n </Box>\n </Box>\n\n <Box component=\"ol\" v-bind=\"getStyles('messageListGroupItems')\">\n <Box\n v-for=\"(message, index) in group.messages\"\n :key=\"message.id\"\n component=\"li\"\n v-bind=\"getStyles('messageListItem')\"\n :data-first-of-run=\"\n index === 0 || group.messages[index - 1].direction !== message.direction\n ? ''\n : undefined\n \"\n >\n <slot v-if=\"slots.message\" name=\"message\" :message=\"message\" />\n\n <WhatsAppMessage\n v-else\n :message=\"message\"\n :with-retry=\"withRetry\"\n :with-tail=\"\n index === 0 || group.messages[index - 1].direction !== message.direction\n \"\n :max-width=\"props.bubbleMaxWidth\"\n :labels=\"props.labels\"\n :render-message=\"messageRenderers.renderMessage\"\n :render-message-content=\"messageRenderers.renderMessageContent\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @retry=\"emit('retryMessage', $event)\"\n @media-download=\"emit('mediaDownload', $event, message)\"\n @media-preview=\"emit('mediaPreview', $event, message)\"\n >\n <template v-if=\"slots.messageFooter\" #messageFooter=\"footerProps\">\n <slot name=\"messageFooter\" v-bind=\"footerProps\" />\n </template>\n <template v-if=\"slots.mediaAttachment\" #mediaAttachment=\"mediaProps\">\n <slot name=\"mediaAttachment\" v-bind=\"mediaProps\" />\n </template>\n </WhatsAppMessage>\n </Box>\n </Box>\n </Box>\n </Box>\n </template>\n </div>\n </ScrollArea>\n\n <ActionIcon\n v-if=\"!atBottom && hasMessages\"\n v-bind=\"getStyles('messageListScrollToBottom')\"\n variant=\"default\"\n radius=\"xl\"\n size=\"lg\"\n :aria-label=\"\n pendingCount > 0 ? config.labels.newMessages(pendingCount) : config.labels.scrollToBottom\n \"\n @click=\"scrollToBottom('smooth')\"\n >\n <WhatsAppIcon name=\"chevronDown\" size=\"18\" />\n </ActionIcon>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppMessageListComponent from './WhatsAppMessageList.vue'\nimport type { WhatsAppMessageListFactory } from './WhatsAppMessageList.types'\nimport classes from './WhatsAppMessageList.module.css'\n\nexport const WhatsAppMessageList = factory<WhatsAppMessageListFactory>(\n WhatsAppMessageListComponent,\n { classes },\n)\n\nexport type {\n WhatsAppMessageListEmits,\n WhatsAppMessageListExposed,\n WhatsAppMessageListFactory,\n WhatsAppMessageListOwnProps,\n WhatsAppMessageListProps,\n WhatsAppMessageListSlots,\n WhatsAppMessageListStylesNames,\n} from './WhatsAppMessageList.types'\n",".conversationRoot {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n overflow: hidden;\n background-color: var(--mantine-color-body);\n}\n\n.conversationState {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mantine-spacing-sm);\n flex: 1;\n padding: var(--mantine-spacing-xl);\n text-align: center;\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n draftBehavior: 'preserve',\n withHeader: true,\n withComposer: true,\n withBack: false,\n withContactToggle: false,\n focusComposerOnChange: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch } from 'vue'\nimport { Box, Text, useProps, useStyles } from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport {\n provideWhatsAppConversationContext,\n useWhatsAppInboxConfig,\n} from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationSlots } from '../../component-props'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppAttachment, WhatsAppMessageData, WhatsAppOutgoingMessage } from '../../types'\nimport { resolveCapabilities } from '../../utils'\nimport { WhatsAppComposer } from '../WhatsAppComposer'\nimport type { WhatsAppComposerExposed } from '../WhatsAppComposer'\nimport { WhatsAppConversationHeader } from '../WhatsAppConversationHeader'\nimport { WhatsAppMessageList } from '../WhatsAppMessageList'\nimport type { WhatsAppMessageListExposed } from '../WhatsAppMessageList'\nimport type {\n WhatsAppConversationEmits,\n WhatsAppConversationOwnProps,\n} from './WhatsAppConversation.types'\nimport classes from './WhatsAppConversation.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversation',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationOwnProps>(), {\n conversation: undefined,\n conversationId: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n drafts: undefined,\n defaultDrafts: undefined,\n draftBehavior: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n withBack: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationEmits>()\ndefineSlots<WhatsAppConversationSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversation', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversation',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationRoot',\n})\n\nconst conversationId = computed(() => props.conversationId ?? props.conversation?.id)\n\nconst capabilities = computed(() =>\n resolveCapabilities(props.capabilities ?? props.conversation?.capabilities),\n)\n\n/**\n * Publishes the conversation to the primitives below, so a consumer can compose a custom layout\n * out of `WhatsAppMessageList` and `WhatsAppComposer` without threading capabilities through\n * every level. Getters keep the context reactive after a single `provide` in `setup`.\n */\nprovideWhatsAppConversationContext({\n get conversation() {\n return props.conversation\n },\n get conversationId() {\n return conversationId.value\n },\n get capabilities() {\n return capabilities.value\n },\n})\n\nconst composerRef = ref<WhatsAppComposerExposed | null>(null)\nconst messageListRef = ref<WhatsAppMessageListExposed | null>(null)\n\nfunction focusComposer() {\n composerRef.value?.focus()\n}\n\nfunction scrollToBottom(behavior: ScrollBehavior = 'auto') {\n messageListRef.value?.scrollToBottom(behavior)\n}\n\n/**\n * Unsent drafts, one per conversation.\n *\n * Drafts are preserved by default. `draftBehavior: 'reset'` opts out, and a controlled `draft`\n * bypasses the map for single-conversation layouts.\n */\nconst [draftMap, setDraftMap] = useUncontrolled<Record<string, string>>({\n value: () => props.drafts,\n defaultValue: props.defaultDrafts,\n finalValue: {},\n onChange: (value) => emit('update:drafts', value),\n})\n\nconst singleDraft = computed(() => props.draft !== undefined)\n\nconst composerDraft = computed(() =>\n singleDraft.value ? props.draft : (draftMap.value[conversationId.value ?? ''] ?? ''),\n)\n\n/** Drops the draft of the conversation that was just sent from, so the input starts clean. */\nfunction clearDraft(id: string | undefined) {\n if (singleDraft.value || !id || draftMap.value[id] === undefined) {\n return\n }\n\n const { [id]: _sent, ...rest } = draftMap.value\n\n setDraftMap(rest)\n}\n\nfunction setComposerDraft(value: string) {\n emit('update:draft', value)\n\n const id = conversationId.value\n\n if (singleDraft.value || !id) {\n return\n }\n\n // An empty draft is dropped rather than stored, so a persisted map never fills up with\n // entries for conversations the user only visited.\n if (value.length === 0) {\n clearDraft(id)\n return\n }\n\n setDraftMap({ ...draftMap.value, [id]: value })\n}\n\n// Focus the composer after switching conversations.\nwatch(conversationId, (next, previous) => {\n if (props.draftBehavior === 'reset') {\n clearDraft(previous)\n }\n\n if (next && props.focusComposerOnChange) {\n void nextTick(focusComposer)\n }\n})\n\nconst hasConversation = computed(() => Boolean(conversationId.value))\n\n// Multi-argument emits need a real handler: a template expression only ever receives `$event`.\nfunction handleMediaDownload(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaDownload', attachment, message)\n}\n\nfunction handleMediaPreview(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaPreview', attachment, message)\n}\n\nfunction handleSend(payload: WhatsAppOutgoingMessage) {\n // The composer resets its own input on send; the stored draft has to follow.\n clearDraft(conversationId.value)\n emit('send', payload)\n}\n\ndefineExpose({ focusComposer, scrollToBottom })\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('conversationRoot') }\"\n :data-conversation-id=\"conversationId\"\n >\n <Box v-if=\"!hasConversation\" v-bind=\"getStyles('conversationState')\">\n <WhatsAppIcon name=\"message\" size=\"44\" :style=\"{ color: 'var(--mantine-color-dimmed)' }\" />\n <Text size=\"sm\" fw=\"500\">{{ config.labels.noConversationSelected }}</Text>\n <Text size=\"xs\" c=\"dimmed\">{{ config.labels.noConversationSelectedDescription }}</Text>\n </Box>\n\n <template v-else>\n <slot\n v-if=\"slots.conversationHeader\"\n name=\"conversationHeader\"\n :conversation=\"props.conversation\"\n />\n\n <WhatsAppConversationHeader\n v-else-if=\"props.withHeader\"\n v-bind=\"props.headerProps\"\n :conversation=\"props.conversation\"\n :with-back=\"props.withBack\"\n :with-contact-toggle=\"props.withContactToggle\"\n :contact-panel-opened=\"props.contactPanelOpened\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @back=\"emit('back')\"\n @toggle-contact-panel=\"emit('toggleContactPanel', $event)\"\n @contact-click=\"props.conversation && emit('contactClick', props.conversation)\"\n >\n <template v-if=\"slots.headerActions\" #headerActions=\"headerActionsProps\">\n <slot name=\"headerActions\" v-bind=\"headerActionsProps\" />\n </template>\n </WhatsAppConversationHeader>\n\n <WhatsAppMessageList\n ref=\"messageListRef\"\n v-bind=\"props.messageListProps\"\n :messages=\"props.messages\"\n :conversation-id=\"conversationId\"\n :loading=\"props.messagesLoading\"\n :error=\"props.messagesError\"\n :pagination=\"props.messagesPagination\"\n :labels=\"props.labels\"\n :render-message=\"props.renderMessage\"\n :render-message-content=\"props.renderMessageContent\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @load-older=\"emit('loadOlderMessages', $event)\"\n @retry-load=\"emit('retryLoadMessages')\"\n @retry-message=\"emit('retryMessage', $event)\"\n @media-download=\"handleMediaDownload\"\n @media-preview=\"handleMediaPreview\"\n @at-bottom-change=\"emit('atBottomChange', $event)\"\n >\n <template v-if=\"slots.message\" #message=\"messageProps\">\n <slot name=\"message\" v-bind=\"messageProps\" />\n </template>\n <template v-if=\"slots.messageContent\" #messageContent=\"messageContentProps\">\n <slot name=\"messageContent\" v-bind=\"messageContentProps\" />\n </template>\n <template v-if=\"slots.messageFooter\" #messageFooter=\"messageFooterProps\">\n <slot name=\"messageFooter\" v-bind=\"messageFooterProps\" />\n </template>\n <template v-if=\"slots.mediaAttachment\" #mediaAttachment=\"mediaProps\">\n <slot name=\"mediaAttachment\" v-bind=\"mediaProps\" />\n </template>\n <template v-if=\"slots.emptyConversation\" #emptyConversation>\n <slot name=\"emptyConversation\" />\n </template>\n <template v-if=\"slots.loadingMessages\" #loadingMessages>\n <slot name=\"loadingMessages\" />\n </template>\n <template v-if=\"slots.errorMessages\" #errorMessages=\"errorProps\">\n <slot name=\"errorMessages\" v-bind=\"errorProps\" />\n </template>\n </WhatsAppMessageList>\n\n <WhatsAppComposer\n v-if=\"props.withComposer\"\n ref=\"composerRef\"\n v-bind=\"props.composerProps\"\n :conversation-id=\"conversationId\"\n :model-value=\"composerDraft\"\n :capabilities=\"props.capabilities ?? props.conversation?.capabilities\"\n :uploads=\"props.uploads\"\n :templates=\"props.templates\"\n :templates-loading=\"props.templatesLoading\"\n :templates-error=\"props.templatesError\"\n :sending=\"props.sending\"\n :error=\"props.sendError\"\n :reply-to=\"props.replyTo\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @update:model-value=\"setComposerDraft($event)\"\n @update:reply-to=\"emit('update:replyTo', $event)\"\n @typing=\"emit('typing', $event)\"\n @send=\"handleSend\"\n @attachments-add=\"emit('attachmentsAdd', $event)\"\n @attachments-reject=\"emit('attachmentsReject', $event)\"\n @attachment-remove=\"emit('attachmentRemove', $event)\"\n @attachment-retry=\"emit('attachmentRetry', $event)\"\n @attachment-cancel=\"emit('attachmentCancel', $event)\"\n @validation-error=\"emit('validationError', $event)\"\n @retry-send=\"emit('retrySend')\"\n @templates-retry-load=\"emit('templatesRetryLoad')\"\n >\n <template v-if=\"slots.composerPrefix\" #composerPrefix>\n <slot name=\"composerPrefix\" />\n </template>\n <template v-if=\"slots.composerSuffix\" #composerSuffix>\n <slot name=\"composerSuffix\" />\n </template>\n <template v-if=\"slots.composerActions\" #composerActions>\n <slot name=\"composerActions\" />\n </template>\n <template v-if=\"slots.emojiPicker\" #emojiPicker=\"emojiProps\">\n <slot name=\"emojiPicker\" v-bind=\"emojiProps\" />\n </template>\n <template v-if=\"slots.attachmentPreview\" #attachmentPreview=\"attachmentProps\">\n <slot name=\"attachmentPreview\" v-bind=\"attachmentProps\" />\n </template>\n <template v-if=\"slots.templatePreview\" #templatePreview=\"templateProps\">\n <slot name=\"templatePreview\" v-bind=\"templateProps\" />\n </template>\n </WhatsAppComposer>\n </template>\n </Box>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n draftBehavior: 'preserve',\n withHeader: true,\n withComposer: true,\n withBack: false,\n withContactToggle: false,\n focusComposerOnChange: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch } from 'vue'\nimport { Box, Text, useProps, useStyles } from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport {\n provideWhatsAppConversationContext,\n useWhatsAppInboxConfig,\n} from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationSlots } from '../../component-props'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppAttachment, WhatsAppMessageData, WhatsAppOutgoingMessage } from '../../types'\nimport { resolveCapabilities } from '../../utils'\nimport { WhatsAppComposer } from '../WhatsAppComposer'\nimport type { WhatsAppComposerExposed } from '../WhatsAppComposer'\nimport { WhatsAppConversationHeader } from '../WhatsAppConversationHeader'\nimport { WhatsAppMessageList } from '../WhatsAppMessageList'\nimport type { WhatsAppMessageListExposed } from '../WhatsAppMessageList'\nimport type {\n WhatsAppConversationEmits,\n WhatsAppConversationOwnProps,\n} from './WhatsAppConversation.types'\nimport classes from './WhatsAppConversation.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversation',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationOwnProps>(), {\n conversation: undefined,\n conversationId: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n drafts: undefined,\n defaultDrafts: undefined,\n draftBehavior: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n withBack: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationEmits>()\ndefineSlots<WhatsAppConversationSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversation', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversation',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationRoot',\n})\n\nconst conversationId = computed(() => props.conversationId ?? props.conversation?.id)\n\nconst capabilities = computed(() =>\n resolveCapabilities(props.capabilities ?? props.conversation?.capabilities),\n)\n\n/**\n * Publishes the conversation to the primitives below, so a consumer can compose a custom layout\n * out of `WhatsAppMessageList` and `WhatsAppComposer` without threading capabilities through\n * every level. Getters keep the context reactive after a single `provide` in `setup`.\n */\nprovideWhatsAppConversationContext({\n get conversation() {\n return props.conversation\n },\n get conversationId() {\n return conversationId.value\n },\n get capabilities() {\n return capabilities.value\n },\n})\n\nconst composerRef = ref<WhatsAppComposerExposed | null>(null)\nconst messageListRef = ref<WhatsAppMessageListExposed | null>(null)\n\nfunction focusComposer() {\n composerRef.value?.focus()\n}\n\nfunction scrollToBottom(behavior: ScrollBehavior = 'auto') {\n messageListRef.value?.scrollToBottom(behavior)\n}\n\n/**\n * Unsent drafts, one per conversation.\n *\n * Drafts are preserved by default. `draftBehavior: 'reset'` opts out, and a controlled `draft`\n * bypasses the map for single-conversation layouts.\n */\nconst [draftMap, setDraftMap] = useUncontrolled<Record<string, string>>({\n value: () => props.drafts,\n defaultValue: props.defaultDrafts,\n finalValue: {},\n onChange: (value) => emit('update:drafts', value),\n})\n\nconst singleDraft = computed(() => props.draft !== undefined)\n\nconst composerDraft = computed(() =>\n singleDraft.value ? props.draft : (draftMap.value[conversationId.value ?? ''] ?? ''),\n)\n\n/** Drops the draft of the conversation that was just sent from, so the input starts clean. */\nfunction clearDraft(id: string | undefined) {\n if (singleDraft.value || !id || draftMap.value[id] === undefined) {\n return\n }\n\n const { [id]: _sent, ...rest } = draftMap.value\n\n setDraftMap(rest)\n}\n\nfunction setComposerDraft(value: string) {\n emit('update:draft', value)\n\n const id = conversationId.value\n\n if (singleDraft.value || !id) {\n return\n }\n\n // An empty draft is dropped rather than stored, so a persisted map never fills up with\n // entries for conversations the user only visited.\n if (value.length === 0) {\n clearDraft(id)\n return\n }\n\n setDraftMap({ ...draftMap.value, [id]: value })\n}\n\n// Focus the composer after switching conversations.\nwatch(conversationId, (next, previous) => {\n if (props.draftBehavior === 'reset') {\n clearDraft(previous)\n }\n\n if (next && props.focusComposerOnChange) {\n void nextTick(focusComposer)\n }\n})\n\nconst hasConversation = computed(() => Boolean(conversationId.value))\n\n// Multi-argument emits need a real handler: a template expression only ever receives `$event`.\nfunction handleMediaDownload(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaDownload', attachment, message)\n}\n\nfunction handleMediaPreview(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaPreview', attachment, message)\n}\n\nfunction handleSend(payload: WhatsAppOutgoingMessage) {\n // The composer resets its own input on send; the stored draft has to follow.\n clearDraft(conversationId.value)\n emit('send', payload)\n}\n\ndefineExpose({ focusComposer, scrollToBottom })\n</script>\n\n<template>\n <Box\n v-bind=\"{ ...attrs, ...getStyles('conversationRoot') }\"\n :data-conversation-id=\"conversationId\"\n >\n <Box v-if=\"!hasConversation\" v-bind=\"getStyles('conversationState')\">\n <WhatsAppIcon name=\"message\" size=\"44\" :style=\"{ color: 'var(--mantine-color-dimmed)' }\" />\n <Text size=\"sm\" fw=\"500\">{{ config.labels.noConversationSelected }}</Text>\n <Text size=\"xs\" c=\"dimmed\">{{ config.labels.noConversationSelectedDescription }}</Text>\n </Box>\n\n <template v-else>\n <slot\n v-if=\"slots.conversationHeader\"\n name=\"conversationHeader\"\n :conversation=\"props.conversation\"\n />\n\n <WhatsAppConversationHeader\n v-else-if=\"props.withHeader\"\n v-bind=\"props.headerProps\"\n :conversation=\"props.conversation\"\n :with-back=\"props.withBack\"\n :with-contact-toggle=\"props.withContactToggle\"\n :contact-panel-opened=\"props.contactPanelOpened\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @back=\"emit('back')\"\n @toggle-contact-panel=\"emit('toggleContactPanel', $event)\"\n @contact-click=\"props.conversation && emit('contactClick', props.conversation)\"\n >\n <template v-if=\"slots.headerActions\" #headerActions=\"headerActionsProps\">\n <slot name=\"headerActions\" v-bind=\"headerActionsProps\" />\n </template>\n </WhatsAppConversationHeader>\n\n <WhatsAppMessageList\n ref=\"messageListRef\"\n v-bind=\"props.messageListProps\"\n :messages=\"props.messages\"\n :conversation-id=\"conversationId\"\n :loading=\"props.messagesLoading\"\n :error=\"props.messagesError\"\n :pagination=\"props.messagesPagination\"\n :labels=\"props.labels\"\n :render-message=\"props.renderMessage\"\n :render-message-content=\"props.renderMessageContent\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @load-older=\"emit('loadOlderMessages', $event)\"\n @retry-load=\"emit('retryLoadMessages')\"\n @retry-message=\"emit('retryMessage', $event)\"\n @media-download=\"handleMediaDownload\"\n @media-preview=\"handleMediaPreview\"\n @at-bottom-change=\"emit('atBottomChange', $event)\"\n >\n <template v-if=\"slots.message\" #message=\"messageProps\">\n <slot name=\"message\" v-bind=\"messageProps\" />\n </template>\n <template v-if=\"slots.messageContent\" #messageContent=\"messageContentProps\">\n <slot name=\"messageContent\" v-bind=\"messageContentProps\" />\n </template>\n <template v-if=\"slots.messageFooter\" #messageFooter=\"messageFooterProps\">\n <slot name=\"messageFooter\" v-bind=\"messageFooterProps\" />\n </template>\n <template v-if=\"slots.mediaAttachment\" #mediaAttachment=\"mediaProps\">\n <slot name=\"mediaAttachment\" v-bind=\"mediaProps\" />\n </template>\n <template v-if=\"slots.emptyConversation\" #emptyConversation>\n <slot name=\"emptyConversation\" />\n </template>\n <template v-if=\"slots.loadingMessages\" #loadingMessages>\n <slot name=\"loadingMessages\" />\n </template>\n <template v-if=\"slots.errorMessages\" #errorMessages=\"errorProps\">\n <slot name=\"errorMessages\" v-bind=\"errorProps\" />\n </template>\n </WhatsAppMessageList>\n\n <WhatsAppComposer\n v-if=\"props.withComposer\"\n ref=\"composerRef\"\n v-bind=\"props.composerProps\"\n :conversation-id=\"conversationId\"\n :model-value=\"composerDraft\"\n :capabilities=\"props.capabilities ?? props.conversation?.capabilities\"\n :uploads=\"props.uploads\"\n :templates=\"props.templates\"\n :templates-loading=\"props.templatesLoading\"\n :templates-error=\"props.templatesError\"\n :sending=\"props.sending\"\n :error=\"props.sendError\"\n :reply-to=\"props.replyTo\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @update:model-value=\"setComposerDraft($event)\"\n @update:reply-to=\"emit('update:replyTo', $event)\"\n @typing=\"emit('typing', $event)\"\n @send=\"handleSend\"\n @attachments-add=\"emit('attachmentsAdd', $event)\"\n @attachments-reject=\"emit('attachmentsReject', $event)\"\n @attachment-remove=\"emit('attachmentRemove', $event)\"\n @attachment-retry=\"emit('attachmentRetry', $event)\"\n @attachment-cancel=\"emit('attachmentCancel', $event)\"\n @validation-error=\"emit('validationError', $event)\"\n @retry-send=\"emit('retrySend')\"\n @templates-retry-load=\"emit('templatesRetryLoad')\"\n >\n <template v-if=\"slots.composerPrefix\" #composerPrefix>\n <slot name=\"composerPrefix\" />\n </template>\n <template v-if=\"slots.composerSuffix\" #composerSuffix>\n <slot name=\"composerSuffix\" />\n </template>\n <template v-if=\"slots.composerActions\" #composerActions>\n <slot name=\"composerActions\" />\n </template>\n <template v-if=\"slots.emojiPicker\" #emojiPicker=\"emojiProps\">\n <slot name=\"emojiPicker\" v-bind=\"emojiProps\" />\n </template>\n <template v-if=\"slots.attachmentPreview\" #attachmentPreview=\"attachmentProps\">\n <slot name=\"attachmentPreview\" v-bind=\"attachmentProps\" />\n </template>\n <template v-if=\"slots.templatePreview\" #templatePreview=\"templateProps\">\n <slot name=\"templatePreview\" v-bind=\"templateProps\" />\n </template>\n </WhatsAppComposer>\n </template>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppConversationComponent from './WhatsAppConversation.vue'\nimport type { WhatsAppConversationFactory } from './WhatsAppConversation.types'\nimport classes from './WhatsAppConversation.module.css'\n\nexport const WhatsAppConversation = factory<WhatsAppConversationFactory>(\n WhatsAppConversationComponent,\n { classes },\n)\n\nexport type {\n WhatsAppConversationEmits,\n WhatsAppConversationExposed,\n WhatsAppConversationFactory,\n WhatsAppConversationOwnProps,\n WhatsAppConversationProps,\n WhatsAppConversationStylesNames,\n} from './WhatsAppConversation.types'\n",".conversationItemRoot {\n display: flex;\n align-items: flex-start;\n gap: var(--mantine-spacing-sm);\n width: 100%;\n padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);\n text-align: start;\n border-radius: var(--mantine-radius-sm);\n}\n\n.conversationItemRoot {\n @mixin hover {\n background-color: var(--mantine-color-default-hover);\n }\n}\n\n.conversationItemRoot:where([data-selected]) {\n background-color: var(--mantine-color-default-hover);\n}\n\n.conversationItemRoot:where([data-unread]) .conversationItemName {\n font-weight: 700;\n}\n\n.conversationItemAvatar {\n flex-shrink: 0;\n}\n\n.conversationItemBody {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.conversationItemTopRow {\n display: flex;\n align-items: baseline;\n gap: var(--mantine-spacing-xs);\n}\n\n.conversationItemName {\n flex: 1;\n min-width: 0;\n font-size: var(--mantine-font-size-sm);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.conversationItemTime {\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mantine-color-dimmed);\n}\n\n.conversationItemRoot:where([data-unread]) .conversationItemTime {\n color: var(--mantine-primary-color-filled);\n}\n\n.conversationItemPhone {\n font-size: 11px;\n color: var(--mantine-color-dimmed);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.conversationItemBottomRow {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n}\n\n.conversationItemPreview {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.conversationItemPreviewText {\n min-width: 0;\n font-size: var(--mantine-font-size-xs);\n color: var(--mantine-color-dimmed);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.conversationItemIndicators {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n color: var(--mantine-color-dimmed);\n}\n\n.conversationItemUnread {\n flex-shrink: 0;\n}\n\n.conversationItemLabels {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n selected: false,\n withUnreadBadge: true,\n withStatus: true,\n withPhoneNumber: true,\n withLabels: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Avatar, Badge, Box, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { getContactDisplayName, getConversationPreviewText } from '../../utils'\nimport { WhatsAppMessageStatus } from '../WhatsAppMessageStatus'\nimport type {\n WhatsAppConversationListItemEmits,\n WhatsAppConversationListItemOwnProps,\n WhatsAppConversationListItemSlots,\n} from './WhatsAppConversationListItem.types'\nimport classes from './WhatsAppConversationListItem.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversationListItem',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationListItemOwnProps>(), {\n selected: undefined,\n withUnreadBadge: undefined,\n withStatus: undefined,\n withPhoneNumber: undefined,\n withLabels: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationListItemEmits>()\ndefineSlots<WhatsAppConversationListItemSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversationListItem', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversationListItem',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationItemRoot',\n})\n\nconst conversation = computed(() => props.conversation)\nconst slotProps = computed(() => ({\n conversation: conversation.value,\n selected: Boolean(props.selected),\n}))\n\nconst displayName = computed(() => getContactDisplayName(conversation.value))\nconst unreadCount = computed(() => conversation.value.unreadCount ?? 0)\nconst isUnread = computed(() => unreadCount.value > 0)\n\nconst timestamp = computed(\n () => conversation.value.lastMessage?.timestamp ?? conversation.value.updatedAt,\n)\nconst timeLabel = computed(() => config.conversationTime(timestamp.value))\n\nconst previewText = computed(() =>\n getConversationPreviewText(conversation.value.lastMessage, config.labels),\n)\n\nconst previewStatus = computed(() =>\n props.withStatus && conversation.value.lastMessage?.direction === 'outbound'\n ? conversation.value.lastMessage.status\n : undefined,\n)\n\n/**\n * One accessible name for the whole row. Without it a screen reader would read the name, the\n * time and the preview as three unrelated fragments and never mention the unread count, which\n * is the part that decides whether the row is worth opening.\n */\nconst accessibleName = computed(() => {\n const parts = [config.labels.conversationItemLabel(displayName.value)]\n\n if (isUnread.value) {\n parts.push(config.labels.unreadCountLabel(unreadCount.value))\n }\n\n if (previewText.value) {\n parts.push(previewText.value)\n }\n\n if (timeLabel.value) {\n parts.push(timeLabel.value)\n }\n\n return parts.join('. ')\n})\n</script>\n\n<template>\n <UnstyledButton\n v-bind=\"{ ...attrs, ...getStyles('conversationItemRoot') }\"\n type=\"button\"\n :aria-current=\"props.selected ? true : undefined\"\n :aria-label=\"accessibleName\"\n :data-selected=\"props.selected ? '' : undefined\"\n :data-unread=\"isUnread ? '' : undefined\"\n :data-conversation-id=\"conversation.id\"\n @click=\"emit('select', conversation)\"\n >\n <slot v-if=\"slots.conversationAvatar\" name=\"conversationAvatar\" v-bind=\"slotProps\" />\n <Avatar\n v-else\n v-bind=\"getStyles('conversationItemAvatar')\"\n :src=\"conversation.contact.avatarUrl\"\n :name=\"displayName\"\n color=\"initials\"\n radius=\"xl\"\n size=\"md\"\n aria-hidden=\"true\"\n />\n\n <Box v-bind=\"getStyles('conversationItemBody')\" aria-hidden=\"true\">\n <Box v-bind=\"getStyles('conversationItemTopRow')\">\n <Box v-bind=\"getStyles('conversationItemName')\">{{ displayName }}</Box>\n <Box v-if=\"timeLabel\" v-bind=\"getStyles('conversationItemTime')\">{{ timeLabel }}</Box>\n </Box>\n\n <Box\n v-if=\"\n props.withPhoneNumber && conversation.contact.phoneNumber && conversation.contact.name\n \"\n v-bind=\"getStyles('conversationItemPhone')\"\n >\n {{ conversation.contact.phoneNumber }}\n </Box>\n\n <Box v-bind=\"getStyles('conversationItemBottomRow')\">\n <slot v-if=\"slots.conversationPreview\" name=\"conversationPreview\" v-bind=\"slotProps\" />\n\n <Box v-else v-bind=\"getStyles('conversationItemPreview')\">\n <WhatsAppMessageStatus\n v-if=\"previewStatus\"\n :status=\"previewStatus\"\n :labels=\"props.labels\"\n />\n <Box v-bind=\"getStyles('conversationItemPreviewText')\">{{ previewText }}</Box>\n </Box>\n\n <Box\n v-if=\"conversation.muted || conversation.pinned\"\n v-bind=\"getStyles('conversationItemIndicators')\"\n >\n <WhatsAppIcon v-if=\"conversation.pinned\" name=\"pin\" size=\"14\" />\n <WhatsAppIcon v-if=\"conversation.muted\" name=\"mute\" size=\"14\" />\n </Box>\n\n <Badge\n v-if=\"props.withUnreadBadge && isUnread\"\n v-bind=\"getStyles('conversationItemUnread')\"\n size=\"sm\"\n circle\n >\n {{ unreadCount }}\n </Badge>\n </Box>\n\n <Box\n v-if=\"props.withLabels && conversation.labels?.length\"\n v-bind=\"getStyles('conversationItemLabels')\"\n >\n <Badge\n v-for=\"label in conversation.labels\"\n :key=\"label.id\"\n size=\"xs\"\n variant=\"light\"\n :color=\"label.color\"\n >\n {{ label.name }}\n </Badge>\n </Box>\n </Box>\n </UnstyledButton>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n selected: false,\n withUnreadBadge: true,\n withStatus: true,\n withPhoneNumber: true,\n withLabels: true,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue'\nimport { Avatar, Badge, Box, UnstyledButton, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport { WhatsAppIcon } from '../../icons'\nimport { getContactDisplayName, getConversationPreviewText } from '../../utils'\nimport { WhatsAppMessageStatus } from '../WhatsAppMessageStatus'\nimport type {\n WhatsAppConversationListItemEmits,\n WhatsAppConversationListItemOwnProps,\n WhatsAppConversationListItemSlots,\n} from './WhatsAppConversationListItem.types'\nimport classes from './WhatsAppConversationListItem.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversationListItem',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationListItemOwnProps>(), {\n selected: undefined,\n withUnreadBadge: undefined,\n withStatus: undefined,\n withPhoneNumber: undefined,\n withLabels: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationListItemEmits>()\ndefineSlots<WhatsAppConversationListItemSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversationListItem', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversationListItem',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationItemRoot',\n})\n\nconst conversation = computed(() => props.conversation)\nconst slotProps = computed(() => ({\n conversation: conversation.value,\n selected: Boolean(props.selected),\n}))\n\nconst displayName = computed(() => getContactDisplayName(conversation.value))\nconst unreadCount = computed(() => conversation.value.unreadCount ?? 0)\nconst isUnread = computed(() => unreadCount.value > 0)\n\nconst timestamp = computed(\n () => conversation.value.lastMessage?.timestamp ?? conversation.value.updatedAt,\n)\nconst timeLabel = computed(() => config.conversationTime(timestamp.value))\n\nconst previewText = computed(() =>\n getConversationPreviewText(conversation.value.lastMessage, config.labels),\n)\n\nconst previewStatus = computed(() =>\n props.withStatus && conversation.value.lastMessage?.direction === 'outbound'\n ? conversation.value.lastMessage.status\n : undefined,\n)\n\n/**\n * One accessible name for the whole row. Without it a screen reader would read the name, the\n * time and the preview as three unrelated fragments and never mention the unread count, which\n * is the part that decides whether the row is worth opening.\n */\nconst accessibleName = computed(() => {\n const parts = [config.labels.conversationItemLabel(displayName.value)]\n\n if (isUnread.value) {\n parts.push(config.labels.unreadCountLabel(unreadCount.value))\n }\n\n if (previewText.value) {\n parts.push(previewText.value)\n }\n\n if (timeLabel.value) {\n parts.push(timeLabel.value)\n }\n\n return parts.join('. ')\n})\n</script>\n\n<template>\n <UnstyledButton\n v-bind=\"{ ...attrs, ...getStyles('conversationItemRoot') }\"\n type=\"button\"\n :aria-current=\"props.selected ? true : undefined\"\n :aria-label=\"accessibleName\"\n :data-selected=\"props.selected ? '' : undefined\"\n :data-unread=\"isUnread ? '' : undefined\"\n :data-conversation-id=\"conversation.id\"\n @click=\"emit('select', conversation)\"\n >\n <slot v-if=\"slots.conversationAvatar\" name=\"conversationAvatar\" v-bind=\"slotProps\" />\n <Avatar\n v-else\n v-bind=\"getStyles('conversationItemAvatar')\"\n :src=\"conversation.contact.avatarUrl\"\n :name=\"displayName\"\n color=\"initials\"\n radius=\"xl\"\n size=\"md\"\n aria-hidden=\"true\"\n />\n\n <Box v-bind=\"getStyles('conversationItemBody')\" aria-hidden=\"true\">\n <Box v-bind=\"getStyles('conversationItemTopRow')\">\n <Box v-bind=\"getStyles('conversationItemName')\">{{ displayName }}</Box>\n <Box v-if=\"timeLabel\" v-bind=\"getStyles('conversationItemTime')\">{{ timeLabel }}</Box>\n </Box>\n\n <Box\n v-if=\"\n props.withPhoneNumber && conversation.contact.phoneNumber && conversation.contact.name\n \"\n v-bind=\"getStyles('conversationItemPhone')\"\n >\n {{ conversation.contact.phoneNumber }}\n </Box>\n\n <Box v-bind=\"getStyles('conversationItemBottomRow')\">\n <slot v-if=\"slots.conversationPreview\" name=\"conversationPreview\" v-bind=\"slotProps\" />\n\n <Box v-else v-bind=\"getStyles('conversationItemPreview')\">\n <WhatsAppMessageStatus\n v-if=\"previewStatus\"\n :status=\"previewStatus\"\n :labels=\"props.labels\"\n />\n <Box v-bind=\"getStyles('conversationItemPreviewText')\">{{ previewText }}</Box>\n </Box>\n\n <Box\n v-if=\"conversation.muted || conversation.pinned\"\n v-bind=\"getStyles('conversationItemIndicators')\"\n >\n <WhatsAppIcon v-if=\"conversation.pinned\" name=\"pin\" size=\"14\" />\n <WhatsAppIcon v-if=\"conversation.muted\" name=\"mute\" size=\"14\" />\n </Box>\n\n <Badge\n v-if=\"props.withUnreadBadge && isUnread\"\n v-bind=\"getStyles('conversationItemUnread')\"\n size=\"sm\"\n circle\n >\n {{ unreadCount }}\n </Badge>\n </Box>\n\n <Box\n v-if=\"props.withLabels && conversation.labels?.length\"\n v-bind=\"getStyles('conversationItemLabels')\"\n >\n <Badge\n v-for=\"label in conversation.labels\"\n :key=\"label.id\"\n size=\"xs\"\n variant=\"light\"\n :color=\"label.color\"\n >\n {{ label.name }}\n </Badge>\n </Box>\n </Box>\n </UnstyledButton>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppConversationListItemComponent from './WhatsAppConversationListItem.vue'\nimport type { WhatsAppConversationListItemFactory } from './WhatsAppConversationListItem.types'\nimport classes from './WhatsAppConversationListItem.module.css'\n\nexport const WhatsAppConversationListItem = factory<WhatsAppConversationListItemFactory>(\n WhatsAppConversationListItemComponent,\n { classes },\n)\n\nexport type {\n WhatsAppConversationListItemEmits,\n WhatsAppConversationListItemFactory,\n WhatsAppConversationListItemOwnProps,\n WhatsAppConversationListItemProps,\n WhatsAppConversationListItemSlots,\n WhatsAppConversationListItemStylesNames,\n} from './WhatsAppConversationListItem.types'\n",".conversationListRoot {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n background-color: var(--mantine-color-body);\n}\n\n.conversationListHeader {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-sm);\n border-bottom: 1px solid var(--mantine-color-default-border);\n}\n\n.conversationListTitleRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mantine-spacing-xs);\n min-height: 28px;\n}\n\n.conversationListTitle {\n font-size: var(--mantine-font-size-lg);\n font-weight: 700;\n}\n\n.conversationListNewButton {\n flex-shrink: 0;\n}\n\n.newConversationForm {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-sm);\n}\n\n.newConversationActions {\n display: flex;\n justify-content: flex-end;\n gap: var(--mantine-spacing-xs);\n}\n\n.conversationListSearch {\n width: 100%;\n}\n\n.conversationListFilters {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n flex-wrap: wrap;\n}\n\n.conversationListScrollArea {\n flex: 1;\n min-height: 0;\n}\n\n.conversationListItems {\n display: flex;\n flex-direction: column;\n gap: 2px;\n list-style: none;\n margin: 0;\n padding: var(--mantine-spacing-xs);\n}\n\n.conversationListItemWrapper {\n display: block;\n}\n\n.conversationListState {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mantine-spacing-sm);\n padding: var(--mantine-spacing-xl) var(--mantine-spacing-md);\n text-align: center;\n}\n\n.conversationListLoadMore {\n display: flex;\n justify-content: center;\n padding: var(--mantine-spacing-xs);\n}\n\n.conversationListFooter {\n border-top: 1px solid var(--mantine-color-default-border);\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n order: 'none',\n withHeader: true,\n withInfiniteScroll: true,\n withNewConversation: false,\n loadMoreThreshold: 160,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, useSlots } from 'vue'\nimport {\n ActionIcon,\n Alert,\n Box,\n Button,\n Center,\n Group,\n Loader,\n Modal,\n ScrollArea,\n Select,\n Switch,\n Text,\n TextInput,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationListSlots } from '../../component-props'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppConversationSummary, WhatsAppInboxFilters } from '../../types'\nimport { isValidPhoneNumber, normalizePhoneNumber, sortConversationsByActivity } from '../../utils'\nimport { WhatsAppConversationListItem } from '../WhatsAppConversationListItem'\nimport type {\n WhatsAppConversationListEmits,\n WhatsAppConversationListOwnProps,\n} from './WhatsAppConversationList.types'\nimport classes from './WhatsAppConversationList.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversationList',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationListOwnProps>(), {\n conversations: undefined,\n selectedConversationId: undefined,\n defaultSelectedConversationId: undefined,\n filters: undefined,\n defaultFilters: undefined,\n filtersConfig: undefined,\n loading: undefined,\n error: undefined,\n pagination: undefined,\n order: undefined,\n withHeader: undefined,\n withInfiniteScroll: undefined,\n loadMoreThreshold: undefined,\n title: undefined,\n withNewConversation: undefined,\n newConversationOpened: undefined,\n newConversationCreating: undefined,\n newConversationError: undefined,\n validatePhoneNumber: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationListEmits>()\ndefineSlots<WhatsAppConversationListSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversationList', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversationList',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationListRoot',\n})\n\nconst [selectedId, setSelectedId] = useUncontrolled<string | null>({\n value: () => props.selectedConversationId,\n defaultValue: props.defaultSelectedConversationId,\n finalValue: null,\n onChange: (value) => emit('update:selectedConversationId', value),\n})\n\nconst [filters, setFilters] = useUncontrolled<WhatsAppInboxFilters>({\n value: () => props.filters,\n defaultValue: props.defaultFilters,\n finalValue: {},\n onChange: (value) => emit('update:filters', value),\n})\n\nfunction patchFilters(partial: WhatsAppInboxFilters) {\n setFilters({ ...filters.value, ...partial })\n}\n\nconst filtersConfig = computed(() => props.filtersConfig ?? {})\nconst withSearch = computed(() => filtersConfig.value.search ?? true)\nconst withUnread = computed(() => filtersConfig.value.unread ?? true)\nconst assigneeOptions = computed(() =>\n filtersConfig.value.assignees\n ? [\n { value: '', label: config.labels.unassigned },\n ...filtersConfig.value.assignees.map((assignee) => ({\n value: assignee.id,\n label: assignee.name,\n })),\n ]\n : undefined,\n)\nconst statusOptions = computed(() => filtersConfig.value.statuses)\n\nconst conversations = computed(() => {\n const list = props.conversations ?? []\n\n return props.order === 'activity' ? sortConversationsByActivity(list) : list\n})\n\nconst hasConversations = computed(() => conversations.value.length > 0)\nconst showLoading = computed(() => Boolean(props.loading) && !hasConversations.value)\nconst showError = computed(() => Boolean(props.error) && !hasConversations.value)\n\n/** A filtered-empty list gets different copy than a genuinely empty inbox. */\nconst hasActiveFilters = computed(() => {\n const current = filters.value\n\n return Boolean(\n current.query ||\n current.unreadOnly ||\n current.status ||\n current.assigneeId !== undefined ||\n current.labels?.length,\n )\n})\n\nconst showEmpty = computed(() => !showLoading.value && !showError.value && !hasConversations.value)\n\nconst canLoadMore = computed(\n () => Boolean(props.pagination?.hasMore) && !props.pagination?.loadingMore,\n)\n\n/** Guards against a burst of scroll events queueing several identical page requests. */\nconst loadMoreRequested = ref(false)\n\nfunction requestMore() {\n if (!canLoadMore.value || loadMoreRequested.value) {\n return\n }\n\n loadMoreRequested.value = true\n emit('loadMore', { cursor: props.pagination?.cursor })\n}\n\nfunction handleScroll(position: { x: number; y: number }) {\n if (!props.withInfiniteScroll) {\n return\n }\n\n const viewport = scrollRoot.value?.querySelector<HTMLElement>(\n '[data-whatsapp-conversation-viewport]',\n )\n\n if (!viewport) {\n return\n }\n\n const distance = viewport.scrollHeight - position.y - viewport.clientHeight\n\n if (distance <= (props.loadMoreThreshold ?? defaultProps.loadMoreThreshold)) {\n requestMore()\n } else {\n loadMoreRequested.value = false\n }\n}\n\nconst scrollRoot = ref<HTMLElement | null>(null)\n\nconst setScrollRoot = (node: Element | null) => {\n scrollRoot.value = node as HTMLElement | null\n}\n\nconst viewportProps = { 'data-whatsapp-conversation-viewport': '' }\n\nconst [newConversationOpened, setNewConversationOpened] = useUncontrolled<boolean>({\n value: () => props.newConversationOpened,\n finalValue: false,\n onChange: (value) => emit('update:newConversationOpened', value),\n})\n\nconst newPhoneNumber = ref('')\nconst newName = ref('')\nconst newPhoneError = ref<string | null>(null)\n\nfunction openNewConversation() {\n newPhoneNumber.value = ''\n newName.value = ''\n newPhoneError.value = null\n setNewConversationOpened(true)\n}\n\nfunction submitNewConversation() {\n const phoneNumber = newPhoneNumber.value.trim()\n\n const error = props.validatePhoneNumber\n ? props.validatePhoneNumber(phoneNumber)\n : isValidPhoneNumber(phoneNumber)\n ? null\n : config.labels.newConversationInvalidPhone\n\n newPhoneError.value = error\n\n if (error) {\n return\n }\n\n emit('newConversation', {\n phoneNumber,\n normalizedPhoneNumber: normalizePhoneNumber(phoneNumber),\n name: newName.value.trim() || undefined,\n })\n}\n\nfunction select(conversation: WhatsAppConversationSummary) {\n setSelectedId(conversation.id)\n emit('select', conversation)\n}\n</script>\n\n<template>\n <Box :root-ref=\"setScrollRoot\" v-bind=\"{ ...attrs, ...getStyles('conversationListRoot') }\">\n <Box v-if=\"props.withHeader\" v-bind=\"getStyles('conversationListHeader')\">\n <slot name=\"listHeader\" />\n\n <Box v-bind=\"getStyles('conversationListTitleRow')\">\n <Box v-bind=\"getStyles('conversationListTitle')\">\n {{ props.title ?? config.labels.conversationsLabel }}\n </Box>\n\n <ActionIcon\n v-if=\"props.withNewConversation\"\n v-bind=\"getStyles('conversationListNewButton')\"\n variant=\"subtle\"\n color=\"gray\"\n :aria-label=\"config.labels.newConversation\"\n @click=\"openNewConversation\"\n >\n <WhatsAppIcon name=\"plus\" size=\"20\" />\n </ActionIcon>\n </Box>\n\n <TextInput\n v-if=\"withSearch\"\n v-bind=\"getStyles('conversationListSearch')\"\n size=\"sm\"\n type=\"search\"\n :model-value=\"filters.query ?? ''\"\n :placeholder=\"config.labels.searchPlaceholder\"\n :aria-label=\"config.labels.searchLabel\"\n @update:model-value=\"patchFilters({ query: $event })\"\n >\n <template #leftSection>\n <WhatsAppIcon name=\"search\" size=\"16\" />\n </template>\n </TextInput>\n\n <Box\n v-if=\"withUnread || assigneeOptions || statusOptions || slots.filters\"\n v-bind=\"getStyles('conversationListFilters')\"\n >\n <Switch\n v-if=\"withUnread\"\n size=\"xs\"\n :label=\"config.labels.unreadFilterLabel\"\n :model-value=\"filters.unreadOnly ?? false\"\n @update:model-value=\"patchFilters({ unreadOnly: $event })\"\n />\n\n <Select\n v-if=\"statusOptions\"\n size=\"xs\"\n clearable\n :data=\"statusOptions\"\n :placeholder=\"config.labels.statusFilterPlaceholder\"\n :aria-label=\"config.labels.statusFilterLabel\"\n :model-value=\"filters.status ?? null\"\n @update:model-value=\"patchFilters({ status: $event })\"\n />\n\n <Select\n v-if=\"assigneeOptions\"\n size=\"xs\"\n clearable\n :data=\"assigneeOptions\"\n :placeholder=\"config.labels.assigneeFilterPlaceholder\"\n :aria-label=\"config.labels.assigneeFilterLabel\"\n :model-value=\"filters.assigneeId === null ? '' : (filters.assigneeId ?? null)\"\n @update:model-value=\"patchFilters({ assigneeId: $event === '' ? null : $event })\"\n />\n\n <slot name=\"filters\" />\n </Box>\n </Box>\n\n <Center v-if=\"showLoading\" v-bind=\"getStyles('conversationListState')\">\n <slot v-if=\"slots.loadingInbox\" name=\"loadingInbox\" />\n <template v-else>\n <Loader size=\"sm\" />\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.loadingConversations }}</Text>\n </template>\n </Center>\n\n <Box v-else-if=\"showError\" v-bind=\"getStyles('conversationListState')\">\n <slot v-if=\"slots.errorInbox\" name=\"errorInbox\" :error=\"props.error ?? ''\" />\n <Alert v-else color=\"red\" variant=\"light\" :title=\"config.labels.conversationsError\">\n <Text size=\"sm\">{{ props.error }}</Text>\n <Button mt=\"sm\" size=\"xs\" variant=\"light\" color=\"red\" @click=\"emit('retryLoad')\">\n {{ config.labels.retry }}\n </Button>\n </Alert>\n </Box>\n\n <Box v-else-if=\"showEmpty\" v-bind=\"getStyles('conversationListState')\">\n <slot v-if=\"slots.emptyInbox\" name=\"emptyInbox\" />\n <template v-else>\n <WhatsAppIcon name=\"inbox\" size=\"40\" :style=\"{ color: 'var(--mantine-color-dimmed)' }\" />\n <Text size=\"sm\" c=\"dimmed\">\n {{ hasActiveFilters ? config.labels.emptySearch : config.labels.emptyInbox }}\n </Text>\n <Button v-if=\"hasActiveFilters\" size=\"xs\" variant=\"subtle\" @click=\"setFilters({})\">\n {{ config.labels.clearFilters }}\n </Button>\n </template>\n </Box>\n\n <ScrollArea\n v-else\n v-bind=\"getStyles('conversationListScrollArea')\"\n type=\"auto\"\n scrollbars=\"y\"\n :viewport-props=\"viewportProps\"\n @scroll-position-change=\"handleScroll\"\n >\n <Box\n component=\"ul\"\n v-bind=\"getStyles('conversationListItems')\"\n :aria-label=\"config.labels.conversationsLabel\"\n >\n <Box\n v-for=\"conversation in conversations\"\n :key=\"conversation.id\"\n component=\"li\"\n v-bind=\"getStyles('conversationListItemWrapper')\"\n >\n <slot\n v-if=\"slots.conversationItem\"\n name=\"conversationItem\"\n :conversation=\"conversation\"\n :selected=\"conversation.id === selectedId\"\n />\n\n <WhatsAppConversationListItem\n v-else\n :conversation=\"conversation\"\n :selected=\"conversation.id === selectedId\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @select=\"select\"\n >\n <template v-if=\"slots.conversationAvatar\" #conversationAvatar=\"avatarProps\">\n <slot name=\"conversationAvatar\" v-bind=\"avatarProps\" />\n </template>\n <template v-if=\"slots.conversationPreview\" #conversationPreview=\"previewProps\">\n <slot name=\"conversationPreview\" v-bind=\"previewProps\" />\n </template>\n </WhatsAppConversationListItem>\n </Box>\n </Box>\n\n <Box\n v-if=\"canLoadMore || props.pagination?.loadingMore\"\n v-bind=\"getStyles('conversationListLoadMore')\"\n >\n <Group v-if=\"props.pagination?.loadingMore\" gap=\"xs\">\n <Loader size=\"xs\" />\n <Text size=\"xs\" c=\"dimmed\">{{ config.labels.loading }}</Text>\n </Group>\n <Button v-else size=\"xs\" variant=\"subtle\" @click=\"requestMore\">\n {{ config.labels.loadMoreConversations }}\n </Button>\n </Box>\n </ScrollArea>\n\n <Box v-if=\"slots.listFooter\" v-bind=\"getStyles('conversationListFooter')\">\n <slot name=\"listFooter\" />\n </Box>\n\n <Modal\n :opened=\"newConversationOpened\"\n :title=\"config.labels.newConversationTitle\"\n size=\"md\"\n @close=\"setNewConversationOpened(false)\"\n >\n <Box\n component=\"form\"\n v-bind=\"getStyles('newConversationForm')\"\n @submit.prevent=\"submitNewConversation\"\n >\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.newConversationDescription }}</Text>\n\n <TextInput\n v-model=\"newPhoneNumber\"\n type=\"tel\"\n required\n data-autofocus\n :label=\"config.labels.newConversationPhoneLabel\"\n :placeholder=\"config.labels.newConversationPhonePlaceholder\"\n :error=\"newPhoneError\"\n />\n\n <TextInput\n v-model=\"newName\"\n :label=\"config.labels.newConversationNameLabel\"\n :placeholder=\"config.labels.newConversationNamePlaceholder\"\n />\n\n <Alert v-if=\"props.newConversationError\" color=\"red\" variant=\"light\" role=\"alert\">\n {{ props.newConversationError }}\n </Alert>\n\n <Box v-bind=\"getStyles('newConversationActions')\">\n <Button variant=\"default\" @click=\"setNewConversationOpened(false)\">\n {{ config.labels.cancel }}\n </Button>\n <Button type=\"submit\" :loading=\"props.newConversationCreating\">\n {{ config.labels.newConversationSubmit }}\n </Button>\n </Box>\n </Box>\n </Modal>\n </Box>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n order: 'none',\n withHeader: true,\n withInfiniteScroll: true,\n withNewConversation: false,\n loadMoreThreshold: 160,\n} as const\n\nexport { defaultProps }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, useSlots } from 'vue'\nimport {\n ActionIcon,\n Alert,\n Box,\n Button,\n Center,\n Group,\n Loader,\n Modal,\n ScrollArea,\n Select,\n Switch,\n Text,\n TextInput,\n useProps,\n useStyles,\n} from '@mantine-vue/core'\nimport { useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationListSlots } from '../../component-props'\nimport { WhatsAppIcon } from '../../icons'\nimport type { WhatsAppConversationSummary, WhatsAppInboxFilters } from '../../types'\nimport { isValidPhoneNumber, normalizePhoneNumber, sortConversationsByActivity } from '../../utils'\nimport { WhatsAppConversationListItem } from '../WhatsAppConversationListItem'\nimport type {\n WhatsAppConversationListEmits,\n WhatsAppConversationListOwnProps,\n} from './WhatsAppConversationList.types'\nimport classes from './WhatsAppConversationList.module.css'\n\ndefineOptions({\n name: 'WhatsAppConversationList',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppConversationListOwnProps>(), {\n conversations: undefined,\n selectedConversationId: undefined,\n defaultSelectedConversationId: undefined,\n filters: undefined,\n defaultFilters: undefined,\n filtersConfig: undefined,\n loading: undefined,\n error: undefined,\n pagination: undefined,\n order: undefined,\n withHeader: undefined,\n withInfiniteScroll: undefined,\n loadMoreThreshold: undefined,\n title: undefined,\n withNewConversation: undefined,\n newConversationOpened: undefined,\n newConversationCreating: undefined,\n newConversationError: undefined,\n validatePhoneNumber: undefined,\n labels: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppConversationListEmits>()\ndefineSlots<WhatsAppConversationListSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppConversationList', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppConversationList',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'conversationListRoot',\n})\n\nconst [selectedId, setSelectedId] = useUncontrolled<string | null>({\n value: () => props.selectedConversationId,\n defaultValue: props.defaultSelectedConversationId,\n finalValue: null,\n onChange: (value) => emit('update:selectedConversationId', value),\n})\n\nconst [filters, setFilters] = useUncontrolled<WhatsAppInboxFilters>({\n value: () => props.filters,\n defaultValue: props.defaultFilters,\n finalValue: {},\n onChange: (value) => emit('update:filters', value),\n})\n\nfunction patchFilters(partial: WhatsAppInboxFilters) {\n setFilters({ ...filters.value, ...partial })\n}\n\nconst filtersConfig = computed(() => props.filtersConfig ?? {})\nconst withSearch = computed(() => filtersConfig.value.search ?? true)\nconst withUnread = computed(() => filtersConfig.value.unread ?? true)\nconst assigneeOptions = computed(() =>\n filtersConfig.value.assignees\n ? [\n { value: '', label: config.labels.unassigned },\n ...filtersConfig.value.assignees.map((assignee) => ({\n value: assignee.id,\n label: assignee.name,\n })),\n ]\n : undefined,\n)\nconst statusOptions = computed(() => filtersConfig.value.statuses)\n\nconst conversations = computed(() => {\n const list = props.conversations ?? []\n\n return props.order === 'activity' ? sortConversationsByActivity(list) : list\n})\n\nconst hasConversations = computed(() => conversations.value.length > 0)\nconst showLoading = computed(() => Boolean(props.loading) && !hasConversations.value)\nconst showError = computed(() => Boolean(props.error) && !hasConversations.value)\n\n/** A filtered-empty list gets different copy than a genuinely empty inbox. */\nconst hasActiveFilters = computed(() => {\n const current = filters.value\n\n return Boolean(\n current.query ||\n current.unreadOnly ||\n current.status ||\n current.assigneeId !== undefined ||\n current.labels?.length,\n )\n})\n\nconst showEmpty = computed(() => !showLoading.value && !showError.value && !hasConversations.value)\n\nconst canLoadMore = computed(\n () => Boolean(props.pagination?.hasMore) && !props.pagination?.loadingMore,\n)\n\n/** Guards against a burst of scroll events queueing several identical page requests. */\nconst loadMoreRequested = ref(false)\n\nfunction requestMore() {\n if (!canLoadMore.value || loadMoreRequested.value) {\n return\n }\n\n loadMoreRequested.value = true\n emit('loadMore', { cursor: props.pagination?.cursor })\n}\n\nfunction handleScroll(position: { x: number; y: number }) {\n if (!props.withInfiniteScroll) {\n return\n }\n\n const viewport = scrollRoot.value?.querySelector<HTMLElement>(\n '[data-whatsapp-conversation-viewport]',\n )\n\n if (!viewport) {\n return\n }\n\n const distance = viewport.scrollHeight - position.y - viewport.clientHeight\n\n if (distance <= (props.loadMoreThreshold ?? defaultProps.loadMoreThreshold)) {\n requestMore()\n } else {\n loadMoreRequested.value = false\n }\n}\n\nconst scrollRoot = ref<HTMLElement | null>(null)\n\nconst setScrollRoot = (node: Element | null) => {\n scrollRoot.value = node as HTMLElement | null\n}\n\nconst viewportProps = { 'data-whatsapp-conversation-viewport': '' }\n\nconst [newConversationOpened, setNewConversationOpened] = useUncontrolled<boolean>({\n value: () => props.newConversationOpened,\n finalValue: false,\n onChange: (value) => emit('update:newConversationOpened', value),\n})\n\nconst newPhoneNumber = ref('')\nconst newName = ref('')\nconst newPhoneError = ref<string | null>(null)\n\nfunction openNewConversation() {\n newPhoneNumber.value = ''\n newName.value = ''\n newPhoneError.value = null\n setNewConversationOpened(true)\n}\n\nfunction submitNewConversation() {\n const phoneNumber = newPhoneNumber.value.trim()\n\n const error = props.validatePhoneNumber\n ? props.validatePhoneNumber(phoneNumber)\n : isValidPhoneNumber(phoneNumber)\n ? null\n : config.labels.newConversationInvalidPhone\n\n newPhoneError.value = error\n\n if (error) {\n return\n }\n\n emit('newConversation', {\n phoneNumber,\n normalizedPhoneNumber: normalizePhoneNumber(phoneNumber),\n name: newName.value.trim() || undefined,\n })\n}\n\nfunction select(conversation: WhatsAppConversationSummary) {\n setSelectedId(conversation.id)\n emit('select', conversation)\n}\n</script>\n\n<template>\n <Box :root-ref=\"setScrollRoot\" v-bind=\"{ ...attrs, ...getStyles('conversationListRoot') }\">\n <Box v-if=\"props.withHeader\" v-bind=\"getStyles('conversationListHeader')\">\n <slot name=\"listHeader\" />\n\n <Box v-bind=\"getStyles('conversationListTitleRow')\">\n <Box v-bind=\"getStyles('conversationListTitle')\">\n {{ props.title ?? config.labels.conversationsLabel }}\n </Box>\n\n <ActionIcon\n v-if=\"props.withNewConversation\"\n v-bind=\"getStyles('conversationListNewButton')\"\n variant=\"subtle\"\n color=\"gray\"\n :aria-label=\"config.labels.newConversation\"\n @click=\"openNewConversation\"\n >\n <WhatsAppIcon name=\"plus\" size=\"20\" />\n </ActionIcon>\n </Box>\n\n <TextInput\n v-if=\"withSearch\"\n v-bind=\"getStyles('conversationListSearch')\"\n size=\"sm\"\n type=\"search\"\n :model-value=\"filters.query ?? ''\"\n :placeholder=\"config.labels.searchPlaceholder\"\n :aria-label=\"config.labels.searchLabel\"\n @update:model-value=\"patchFilters({ query: $event })\"\n >\n <template #leftSection>\n <WhatsAppIcon name=\"search\" size=\"16\" />\n </template>\n </TextInput>\n\n <Box\n v-if=\"withUnread || assigneeOptions || statusOptions || slots.filters\"\n v-bind=\"getStyles('conversationListFilters')\"\n >\n <Switch\n v-if=\"withUnread\"\n size=\"xs\"\n :label=\"config.labels.unreadFilterLabel\"\n :model-value=\"filters.unreadOnly ?? false\"\n @update:model-value=\"patchFilters({ unreadOnly: $event })\"\n />\n\n <Select\n v-if=\"statusOptions\"\n size=\"xs\"\n clearable\n :data=\"statusOptions\"\n :placeholder=\"config.labels.statusFilterPlaceholder\"\n :aria-label=\"config.labels.statusFilterLabel\"\n :model-value=\"filters.status ?? null\"\n @update:model-value=\"patchFilters({ status: $event })\"\n />\n\n <Select\n v-if=\"assigneeOptions\"\n size=\"xs\"\n clearable\n :data=\"assigneeOptions\"\n :placeholder=\"config.labels.assigneeFilterPlaceholder\"\n :aria-label=\"config.labels.assigneeFilterLabel\"\n :model-value=\"filters.assigneeId === null ? '' : (filters.assigneeId ?? null)\"\n @update:model-value=\"patchFilters({ assigneeId: $event === '' ? null : $event })\"\n />\n\n <slot name=\"filters\" />\n </Box>\n </Box>\n\n <Center v-if=\"showLoading\" v-bind=\"getStyles('conversationListState')\">\n <slot v-if=\"slots.loadingInbox\" name=\"loadingInbox\" />\n <template v-else>\n <Loader size=\"sm\" />\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.loadingConversations }}</Text>\n </template>\n </Center>\n\n <Box v-else-if=\"showError\" v-bind=\"getStyles('conversationListState')\">\n <slot v-if=\"slots.errorInbox\" name=\"errorInbox\" :error=\"props.error ?? ''\" />\n <Alert v-else color=\"red\" variant=\"light\" :title=\"config.labels.conversationsError\">\n <Text size=\"sm\">{{ props.error }}</Text>\n <Button mt=\"sm\" size=\"xs\" variant=\"light\" color=\"red\" @click=\"emit('retryLoad')\">\n {{ config.labels.retry }}\n </Button>\n </Alert>\n </Box>\n\n <Box v-else-if=\"showEmpty\" v-bind=\"getStyles('conversationListState')\">\n <slot v-if=\"slots.emptyInbox\" name=\"emptyInbox\" />\n <template v-else>\n <WhatsAppIcon name=\"inbox\" size=\"40\" :style=\"{ color: 'var(--mantine-color-dimmed)' }\" />\n <Text size=\"sm\" c=\"dimmed\">\n {{ hasActiveFilters ? config.labels.emptySearch : config.labels.emptyInbox }}\n </Text>\n <Button v-if=\"hasActiveFilters\" size=\"xs\" variant=\"subtle\" @click=\"setFilters({})\">\n {{ config.labels.clearFilters }}\n </Button>\n </template>\n </Box>\n\n <ScrollArea\n v-else\n v-bind=\"getStyles('conversationListScrollArea')\"\n type=\"auto\"\n scrollbars=\"y\"\n :viewport-props=\"viewportProps\"\n @scroll-position-change=\"handleScroll\"\n >\n <Box\n component=\"ul\"\n v-bind=\"getStyles('conversationListItems')\"\n :aria-label=\"config.labels.conversationsLabel\"\n >\n <Box\n v-for=\"conversation in conversations\"\n :key=\"conversation.id\"\n component=\"li\"\n v-bind=\"getStyles('conversationListItemWrapper')\"\n >\n <slot\n v-if=\"slots.conversationItem\"\n name=\"conversationItem\"\n :conversation=\"conversation\"\n :selected=\"conversation.id === selectedId\"\n />\n\n <WhatsAppConversationListItem\n v-else\n :conversation=\"conversation\"\n :selected=\"conversation.id === selectedId\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @select=\"select\"\n >\n <template v-if=\"slots.conversationAvatar\" #conversationAvatar=\"avatarProps\">\n <slot name=\"conversationAvatar\" v-bind=\"avatarProps\" />\n </template>\n <template v-if=\"slots.conversationPreview\" #conversationPreview=\"previewProps\">\n <slot name=\"conversationPreview\" v-bind=\"previewProps\" />\n </template>\n </WhatsAppConversationListItem>\n </Box>\n </Box>\n\n <Box\n v-if=\"canLoadMore || props.pagination?.loadingMore\"\n v-bind=\"getStyles('conversationListLoadMore')\"\n >\n <Group v-if=\"props.pagination?.loadingMore\" gap=\"xs\">\n <Loader size=\"xs\" />\n <Text size=\"xs\" c=\"dimmed\">{{ config.labels.loading }}</Text>\n </Group>\n <Button v-else size=\"xs\" variant=\"subtle\" @click=\"requestMore\">\n {{ config.labels.loadMoreConversations }}\n </Button>\n </Box>\n </ScrollArea>\n\n <Box v-if=\"slots.listFooter\" v-bind=\"getStyles('conversationListFooter')\">\n <slot name=\"listFooter\" />\n </Box>\n\n <Modal\n :opened=\"newConversationOpened\"\n :title=\"config.labels.newConversationTitle\"\n size=\"md\"\n @close=\"setNewConversationOpened(false)\"\n >\n <Box\n component=\"form\"\n v-bind=\"getStyles('newConversationForm')\"\n @submit.prevent=\"submitNewConversation\"\n >\n <Text size=\"sm\" c=\"dimmed\">{{ config.labels.newConversationDescription }}</Text>\n\n <TextInput\n v-model=\"newPhoneNumber\"\n type=\"tel\"\n required\n data-autofocus\n :label=\"config.labels.newConversationPhoneLabel\"\n :placeholder=\"config.labels.newConversationPhonePlaceholder\"\n :error=\"newPhoneError\"\n />\n\n <TextInput\n v-model=\"newName\"\n :label=\"config.labels.newConversationNameLabel\"\n :placeholder=\"config.labels.newConversationNamePlaceholder\"\n />\n\n <Alert v-if=\"props.newConversationError\" color=\"red\" variant=\"light\" role=\"alert\">\n {{ props.newConversationError }}\n </Alert>\n\n <Box v-bind=\"getStyles('newConversationActions')\">\n <Button variant=\"default\" @click=\"setNewConversationOpened(false)\">\n {{ config.labels.cancel }}\n </Button>\n <Button type=\"submit\" :loading=\"props.newConversationCreating\">\n {{ config.labels.newConversationSubmit }}\n </Button>\n </Box>\n </Box>\n </Modal>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppConversationListComponent from './WhatsAppConversationList.vue'\nimport type { WhatsAppConversationListFactory } from './WhatsAppConversationList.types'\nimport classes from './WhatsAppConversationList.module.css'\n\nexport const WhatsAppConversationList = factory<WhatsAppConversationListFactory>(\n WhatsAppConversationListComponent,\n { classes },\n)\n\nexport type {\n WhatsAppConversationListEmits,\n WhatsAppConversationListFactory,\n WhatsAppConversationListOwnProps,\n WhatsAppConversationListProps,\n WhatsAppConversationListStylesNames,\n WhatsAppConversationOrder,\n} from './WhatsAppConversationList.types'\n",".inboxRoot {\n display: grid;\n grid-template-columns: var(--wa-sidebar-width, 320px) minmax(0, 1fr);\n min-height: 0;\n height: 100%;\n overflow: hidden;\n border: 1px solid var(--mantine-color-default-border);\n border-radius: var(--mantine-radius-md);\n background-color: var(--mantine-color-body);\n}\n\n.inboxRoot:where([data-with-panel]) {\n grid-template-columns:\n var(--wa-sidebar-width, 320px) minmax(0, 1fr)\n var(--wa-panel-width, 320px);\n}\n\n.inboxRoot:where([data-narrow]) {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.inboxSidebar {\n min-width: 0;\n min-height: 0;\n border-inline-end: 1px solid var(--mantine-color-default-border);\n}\n\n.inboxRoot:where([data-narrow]) .inboxSidebar {\n border-inline-end: none;\n}\n\n.inboxMain {\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.inboxPanel {\n min-width: 0;\n min-height: 0;\n}\n\n.inboxRoot:where([data-narrow]) .inboxPanel {\n border-inline-start: none;\n}\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n layout: 'auto',\n narrowBreakpoint: 720,\n order: 'none',\n withContactPanel: false,\n} as const\n\nfunction toCssWidth(value: string | number | undefined) {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'number' ? `${value}px` : value\n}\n\nconst varsResolver = createVarsResolver<any>((_, { sidebarWidth, contactPanelWidth }) => ({\n inboxRoot: {\n '--wa-sidebar-width': toCssWidth(sidebarWidth),\n '--wa-panel-width': toCssWidth(contactPanelWidth),\n },\n}))\n\nexport { defaultProps, toCssWidth, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, useSlots } from 'vue'\nimport { Box, useProps, useStyles } from '@mantine-vue/core'\nimport { useResizeObserver, useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type {\n WhatsAppAttachment,\n WhatsAppConversationSummary,\n WhatsAppMessageData,\n} from '../../types'\nimport { WhatsAppContactPanel } from '../WhatsAppContactPanel'\nimport { WhatsAppConversation } from '../WhatsAppConversation'\nimport type { WhatsAppConversationExposed } from '../WhatsAppConversation'\nimport { WhatsAppConversationList } from '../WhatsAppConversationList'\nimport type {\n WhatsAppInboxEmits,\n WhatsAppInboxOwnProps,\n WhatsAppInboxSlots,\n} from './WhatsAppInbox.types'\nimport classes from './WhatsAppInbox.module.css'\n\ndefineOptions({\n name: 'WhatsAppInbox',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInboxOwnProps>(), {\n conversations: undefined,\n selectedConversationId: undefined,\n defaultSelectedConversationId: undefined,\n conversation: undefined,\n filters: undefined,\n defaultFilters: undefined,\n filtersConfig: undefined,\n conversationsLoading: undefined,\n conversationsError: undefined,\n conversationsPagination: undefined,\n order: undefined,\n layout: undefined,\n narrowBreakpoint: undefined,\n sidebarWidth: undefined,\n contactPanelWidth: undefined,\n withContactPanel: undefined,\n contactPanelOpened: undefined,\n defaultContactPanelOpened: undefined,\n conversationListProps: undefined,\n contactPanelProps: undefined,\n withNewConversation: undefined,\n newConversationOpened: undefined,\n newConversationCreating: undefined,\n newConversationError: undefined,\n validatePhoneNumber: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n drafts: undefined,\n defaultDrafts: undefined,\n draftBehavior: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppInboxEmits>()\ndefineSlots<WhatsAppInboxSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInbox', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInbox',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'inboxRoot',\n})\n\nconst [selectedId, setSelectedId] = useUncontrolled<string | null>({\n value: () => props.selectedConversationId,\n defaultValue: props.defaultSelectedConversationId,\n finalValue: null,\n onChange: (value) => emit('update:selectedConversationId', value),\n})\n\nconst [contactPanelOpened, setContactPanelOpened] = useUncontrolled<boolean>({\n value: () => props.contactPanelOpened,\n defaultValue: props.defaultContactPanelOpened,\n finalValue: false,\n onChange: (value) => emit('update:contactPanelOpened', value),\n})\n\nconst { ref: rootElement, rect } = useResizeObserver<HTMLElement>()\n\nconst setRootElement = (node: Element | null) => {\n rootElement.value = node as HTMLElement | null\n}\n\n/**\n * The component measures itself rather than the viewport, so an inbox rendered inside a narrow\n * column collapses even on a wide screen.\n *\n * A width of `0` means nothing has been measured yet (first paint, or an environment without\n * `ResizeObserver`); the split layout is the safer assumption there, since collapsing and then\n * expanding would flash the wrong pane.\n */\nconst narrow = computed(() => {\n if (props.layout === 'split') {\n return false\n }\n\n if (props.layout === 'single') {\n return true\n }\n\n const width = rect.value.width\n\n return width > 0 && width < (props.narrowBreakpoint ?? defaultProps.narrowBreakpoint)\n})\n\n/**\n * The selection is the single source of truth for which conversation is open. `conversation` is\n * only the detail record for it, so passing one does not open it on its own -- otherwise the\n * inbox could not represent \"nothing selected\" while a previous conversation is still loaded.\n */\nconst activeConversationId = computed(() => selectedId.value ?? undefined)\n\nconst activeConversation = computed(() => {\n if (!activeConversationId.value) {\n return undefined\n }\n\n if (props.conversation?.id === activeConversationId.value) {\n return props.conversation\n }\n\n return props.conversations?.find((conversation) => conversation.id === activeConversationId.value)\n})\n\nconst showSidebar = computed(() => !narrow.value || !activeConversationId.value)\nconst showConversation = computed(() => !narrow.value || Boolean(activeConversationId.value))\nconst showContactPanel = computed(\n () => props.withContactPanel && contactPanelOpened.value && !narrow.value,\n)\n\nconst conversationRef = ref<WhatsAppConversationExposed | null>(null)\n\nfunction focusComposer() {\n conversationRef.value?.focusComposer()\n}\n\nfunction scrollToBottom(behavior: ScrollBehavior = 'auto') {\n conversationRef.value?.scrollToBottom(behavior)\n}\n\nfunction selectConversation(conversation: WhatsAppConversationSummary) {\n setSelectedId(conversation.id)\n emit('selectConversation', conversation)\n}\n\nfunction goBack() {\n setSelectedId(null)\n emit('back')\n}\n\nfunction handleMediaDownload(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaDownload', attachment, message)\n}\n\nfunction handleMediaPreview(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaPreview', attachment, message)\n}\n\ndefineExpose({ focusComposer, scrollToBottom })\n</script>\n\n<template>\n <Box\n :root-ref=\"setRootElement\"\n v-bind=\"{ ...attrs, ...getStyles('inboxRoot') }\"\n :data-narrow=\"narrow ? '' : undefined\"\n :data-with-panel=\"showContactPanel ? '' : undefined\"\n :aria-label=\"config.labels.conversationsLabel\"\n >\n <WhatsAppConversationList\n v-if=\"showSidebar\"\n v-bind=\"{ ...props.conversationListProps, ...getStyles('inboxSidebar') }\"\n :conversations=\"props.conversations\"\n :selected-conversation-id=\"selectedId\"\n :filters=\"props.filters\"\n :default-filters=\"props.defaultFilters\"\n :filters-config=\"props.filtersConfig\"\n :loading=\"props.conversationsLoading\"\n :error=\"props.conversationsError\"\n :pagination=\"props.conversationsPagination\"\n :order=\"props.order\"\n :with-new-conversation=\"props.withNewConversation\"\n :new-conversation-opened=\"props.newConversationOpened\"\n :new-conversation-creating=\"props.newConversationCreating\"\n :new-conversation-error=\"props.newConversationError\"\n :validate-phone-number=\"props.validatePhoneNumber\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @update:selected-conversation-id=\"setSelectedId($event)\"\n @update:filters=\"emit('update:filters', $event)\"\n @select=\"selectConversation\"\n @load-more=\"emit('loadMoreConversations', $event)\"\n @retry-load=\"emit('retryLoadConversations')\"\n @update:new-conversation-opened=\"emit('update:newConversationOpened', $event)\"\n @new-conversation=\"emit('newConversation', $event)\"\n >\n <template v-if=\"slots.listHeader\" #listHeader><slot name=\"listHeader\" /></template>\n <template v-if=\"slots.listFooter\" #listFooter><slot name=\"listFooter\" /></template>\n <template v-if=\"slots.filters\" #filters><slot name=\"filters\" /></template>\n <template v-if=\"slots.conversationItem\" #conversationItem=\"itemProps\">\n <slot name=\"conversationItem\" v-bind=\"itemProps\" />\n </template>\n <template v-if=\"slots.conversationAvatar\" #conversationAvatar=\"avatarProps\">\n <slot name=\"conversationAvatar\" v-bind=\"avatarProps\" />\n </template>\n <template v-if=\"slots.conversationPreview\" #conversationPreview=\"previewProps\">\n <slot name=\"conversationPreview\" v-bind=\"previewProps\" />\n </template>\n <template v-if=\"slots.emptyInbox\" #emptyInbox><slot name=\"emptyInbox\" /></template>\n <template v-if=\"slots.loadingInbox\" #loadingInbox><slot name=\"loadingInbox\" /></template>\n <template v-if=\"slots.errorInbox\" #errorInbox=\"errorProps\">\n <slot name=\"errorInbox\" v-bind=\"errorProps\" />\n </template>\n </WhatsAppConversationList>\n\n <Box v-if=\"showConversation\" v-bind=\"getStyles('inboxMain')\">\n <WhatsAppConversation\n ref=\"conversationRef\"\n :conversation=\"activeConversation\"\n :conversation-id=\"activeConversationId\"\n :capabilities=\"props.capabilities\"\n :messages=\"props.messages\"\n :messages-loading=\"props.messagesLoading\"\n :messages-error=\"props.messagesError\"\n :messages-pagination=\"props.messagesPagination\"\n :uploads=\"props.uploads\"\n :templates=\"props.templates\"\n :templates-loading=\"props.templatesLoading\"\n :templates-error=\"props.templatesError\"\n :draft=\"props.draft\"\n :drafts=\"props.drafts\"\n :default-drafts=\"props.defaultDrafts\"\n :draft-behavior=\"props.draftBehavior\"\n :sending=\"props.sending\"\n :send-error=\"props.sendError\"\n :reply-to=\"props.replyTo\"\n :with-header=\"props.withHeader\"\n :with-composer=\"props.withComposer\"\n :with-back=\"narrow\"\n :with-contact-toggle=\"props.withContactPanel && !narrow\"\n :contact-panel-opened=\"contactPanelOpened\"\n :focus-composer-on-change=\"props.focusComposerOnChange\"\n :header-props=\"props.headerProps\"\n :message-list-props=\"props.messageListProps\"\n :composer-props=\"props.composerProps\"\n :labels=\"props.labels\"\n :render-message=\"props.renderMessage\"\n :render-message-content=\"props.renderMessageContent\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @update:draft=\"emit('update:draft', $event)\"\n @update:drafts=\"emit('update:drafts', $event)\"\n @update:reply-to=\"emit('update:replyTo', $event)\"\n @typing=\"emit('typing', $event)\"\n @send=\"emit('send', $event)\"\n @attachments-add=\"emit('attachmentsAdd', $event)\"\n @attachments-reject=\"emit('attachmentsReject', $event)\"\n @attachment-remove=\"emit('attachmentRemove', $event)\"\n @attachment-retry=\"emit('attachmentRetry', $event)\"\n @attachment-cancel=\"emit('attachmentCancel', $event)\"\n @validation-error=\"emit('validationError', $event)\"\n @retry-send=\"emit('retrySend')\"\n @templates-retry-load=\"emit('templatesRetryLoad')\"\n @load-older-messages=\"emit('loadOlderMessages', $event)\"\n @retry-load-messages=\"emit('retryLoadMessages')\"\n @retry-message=\"emit('retryMessage', $event)\"\n @media-download=\"handleMediaDownload\"\n @media-preview=\"handleMediaPreview\"\n @at-bottom-change=\"emit('atBottomChange', $event)\"\n @contact-click=\"emit('contactClick', $event)\"\n @toggle-contact-panel=\"setContactPanelOpened($event)\"\n @back=\"goBack\"\n >\n <template v-if=\"slots.conversationHeader\" #conversationHeader=\"headerSlotProps\">\n <slot name=\"conversationHeader\" v-bind=\"headerSlotProps\" />\n </template>\n <template v-if=\"slots.headerActions\" #headerActions=\"headerActionsProps\">\n <slot name=\"headerActions\" v-bind=\"headerActionsProps\" />\n </template>\n <template v-if=\"slots.message\" #message=\"messageProps\">\n <slot name=\"message\" v-bind=\"messageProps\" />\n </template>\n <template v-if=\"slots.messageContent\" #messageContent=\"messageContentProps\">\n <slot name=\"messageContent\" v-bind=\"messageContentProps\" />\n </template>\n <template v-if=\"slots.messageFooter\" #messageFooter=\"messageFooterProps\">\n <slot name=\"messageFooter\" v-bind=\"messageFooterProps\" />\n </template>\n <template v-if=\"slots.mediaAttachment\" #mediaAttachment=\"mediaProps\">\n <slot name=\"mediaAttachment\" v-bind=\"mediaProps\" />\n </template>\n <template v-if=\"slots.emptyConversation\" #emptyConversation>\n <slot name=\"emptyConversation\" />\n </template>\n <template v-if=\"slots.loadingMessages\" #loadingMessages>\n <slot name=\"loadingMessages\" />\n </template>\n <template v-if=\"slots.errorMessages\" #errorMessages=\"errorProps\">\n <slot name=\"errorMessages\" v-bind=\"errorProps\" />\n </template>\n <template v-if=\"slots.composerPrefix\" #composerPrefix>\n <slot name=\"composerPrefix\" />\n </template>\n <template v-if=\"slots.composerSuffix\" #composerSuffix>\n <slot name=\"composerSuffix\" />\n </template>\n <template v-if=\"slots.composerActions\" #composerActions>\n <slot name=\"composerActions\" />\n </template>\n <template v-if=\"slots.emojiPicker\" #emojiPicker=\"emojiProps\">\n <slot name=\"emojiPicker\" v-bind=\"emojiProps\" />\n </template>\n <template v-if=\"slots.attachmentPreview\" #attachmentPreview=\"attachmentProps\">\n <slot name=\"attachmentPreview\" v-bind=\"attachmentProps\" />\n </template>\n <template v-if=\"slots.templatePreview\" #templatePreview=\"templateProps\">\n <slot name=\"templatePreview\" v-bind=\"templateProps\" />\n </template>\n </WhatsAppConversation>\n </Box>\n\n <WhatsAppContactPanel\n v-if=\"showContactPanel\"\n v-bind=\"{ ...props.contactPanelProps, ...getStyles('inboxPanel') }\"\n :conversation=\"activeConversation\"\n :contact=\"activeConversation?.contact\"\n with-close-button\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @close=\"setContactPanelOpened(false)\"\n >\n <template v-if=\"slots.contactPanel\" #contactPanel=\"panelProps\">\n <slot name=\"contactPanel\" v-bind=\"panelProps\" />\n </template>\n <template v-if=\"slots.contactPanelHeader\" #contactPanelHeader=\"panelHeaderProps\">\n <slot name=\"contactPanelHeader\" v-bind=\"panelHeaderProps\" />\n </template>\n <template v-if=\"slots.contactPanelFooter\" #contactPanelFooter=\"panelFooterProps\">\n <slot name=\"contactPanelFooter\" v-bind=\"panelFooterProps\" />\n </template>\n </WhatsAppContactPanel>\n </Box>\n</template>\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n layout: 'auto',\n narrowBreakpoint: 720,\n order: 'none',\n withContactPanel: false,\n} as const\n\nfunction toCssWidth(value: string | number | undefined) {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'number' ? `${value}px` : value\n}\n\nconst varsResolver = createVarsResolver<any>((_, { sidebarWidth, contactPanelWidth }) => ({\n inboxRoot: {\n '--wa-sidebar-width': toCssWidth(sidebarWidth),\n '--wa-panel-width': toCssWidth(contactPanelWidth),\n },\n}))\n\nexport { defaultProps, toCssWidth, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, useSlots } from 'vue'\nimport { Box, useProps, useStyles } from '@mantine-vue/core'\nimport { useResizeObserver, useUncontrolled } from '@mantine-vue/hooks'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type {\n WhatsAppAttachment,\n WhatsAppConversationSummary,\n WhatsAppMessageData,\n} from '../../types'\nimport { WhatsAppContactPanel } from '../WhatsAppContactPanel'\nimport { WhatsAppConversation } from '../WhatsAppConversation'\nimport type { WhatsAppConversationExposed } from '../WhatsAppConversation'\nimport { WhatsAppConversationList } from '../WhatsAppConversationList'\nimport type {\n WhatsAppInboxEmits,\n WhatsAppInboxOwnProps,\n WhatsAppInboxSlots,\n} from './WhatsAppInbox.types'\nimport classes from './WhatsAppInbox.module.css'\n\ndefineOptions({\n name: 'WhatsAppInbox',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInboxOwnProps>(), {\n conversations: undefined,\n selectedConversationId: undefined,\n defaultSelectedConversationId: undefined,\n conversation: undefined,\n filters: undefined,\n defaultFilters: undefined,\n filtersConfig: undefined,\n conversationsLoading: undefined,\n conversationsError: undefined,\n conversationsPagination: undefined,\n order: undefined,\n layout: undefined,\n narrowBreakpoint: undefined,\n sidebarWidth: undefined,\n contactPanelWidth: undefined,\n withContactPanel: undefined,\n contactPanelOpened: undefined,\n defaultContactPanelOpened: undefined,\n conversationListProps: undefined,\n contactPanelProps: undefined,\n withNewConversation: undefined,\n newConversationOpened: undefined,\n newConversationCreating: undefined,\n newConversationError: undefined,\n validatePhoneNumber: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n drafts: undefined,\n defaultDrafts: undefined,\n draftBehavior: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\nconst emit = defineEmits<WhatsAppInboxEmits>()\ndefineSlots<WhatsAppInboxSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInbox', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInbox',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'inboxRoot',\n})\n\nconst [selectedId, setSelectedId] = useUncontrolled<string | null>({\n value: () => props.selectedConversationId,\n defaultValue: props.defaultSelectedConversationId,\n finalValue: null,\n onChange: (value) => emit('update:selectedConversationId', value),\n})\n\nconst [contactPanelOpened, setContactPanelOpened] = useUncontrolled<boolean>({\n value: () => props.contactPanelOpened,\n defaultValue: props.defaultContactPanelOpened,\n finalValue: false,\n onChange: (value) => emit('update:contactPanelOpened', value),\n})\n\nconst { ref: rootElement, rect } = useResizeObserver<HTMLElement>()\n\nconst setRootElement = (node: Element | null) => {\n rootElement.value = node as HTMLElement | null\n}\n\n/**\n * The component measures itself rather than the viewport, so an inbox rendered inside a narrow\n * column collapses even on a wide screen.\n *\n * A width of `0` means nothing has been measured yet (first paint, or an environment without\n * `ResizeObserver`); the split layout is the safer assumption there, since collapsing and then\n * expanding would flash the wrong pane.\n */\nconst narrow = computed(() => {\n if (props.layout === 'split') {\n return false\n }\n\n if (props.layout === 'single') {\n return true\n }\n\n const width = rect.value.width\n\n return width > 0 && width < (props.narrowBreakpoint ?? defaultProps.narrowBreakpoint)\n})\n\n/**\n * The selection is the single source of truth for which conversation is open. `conversation` is\n * only the detail record for it, so passing one does not open it on its own -- otherwise the\n * inbox could not represent \"nothing selected\" while a previous conversation is still loaded.\n */\nconst activeConversationId = computed(() => selectedId.value ?? undefined)\n\nconst activeConversation = computed(() => {\n if (!activeConversationId.value) {\n return undefined\n }\n\n if (props.conversation?.id === activeConversationId.value) {\n return props.conversation\n }\n\n return props.conversations?.find((conversation) => conversation.id === activeConversationId.value)\n})\n\nconst showSidebar = computed(() => !narrow.value || !activeConversationId.value)\nconst showConversation = computed(() => !narrow.value || Boolean(activeConversationId.value))\nconst showContactPanel = computed(\n () => props.withContactPanel && contactPanelOpened.value && !narrow.value,\n)\n\nconst conversationRef = ref<WhatsAppConversationExposed | null>(null)\n\nfunction focusComposer() {\n conversationRef.value?.focusComposer()\n}\n\nfunction scrollToBottom(behavior: ScrollBehavior = 'auto') {\n conversationRef.value?.scrollToBottom(behavior)\n}\n\nfunction selectConversation(conversation: WhatsAppConversationSummary) {\n setSelectedId(conversation.id)\n emit('selectConversation', conversation)\n}\n\nfunction goBack() {\n setSelectedId(null)\n emit('back')\n}\n\nfunction handleMediaDownload(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaDownload', attachment, message)\n}\n\nfunction handleMediaPreview(attachment: WhatsAppAttachment, message: WhatsAppMessageData) {\n emit('mediaPreview', attachment, message)\n}\n\ndefineExpose({ focusComposer, scrollToBottom })\n</script>\n\n<template>\n <Box\n :root-ref=\"setRootElement\"\n v-bind=\"{ ...attrs, ...getStyles('inboxRoot') }\"\n :data-narrow=\"narrow ? '' : undefined\"\n :data-with-panel=\"showContactPanel ? '' : undefined\"\n :aria-label=\"config.labels.conversationsLabel\"\n >\n <WhatsAppConversationList\n v-if=\"showSidebar\"\n v-bind=\"{ ...props.conversationListProps, ...getStyles('inboxSidebar') }\"\n :conversations=\"props.conversations\"\n :selected-conversation-id=\"selectedId\"\n :filters=\"props.filters\"\n :default-filters=\"props.defaultFilters\"\n :filters-config=\"props.filtersConfig\"\n :loading=\"props.conversationsLoading\"\n :error=\"props.conversationsError\"\n :pagination=\"props.conversationsPagination\"\n :order=\"props.order\"\n :with-new-conversation=\"props.withNewConversation\"\n :new-conversation-opened=\"props.newConversationOpened\"\n :new-conversation-creating=\"props.newConversationCreating\"\n :new-conversation-error=\"props.newConversationError\"\n :validate-phone-number=\"props.validatePhoneNumber\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @update:selected-conversation-id=\"setSelectedId($event)\"\n @update:filters=\"emit('update:filters', $event)\"\n @select=\"selectConversation\"\n @load-more=\"emit('loadMoreConversations', $event)\"\n @retry-load=\"emit('retryLoadConversations')\"\n @update:new-conversation-opened=\"emit('update:newConversationOpened', $event)\"\n @new-conversation=\"emit('newConversation', $event)\"\n >\n <template v-if=\"slots.listHeader\" #listHeader><slot name=\"listHeader\" /></template>\n <template v-if=\"slots.listFooter\" #listFooter><slot name=\"listFooter\" /></template>\n <template v-if=\"slots.filters\" #filters><slot name=\"filters\" /></template>\n <template v-if=\"slots.conversationItem\" #conversationItem=\"itemProps\">\n <slot name=\"conversationItem\" v-bind=\"itemProps\" />\n </template>\n <template v-if=\"slots.conversationAvatar\" #conversationAvatar=\"avatarProps\">\n <slot name=\"conversationAvatar\" v-bind=\"avatarProps\" />\n </template>\n <template v-if=\"slots.conversationPreview\" #conversationPreview=\"previewProps\">\n <slot name=\"conversationPreview\" v-bind=\"previewProps\" />\n </template>\n <template v-if=\"slots.emptyInbox\" #emptyInbox><slot name=\"emptyInbox\" /></template>\n <template v-if=\"slots.loadingInbox\" #loadingInbox><slot name=\"loadingInbox\" /></template>\n <template v-if=\"slots.errorInbox\" #errorInbox=\"errorProps\">\n <slot name=\"errorInbox\" v-bind=\"errorProps\" />\n </template>\n </WhatsAppConversationList>\n\n <Box v-if=\"showConversation\" v-bind=\"getStyles('inboxMain')\">\n <WhatsAppConversation\n ref=\"conversationRef\"\n :conversation=\"activeConversation\"\n :conversation-id=\"activeConversationId\"\n :capabilities=\"props.capabilities\"\n :messages=\"props.messages\"\n :messages-loading=\"props.messagesLoading\"\n :messages-error=\"props.messagesError\"\n :messages-pagination=\"props.messagesPagination\"\n :uploads=\"props.uploads\"\n :templates=\"props.templates\"\n :templates-loading=\"props.templatesLoading\"\n :templates-error=\"props.templatesError\"\n :draft=\"props.draft\"\n :drafts=\"props.drafts\"\n :default-drafts=\"props.defaultDrafts\"\n :draft-behavior=\"props.draftBehavior\"\n :sending=\"props.sending\"\n :send-error=\"props.sendError\"\n :reply-to=\"props.replyTo\"\n :with-header=\"props.withHeader\"\n :with-composer=\"props.withComposer\"\n :with-back=\"narrow\"\n :with-contact-toggle=\"props.withContactPanel && !narrow\"\n :contact-panel-opened=\"contactPanelOpened\"\n :focus-composer-on-change=\"props.focusComposerOnChange\"\n :header-props=\"props.headerProps\"\n :message-list-props=\"props.messageListProps\"\n :composer-props=\"props.composerProps\"\n :labels=\"props.labels\"\n :render-message=\"props.renderMessage\"\n :render-message-content=\"props.renderMessageContent\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @update:draft=\"emit('update:draft', $event)\"\n @update:drafts=\"emit('update:drafts', $event)\"\n @update:reply-to=\"emit('update:replyTo', $event)\"\n @typing=\"emit('typing', $event)\"\n @send=\"emit('send', $event)\"\n @attachments-add=\"emit('attachmentsAdd', $event)\"\n @attachments-reject=\"emit('attachmentsReject', $event)\"\n @attachment-remove=\"emit('attachmentRemove', $event)\"\n @attachment-retry=\"emit('attachmentRetry', $event)\"\n @attachment-cancel=\"emit('attachmentCancel', $event)\"\n @validation-error=\"emit('validationError', $event)\"\n @retry-send=\"emit('retrySend')\"\n @templates-retry-load=\"emit('templatesRetryLoad')\"\n @load-older-messages=\"emit('loadOlderMessages', $event)\"\n @retry-load-messages=\"emit('retryLoadMessages')\"\n @retry-message=\"emit('retryMessage', $event)\"\n @media-download=\"handleMediaDownload\"\n @media-preview=\"handleMediaPreview\"\n @at-bottom-change=\"emit('atBottomChange', $event)\"\n @contact-click=\"emit('contactClick', $event)\"\n @toggle-contact-panel=\"setContactPanelOpened($event)\"\n @back=\"goBack\"\n >\n <template v-if=\"slots.conversationHeader\" #conversationHeader=\"headerSlotProps\">\n <slot name=\"conversationHeader\" v-bind=\"headerSlotProps\" />\n </template>\n <template v-if=\"slots.headerActions\" #headerActions=\"headerActionsProps\">\n <slot name=\"headerActions\" v-bind=\"headerActionsProps\" />\n </template>\n <template v-if=\"slots.message\" #message=\"messageProps\">\n <slot name=\"message\" v-bind=\"messageProps\" />\n </template>\n <template v-if=\"slots.messageContent\" #messageContent=\"messageContentProps\">\n <slot name=\"messageContent\" v-bind=\"messageContentProps\" />\n </template>\n <template v-if=\"slots.messageFooter\" #messageFooter=\"messageFooterProps\">\n <slot name=\"messageFooter\" v-bind=\"messageFooterProps\" />\n </template>\n <template v-if=\"slots.mediaAttachment\" #mediaAttachment=\"mediaProps\">\n <slot name=\"mediaAttachment\" v-bind=\"mediaProps\" />\n </template>\n <template v-if=\"slots.emptyConversation\" #emptyConversation>\n <slot name=\"emptyConversation\" />\n </template>\n <template v-if=\"slots.loadingMessages\" #loadingMessages>\n <slot name=\"loadingMessages\" />\n </template>\n <template v-if=\"slots.errorMessages\" #errorMessages=\"errorProps\">\n <slot name=\"errorMessages\" v-bind=\"errorProps\" />\n </template>\n <template v-if=\"slots.composerPrefix\" #composerPrefix>\n <slot name=\"composerPrefix\" />\n </template>\n <template v-if=\"slots.composerSuffix\" #composerSuffix>\n <slot name=\"composerSuffix\" />\n </template>\n <template v-if=\"slots.composerActions\" #composerActions>\n <slot name=\"composerActions\" />\n </template>\n <template v-if=\"slots.emojiPicker\" #emojiPicker=\"emojiProps\">\n <slot name=\"emojiPicker\" v-bind=\"emojiProps\" />\n </template>\n <template v-if=\"slots.attachmentPreview\" #attachmentPreview=\"attachmentProps\">\n <slot name=\"attachmentPreview\" v-bind=\"attachmentProps\" />\n </template>\n <template v-if=\"slots.templatePreview\" #templatePreview=\"templateProps\">\n <slot name=\"templatePreview\" v-bind=\"templateProps\" />\n </template>\n </WhatsAppConversation>\n </Box>\n\n <WhatsAppContactPanel\n v-if=\"showContactPanel\"\n v-bind=\"{ ...props.contactPanelProps, ...getStyles('inboxPanel') }\"\n :conversation=\"activeConversation\"\n :contact=\"activeConversation?.contact\"\n with-close-button\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n @close=\"setContactPanelOpened(false)\"\n >\n <template v-if=\"slots.contactPanel\" #contactPanel=\"panelProps\">\n <slot name=\"contactPanel\" v-bind=\"panelProps\" />\n </template>\n <template v-if=\"slots.contactPanelHeader\" #contactPanelHeader=\"panelHeaderProps\">\n <slot name=\"contactPanelHeader\" v-bind=\"panelHeaderProps\" />\n </template>\n <template v-if=\"slots.contactPanelFooter\" #contactPanelFooter=\"panelFooterProps\">\n <slot name=\"contactPanelFooter\" v-bind=\"panelFooterProps\" />\n </template>\n </WhatsAppContactPanel>\n </Box>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppInboxComponent from './WhatsAppInbox.vue'\nimport type { WhatsAppInboxFactory } from './WhatsAppInbox.types'\nimport classes from './WhatsAppInbox.module.css'\n\nexport const WhatsAppInbox = factory<WhatsAppInboxFactory>(WhatsAppInboxComponent, { classes })\n\nexport type {\n WhatsAppInboxConversationProps,\n WhatsAppInboxEmits,\n WhatsAppInboxExposed,\n WhatsAppInboxFactory,\n WhatsAppInboxLayout,\n WhatsAppInboxOwnProps,\n WhatsAppInboxProps,\n WhatsAppInboxSlots,\n WhatsAppInboxStylesNames,\n} from './WhatsAppInbox.types'\n",".modalRoot {\n display: contents;\n}\n\n/*\n * The dialog is a column: the header keeps its own padding, and the body is the only part that\n * loses it so the conversation can run edge to edge.\n */\n.modalContent {\n display: flex;\n flex-direction: column;\n}\n\n.modalBody {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: var(--wa-modal-height, 70vh);\n min-height: 0;\n padding: 0;\n}\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n opened: false,\n height: '70vh',\n focusComposerOnOpen: true,\n} as const\n\n/**\n * Props the modal keeps for itself. Everything else is forwarded to the conversation, so the\n * wrapper does not have to re-declare the whole conversation API every time it grows.\n */\nconst MODAL_OWN_PROPS = new Set([\n 'opened',\n 'title',\n 'height',\n 'focusComposerOnOpen',\n 'modalProps',\n 'classNames',\n 'styles',\n 'vars',\n 'unstyled',\n])\n\nconst varsResolver = createVarsResolver<any>((_, { height }) => ({\n modalBody: {\n '--wa-modal-height':\n height === undefined ? undefined : typeof height === 'number' ? `${height}px` : height,\n },\n}))\n\nexport { defaultProps, MODAL_OWN_PROPS, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch, type CSSProperties } from 'vue'\nimport { Modal, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationSlots } from '../../component-props'\nimport { getContactDisplayName } from '../../utils'\nimport { WhatsAppConversation } from '../WhatsAppConversation'\nimport type { WhatsAppConversationExposed } from '../WhatsAppConversation'\nimport type { WhatsAppInboxModalOwnProps } from './WhatsAppInboxModal.types'\nimport classes from './WhatsAppInboxModal.module.css'\n\ndefineOptions({\n name: 'WhatsAppInboxModal',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInboxModalOwnProps>(), {\n opened: undefined,\n title: undefined,\n height: undefined,\n focusComposerOnOpen: undefined,\n modalProps: undefined,\n conversation: undefined,\n conversationId: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\n/**\n * Only the dialog's own events are declared. Every conversation listener falls through as an\n * attribute and is spread onto `WhatsAppConversation`, which keeps the two APIs in sync without\n * a forwarding line per event. The full event list is still part of the public type through\n * `WhatsAppInboxModalEmits`.\n */\nconst emit = defineEmits<{\n 'update:opened': [opened: boolean]\n close: []\n}>()\n\ndefineSlots<WhatsAppConversationSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInboxModal', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInboxModal',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'modalRoot',\n})\n\nconst conversationProps = computed(() => {\n const result: Record<string, unknown> = {}\n\n for (const key of Object.keys(props)) {\n if (!MODAL_OWN_PROPS.has(key)) {\n result[key] = (props as Record<string, unknown>)[key]\n }\n }\n\n return result\n})\n\nconst forwardedAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n\n return rest\n})\n\n/**\n * `getStyles` returns the class list as an array, which `Modal`'s `classNames` record does not\n * accept; joining it keeps the Styles API working through the dialog.\n */\nconst bodyClassName = computed(() =>\n (getStyles('modalBody').class as unknown[]).filter(Boolean).join(' '),\n)\nconst bodyStyle = computed(() => getStyles('modalBody').style as CSSProperties)\nconst contentClassName = computed(() =>\n (getStyles('modalContent').class as unknown[]).filter(Boolean).join(' '),\n)\n\nconst slotNames = computed(() => Object.keys(slots) as (keyof WhatsAppConversationSlots)[])\n\nconst conversationRef = ref<WhatsAppConversationExposed | null>(null)\n\nconst title = computed(() => {\n if (props.title !== undefined) {\n return props.title\n }\n\n return props.conversation\n ? getContactDisplayName(props.conversation)\n : config.labels.conversationsLabel\n})\n\nfunction close() {\n emit('update:opened', false)\n emit('close')\n}\n\n// Opening the modal moves focus to the composer.\nwatch(\n () => props.opened,\n (opened) => {\n if (opened && props.focusComposerOnOpen) {\n void nextTick(() => conversationRef.value?.focusComposer())\n }\n },\n)\n</script>\n\n<template>\n <Modal\n v-bind=\"props.modalProps\"\n :opened=\"Boolean(props.opened)\"\n :title=\"title\"\n size=\"lg\"\n :class=\"getStyles('modalRoot').class\"\n :style=\"getStyles('modalRoot').style\"\n :class-names=\"{ content: contentClassName, body: bodyClassName }\"\n :styles=\"{ body: bodyStyle }\"\n @close=\"close\"\n >\n <WhatsAppConversation\n ref=\"conversationRef\"\n v-bind=\"{ ...forwardedAttrs, ...conversationProps }\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n :with-header=\"props.withHeader ?? false\"\n >\n <template v-for=\"name in slotNames\" #[name]=\"slotProps\">\n <slot :name=\"name\" v-bind=\"(slotProps ?? {}) as any\" />\n </template>\n </WhatsAppConversation>\n </Modal>\n</template>\n","<script lang=\"ts\">\nimport { createVarsResolver } from '@mantine-vue/core'\n\nconst defaultProps = {\n opened: false,\n height: '70vh',\n focusComposerOnOpen: true,\n} as const\n\n/**\n * Props the modal keeps for itself. Everything else is forwarded to the conversation, so the\n * wrapper does not have to re-declare the whole conversation API every time it grows.\n */\nconst MODAL_OWN_PROPS = new Set([\n 'opened',\n 'title',\n 'height',\n 'focusComposerOnOpen',\n 'modalProps',\n 'classNames',\n 'styles',\n 'vars',\n 'unstyled',\n])\n\nconst varsResolver = createVarsResolver<any>((_, { height }) => ({\n modalBody: {\n '--wa-modal-height':\n height === undefined ? undefined : typeof height === 'number' ? `${height}px` : height,\n },\n}))\n\nexport { defaultProps, MODAL_OWN_PROPS, varsResolver }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch, type CSSProperties } from 'vue'\nimport { Modal, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationSlots } from '../../component-props'\nimport { getContactDisplayName } from '../../utils'\nimport { WhatsAppConversation } from '../WhatsAppConversation'\nimport type { WhatsAppConversationExposed } from '../WhatsAppConversation'\nimport type { WhatsAppInboxModalOwnProps } from './WhatsAppInboxModal.types'\nimport classes from './WhatsAppInboxModal.module.css'\n\ndefineOptions({\n name: 'WhatsAppInboxModal',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInboxModalOwnProps>(), {\n opened: undefined,\n title: undefined,\n height: undefined,\n focusComposerOnOpen: undefined,\n modalProps: undefined,\n conversation: undefined,\n conversationId: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\n/**\n * Only the dialog's own events are declared. Every conversation listener falls through as an\n * attribute and is spread onto `WhatsAppConversation`, which keeps the two APIs in sync without\n * a forwarding line per event. The full event list is still part of the public type through\n * `WhatsAppInboxModalEmits`.\n */\nconst emit = defineEmits<{\n 'update:opened': [opened: boolean]\n close: []\n}>()\n\ndefineSlots<WhatsAppConversationSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInboxModal', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInboxModal',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n varsResolver,\n rootSelector: 'modalRoot',\n})\n\nconst conversationProps = computed(() => {\n const result: Record<string, unknown> = {}\n\n for (const key of Object.keys(props)) {\n if (!MODAL_OWN_PROPS.has(key)) {\n result[key] = (props as Record<string, unknown>)[key]\n }\n }\n\n return result\n})\n\nconst forwardedAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n\n return rest\n})\n\n/**\n * `getStyles` returns the class list as an array, which `Modal`'s `classNames` record does not\n * accept; joining it keeps the Styles API working through the dialog.\n */\nconst bodyClassName = computed(() =>\n (getStyles('modalBody').class as unknown[]).filter(Boolean).join(' '),\n)\nconst bodyStyle = computed(() => getStyles('modalBody').style as CSSProperties)\nconst contentClassName = computed(() =>\n (getStyles('modalContent').class as unknown[]).filter(Boolean).join(' '),\n)\n\nconst slotNames = computed(() => Object.keys(slots) as (keyof WhatsAppConversationSlots)[])\n\nconst conversationRef = ref<WhatsAppConversationExposed | null>(null)\n\nconst title = computed(() => {\n if (props.title !== undefined) {\n return props.title\n }\n\n return props.conversation\n ? getContactDisplayName(props.conversation)\n : config.labels.conversationsLabel\n})\n\nfunction close() {\n emit('update:opened', false)\n emit('close')\n}\n\n// Opening the modal moves focus to the composer.\nwatch(\n () => props.opened,\n (opened) => {\n if (opened && props.focusComposerOnOpen) {\n void nextTick(() => conversationRef.value?.focusComposer())\n }\n },\n)\n</script>\n\n<template>\n <Modal\n v-bind=\"props.modalProps\"\n :opened=\"Boolean(props.opened)\"\n :title=\"title\"\n size=\"lg\"\n :class=\"getStyles('modalRoot').class\"\n :style=\"getStyles('modalRoot').style\"\n :class-names=\"{ content: contentClassName, body: bodyClassName }\"\n :styles=\"{ body: bodyStyle }\"\n @close=\"close\"\n >\n <WhatsAppConversation\n ref=\"conversationRef\"\n v-bind=\"{ ...forwardedAttrs, ...conversationProps }\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n :with-header=\"props.withHeader ?? false\"\n >\n <template v-for=\"name in slotNames\" #[name]=\"slotProps\">\n <slot :name=\"name\" v-bind=\"(slotProps ?? {}) as any\" />\n </template>\n </WhatsAppConversation>\n </Modal>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppInboxModalComponent from './WhatsAppInboxModal.vue'\nimport type { WhatsAppInboxModalFactory } from './WhatsAppInboxModal.types'\nimport classes from './WhatsAppInboxModal.module.css'\n\nexport const WhatsAppInboxModal = factory<WhatsAppInboxModalFactory>(WhatsAppInboxModalComponent, {\n classes,\n})\n\nexport type {\n WhatsAppInboxModalConversationProps,\n WhatsAppInboxModalEmits,\n WhatsAppInboxModalFactory,\n WhatsAppInboxModalOwnProps,\n WhatsAppInboxModalProps,\n WhatsAppInboxModalStylesNames,\n} from './WhatsAppInboxModal.types'\n",".drawerRoot {\n display: contents;\n}\n\n/*\n * A column layout is what keeps the composer pinned to the bottom of the drawer: without it the\n * body grows past the viewport and the user has to scroll before they can type.\n */\n.drawerContent {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n}\n\n.drawerBody {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n padding: 0;\n}\n","<script lang=\"ts\">\nconst defaultProps = {\n opened: false,\n position: 'right',\n size: 'md',\n focusComposerOnOpen: true,\n} as const\n\nconst DRAWER_OWN_PROPS = new Set([\n 'opened',\n 'position',\n 'size',\n 'title',\n 'focusComposerOnOpen',\n 'drawerProps',\n 'classNames',\n 'styles',\n 'vars',\n 'unstyled',\n])\n\nexport { defaultProps, DRAWER_OWN_PROPS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch, type CSSProperties } from 'vue'\nimport { Drawer, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationSlots } from '../../component-props'\nimport { getContactDisplayName } from '../../utils'\nimport { WhatsAppConversation } from '../WhatsAppConversation'\nimport type { WhatsAppConversationExposed } from '../WhatsAppConversation'\nimport type { WhatsAppInboxDrawerOwnProps } from './WhatsAppInboxDrawer.types'\nimport classes from './WhatsAppInboxDrawer.module.css'\n\ndefineOptions({\n name: 'WhatsAppInboxDrawer',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInboxDrawerOwnProps>(), {\n opened: undefined,\n position: undefined,\n size: undefined,\n title: undefined,\n focusComposerOnOpen: undefined,\n drawerProps: undefined,\n conversation: undefined,\n conversationId: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n withBack: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\n/**\n * Only the drawer's own events are declared; conversation listeners fall through as attributes\n * and are spread onto `WhatsAppConversation`. The full list stays part of the public type\n * through `WhatsAppInboxDrawerEmits`.\n */\nconst emit = defineEmits<{\n 'update:opened': [opened: boolean]\n close: []\n}>()\n\ndefineSlots<WhatsAppConversationSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInboxDrawer', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInboxDrawer',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'drawerRoot',\n})\n\nconst conversationProps = computed(() => {\n const result: Record<string, unknown> = {}\n\n for (const key of Object.keys(props)) {\n if (!DRAWER_OWN_PROPS.has(key)) {\n result[key] = (props as Record<string, unknown>)[key]\n }\n }\n\n return result\n})\n\nconst forwardedAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n\n return rest\n})\n\n/**\n * `getStyles` returns the class list as an array, which `Drawer`'s `classNames` record does not\n * accept; joining it keeps the Styles API working through the drawer.\n */\nconst bodyClassName = computed(() =>\n (getStyles('drawerBody').class as unknown[]).filter(Boolean).join(' '),\n)\nconst bodyStyle = computed(() => getStyles('drawerBody').style as CSSProperties)\nconst contentClassName = computed(() =>\n (getStyles('drawerContent').class as unknown[]).filter(Boolean).join(' '),\n)\n\nconst slotNames = computed(() => Object.keys(slots) as (keyof WhatsAppConversationSlots)[])\n\nconst conversationRef = ref<WhatsAppConversationExposed | null>(null)\n\nconst title = computed(() => {\n if (props.title !== undefined) {\n return props.title\n }\n\n return props.conversation\n ? getContactDisplayName(props.conversation)\n : config.labels.conversationsLabel\n})\n\nfunction close() {\n emit('update:opened', false)\n emit('close')\n}\n\nwatch(\n () => props.opened,\n (opened) => {\n if (opened && props.focusComposerOnOpen) {\n void nextTick(() => conversationRef.value?.focusComposer())\n }\n },\n)\n</script>\n\n<template>\n <Drawer\n v-bind=\"props.drawerProps\"\n :opened=\"Boolean(props.opened)\"\n :position=\"props.position\"\n :size=\"props.size\"\n :title=\"title\"\n :class=\"getStyles('drawerRoot').class\"\n :style=\"getStyles('drawerRoot').style\"\n :class-names=\"{ content: contentClassName, body: bodyClassName }\"\n :styles=\"{ body: bodyStyle }\"\n @close=\"close\"\n >\n <WhatsAppConversation\n ref=\"conversationRef\"\n v-bind=\"{ ...forwardedAttrs, ...conversationProps }\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n :with-header=\"props.withHeader ?? false\"\n >\n <template v-for=\"name in slotNames\" #[name]=\"slotProps\">\n <slot :name=\"name\" v-bind=\"(slotProps ?? {}) as any\" />\n </template>\n </WhatsAppConversation>\n </Drawer>\n</template>\n","<script lang=\"ts\">\nconst defaultProps = {\n opened: false,\n position: 'right',\n size: 'md',\n focusComposerOnOpen: true,\n} as const\n\nconst DRAWER_OWN_PROPS = new Set([\n 'opened',\n 'position',\n 'size',\n 'title',\n 'focusComposerOnOpen',\n 'drawerProps',\n 'classNames',\n 'styles',\n 'vars',\n 'unstyled',\n])\n\nexport { defaultProps, DRAWER_OWN_PROPS }\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useAttrs, useSlots, watch, type CSSProperties } from 'vue'\nimport { Drawer, useProps, useStyles } from '@mantine-vue/core'\nimport { useWhatsAppInboxConfig } from '../../WhatsAppInbox.context'\nimport type { WhatsAppConversationSlots } from '../../component-props'\nimport { getContactDisplayName } from '../../utils'\nimport { WhatsAppConversation } from '../WhatsAppConversation'\nimport type { WhatsAppConversationExposed } from '../WhatsAppConversation'\nimport type { WhatsAppInboxDrawerOwnProps } from './WhatsAppInboxDrawer.types'\nimport classes from './WhatsAppInboxDrawer.module.css'\n\ndefineOptions({\n name: 'WhatsAppInboxDrawer',\n inheritAttrs: false,\n})\n\nconst rawProps = withDefaults(defineProps<WhatsAppInboxDrawerOwnProps>(), {\n opened: undefined,\n position: undefined,\n size: undefined,\n title: undefined,\n focusComposerOnOpen: undefined,\n drawerProps: undefined,\n conversation: undefined,\n conversationId: undefined,\n capabilities: undefined,\n messages: undefined,\n messagesLoading: undefined,\n messagesError: undefined,\n messagesPagination: undefined,\n uploads: undefined,\n templates: undefined,\n templatesLoading: undefined,\n templatesError: undefined,\n draft: undefined,\n sending: undefined,\n sendError: undefined,\n replyTo: undefined,\n withHeader: undefined,\n withComposer: undefined,\n withBack: undefined,\n withContactToggle: undefined,\n contactPanelOpened: undefined,\n focusComposerOnChange: undefined,\n headerProps: undefined,\n messageListProps: undefined,\n composerProps: undefined,\n labels: undefined,\n renderMessage: undefined,\n renderMessageContent: undefined,\n classNames: undefined,\n styles: undefined,\n vars: undefined,\n})\n\n/**\n * Only the drawer's own events are declared; conversation listeners fall through as attributes\n * and are spread onto `WhatsAppConversation`. The full list stays part of the public type\n * through `WhatsAppInboxDrawerEmits`.\n */\nconst emit = defineEmits<{\n 'update:opened': [opened: boolean]\n close: []\n}>()\n\ndefineSlots<WhatsAppConversationSlots>()\n\nconst slots = useSlots()\nconst attrs = useAttrs()\nconst props = useProps('WhatsAppInboxDrawer', defaultProps, rawProps)\nconst config = useWhatsAppInboxConfig(() => props.labels)\n\nconst getStyles = useStyles({\n name: 'WhatsAppInboxDrawer',\n props,\n classes,\n get className() {\n return attrs.class\n },\n get style() {\n return attrs.style as any\n },\n classNames: props.classNames as any,\n styles: props.styles as any,\n unstyled: props.unstyled,\n vars: props.vars as any,\n rootSelector: 'drawerRoot',\n})\n\nconst conversationProps = computed(() => {\n const result: Record<string, unknown> = {}\n\n for (const key of Object.keys(props)) {\n if (!DRAWER_OWN_PROPS.has(key)) {\n result[key] = (props as Record<string, unknown>)[key]\n }\n }\n\n return result\n})\n\nconst forwardedAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n\n return rest\n})\n\n/**\n * `getStyles` returns the class list as an array, which `Drawer`'s `classNames` record does not\n * accept; joining it keeps the Styles API working through the drawer.\n */\nconst bodyClassName = computed(() =>\n (getStyles('drawerBody').class as unknown[]).filter(Boolean).join(' '),\n)\nconst bodyStyle = computed(() => getStyles('drawerBody').style as CSSProperties)\nconst contentClassName = computed(() =>\n (getStyles('drawerContent').class as unknown[]).filter(Boolean).join(' '),\n)\n\nconst slotNames = computed(() => Object.keys(slots) as (keyof WhatsAppConversationSlots)[])\n\nconst conversationRef = ref<WhatsAppConversationExposed | null>(null)\n\nconst title = computed(() => {\n if (props.title !== undefined) {\n return props.title\n }\n\n return props.conversation\n ? getContactDisplayName(props.conversation)\n : config.labels.conversationsLabel\n})\n\nfunction close() {\n emit('update:opened', false)\n emit('close')\n}\n\nwatch(\n () => props.opened,\n (opened) => {\n if (opened && props.focusComposerOnOpen) {\n void nextTick(() => conversationRef.value?.focusComposer())\n }\n },\n)\n</script>\n\n<template>\n <Drawer\n v-bind=\"props.drawerProps\"\n :opened=\"Boolean(props.opened)\"\n :position=\"props.position\"\n :size=\"props.size\"\n :title=\"title\"\n :class=\"getStyles('drawerRoot').class\"\n :style=\"getStyles('drawerRoot').style\"\n :class-names=\"{ content: contentClassName, body: bodyClassName }\"\n :styles=\"{ body: bodyStyle }\"\n @close=\"close\"\n >\n <WhatsAppConversation\n ref=\"conversationRef\"\n v-bind=\"{ ...forwardedAttrs, ...conversationProps }\"\n :labels=\"props.labels\"\n :class-names=\"props.classNames as any\"\n :styles=\"props.styles as any\"\n :unstyled=\"props.unstyled\"\n :with-header=\"props.withHeader ?? false\"\n >\n <template v-for=\"name in slotNames\" #[name]=\"slotProps\">\n <slot :name=\"name\" v-bind=\"(slotProps ?? {}) as any\" />\n </template>\n </WhatsAppConversation>\n </Drawer>\n</template>\n","import { factory } from '@mantine-vue/core'\nimport WhatsAppInboxDrawerComponent from './WhatsAppInboxDrawer.vue'\nimport type { WhatsAppInboxDrawerFactory } from './WhatsAppInboxDrawer.types'\nimport classes from './WhatsAppInboxDrawer.module.css'\n\nexport const WhatsAppInboxDrawer = factory<WhatsAppInboxDrawerFactory>(\n WhatsAppInboxDrawerComponent,\n { classes },\n)\n\nexport type {\n WhatsAppInboxDrawerConversationProps,\n WhatsAppInboxDrawerEmits,\n WhatsAppInboxDrawerFactory,\n WhatsAppInboxDrawerOwnProps,\n WhatsAppInboxDrawerProps,\n WhatsAppInboxDrawerStylesNames,\n} from './WhatsAppInboxDrawer.types'\n"],"mappings":"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"}
|