@rapidmx/web-client 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (897) hide show
  1. package/README.md +48 -14
  2. package/apps/admin/_layout.tsx +2 -2
  3. package/apps/admin/audit-log/index.tsx +4 -4
  4. package/apps/admin/branding/index.tsx +3 -3
  5. package/apps/admin/data-requests/index.tsx +8 -8
  6. package/apps/admin/distribution-lists/[uid].tsx +3 -3
  7. package/apps/admin/distribution-lists/index.tsx +4 -4
  8. package/apps/admin/distribution-lists/new/index.tsx +5 -5
  9. package/apps/admin/domains/[uid].tsx +6 -6
  10. package/apps/admin/domains/index.tsx +4 -4
  11. package/apps/admin/domains/new/index.tsx +5 -5
  12. package/apps/admin/encryption-policy/index.tsx +1 -1
  13. package/apps/admin/escrow-scopes/[uid].tsx +7 -7
  14. package/apps/admin/escrow-scopes/index.tsx +4 -4
  15. package/apps/admin/escrow-scopes/new/index.tsx +5 -5
  16. package/apps/admin/index.tsx +6 -6
  17. package/apps/admin/ingest-queue/index.tsx +4 -4
  18. package/apps/admin/mailbox-policy/index.tsx +1 -1
  19. package/apps/admin/mailboxes/[uid].tsx +5 -5
  20. package/apps/admin/quarantine/index.tsx +5 -5
  21. package/apps/admin/retention-policy/index.tsx +3 -3
  22. package/apps/admin/signing-certificates/index.tsx +5 -5
  23. package/apps/admin/transport-rules/[uid].tsx +5 -5
  24. package/apps/admin/transport-rules/_transportRuleConfig.tsx +3 -3
  25. package/apps/admin/transport-rules/index.tsx +4 -4
  26. package/apps/admin/transport-rules/new/index.tsx +5 -5
  27. package/apps/escrow/_layout.tsx +1 -1
  28. package/apps/escrow/audit-log/index.tsx +4 -4
  29. package/apps/escrow/index.tsx +4 -4
  30. package/apps/escrow/matters/[uid].tsx +10 -10
  31. package/apps/escrow/matters/new/index.tsx +6 -6
  32. package/apps/shared/appearance/AppearanceForm.tsx +3 -3
  33. package/apps/shared/appearance/AppearanceHead.tsx +1 -1
  34. package/apps/shared/appearance/AppearanceProvider.tsx +3 -3
  35. package/apps/shared/appearance/appearanceCache.ts +1 -1
  36. package/apps/shared/appearance/appearanceContext.ts +1 -1
  37. package/apps/shared/appearance/theme.ts +1 -1
  38. package/apps/shared/auth/adminAccess.ts +1 -1
  39. package/apps/shared/calendar/bookingPlugin.ts +1 -1
  40. package/apps/shared/calendar/calendarLiveUpdates.ts +1 -1
  41. package/apps/shared/calendar/calendarReminders.ts +1 -1
  42. package/apps/shared/calendar/useCalendarReminders.ts +1 -1
  43. package/apps/shared/components/admin/diagnostics/DiagnosticsManager.tsx +1 -1
  44. package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +2 -2
  45. package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +2 -2
  46. package/apps/shared/components/admin/diagnostics/PackagesTable.tsx +1 -1
  47. package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
  48. package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +2 -2
  49. package/apps/shared/components/admin/diagnostics/VersionsPanel.tsx +1 -1
  50. package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +1 -1
  51. package/apps/shared/components/admin/diagnostics/format.ts +1 -1
  52. package/apps/shared/components/admin/diagnostics/logClient.ts +1 -1
  53. package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
  54. package/apps/shared/components/admin/elevation.ts +1 -1
  55. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +3 -3
  56. package/apps/shared/components/admin/layout/AdminShell.tsx +8 -8
  57. package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +6 -6
  58. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +10 -8
  59. package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +4 -4
  60. package/apps/shared/components/admin/mailboxes/MailboxTable.tsx +1 -1
  61. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +19 -14
  62. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +5 -5
  63. package/apps/shared/components/admin/settings/BrandingForm.tsx +5 -5
  64. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
  65. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +4 -4
  66. package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +2 -2
  67. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +32 -27
  68. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +4 -4
  69. package/apps/shared/components/admin/settings/PluginsManager.tsx +5 -5
  70. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +5 -5
  71. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +7 -7
  72. package/apps/shared/components/admin/setup/SetupWizard.tsx +28 -24
  73. package/apps/shared/components/admin/signOut.ts +1 -1
  74. package/apps/shared/components/admin/usePagedList.tsx +2 -2
  75. package/apps/shared/components/calendar/AppointmentQuickForm.tsx +3 -3
  76. package/apps/shared/components/calendar/CalendarListSidebar.tsx +3 -3
  77. package/apps/shared/components/calendar/DescriptionEditor.tsx +1 -1
  78. package/apps/shared/components/calendar/EventDescriptionView.tsx +1 -1
  79. package/apps/shared/components/calendar/EventDetails.tsx +16 -14
  80. package/apps/shared/components/calendar/EventEditor.tsx +54 -39
  81. package/apps/shared/components/calendar/EventExpandedForm.tsx +3 -3
  82. package/apps/shared/components/calendar/EventFormParts.tsx +2 -2
  83. package/apps/shared/components/calendar/EventModal.tsx +5 -5
  84. package/apps/shared/components/calendar/EventQuickForm.tsx +3 -3
  85. package/apps/shared/components/calendar/EventShell.tsx +1 -1
  86. package/apps/shared/components/calendar/FindATime.tsx +6 -4
  87. package/apps/shared/components/calendar/GuestInput.tsx +2 -2
  88. package/apps/shared/components/calendar/MonthView.tsx +2 -2
  89. package/apps/shared/components/calendar/QuickCreateFaces.tsx +1 -1
  90. package/apps/shared/components/calendar/QuickFaceFrame.tsx +1 -1
  91. package/apps/shared/components/calendar/RecurrenceEditor.tsx +2 -2
  92. package/apps/shared/components/calendar/RequestChangeForm.tsx +8 -6
  93. package/apps/shared/components/calendar/ResourcePicker.tsx +7 -5
  94. package/apps/shared/components/calendar/SplitDayView.tsx +1 -1
  95. package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
  96. package/apps/shared/components/calendar/TimeGridView.tsx +5 -3
  97. package/apps/shared/components/calendar/allDay.ts +2 -2
  98. package/apps/shared/components/calendar/eventDialogFields.ts +3 -3
  99. package/apps/shared/components/calendar/eventForm.ts +3 -3
  100. package/apps/shared/components/calendar/eventFormat.ts +3 -3
  101. package/apps/shared/components/calendar/findTimeGrid.ts +2 -2
  102. package/apps/shared/components/calendar/layout/CalendarShell.tsx +11 -9
  103. package/apps/shared/components/contacts/ContactDetailPane.tsx +4 -4
  104. package/apps/shared/components/contacts/ContactForm.tsx +27 -17
  105. package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
  106. package/apps/shared/components/contacts/KeyChangeReview.tsx +5 -5
  107. package/apps/shared/components/contacts/contactKeys.ts +3 -3
  108. package/apps/shared/components/contacts/layout/ContactsShell.tsx +9 -7
  109. package/apps/shared/components/escrow/layout/EscrowShell.tsx +6 -6
  110. package/apps/shared/components/forms/StringListField.tsx +1 -1
  111. package/apps/shared/components/layout/AppShell.tsx +12 -10
  112. package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
  113. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +9 -9
  114. package/apps/shared/components/layout/MailboxProvisioning.tsx +8 -6
  115. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
  116. package/apps/shared/components/layout/ThemeSwitch.tsx +1 -1
  117. package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
  118. package/apps/shared/components/layout/UserMenu.tsx +6 -4
  119. package/apps/shared/components/mail/ConversationList.tsx +25 -10
  120. package/apps/shared/components/mail/ConversationThreadPane.tsx +33 -17
  121. package/apps/shared/components/mail/InviteCard.tsx +11 -9
  122. package/apps/shared/components/mail/LazyReadingPane.tsx +2 -2
  123. package/apps/shared/components/mail/MailAddress.tsx +1 -1
  124. package/apps/shared/components/mail/MailListToolbar.tsx +2 -2
  125. package/apps/shared/components/mail/MailSelectionBar.tsx +2 -2
  126. package/apps/shared/components/mail/MenuButton.tsx +1 -1
  127. package/apps/shared/components/mail/MessageDetailPane.tsx +69 -48
  128. package/apps/shared/components/mail/MoveToFolderDialog.tsx +8 -6
  129. package/apps/shared/components/mail/OutboxRowStatus.tsx +1 -1
  130. package/apps/shared/components/mail/PermanentDeleteDialog.tsx +2 -2
  131. package/apps/shared/components/mail/compose/ComposeContext.tsx +14 -3
  132. package/apps/shared/components/mail/compose/ComposeWindow.tsx +34 -30
  133. package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +4 -4
  134. package/apps/shared/components/mail/compose/EmojiPicker.tsx +2 -2
  135. package/apps/shared/components/mail/compose/GifPicker.tsx +3 -3
  136. package/apps/shared/components/mail/compose/RecipientInput.tsx +1 -1
  137. package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
  138. package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
  139. package/apps/shared/components/mail/compose/quotedBody.ts +5 -5
  140. package/apps/shared/components/mail/compose/recipients.ts +1 -1
  141. package/apps/shared/components/mail/invite/InviteRowChip.tsx +10 -14
  142. package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +11 -9
  143. package/apps/shared/components/mail/invite/InviteTimeline.tsx +1 -1
  144. package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +2 -2
  145. package/apps/shared/components/mail/invite/inviteFormat.ts +2 -2
  146. package/apps/shared/components/mail/invite/inviteStore.ts +14 -6
  147. package/apps/shared/components/mail/labelMenu.tsx +9 -7
  148. package/apps/shared/components/mail/layout/MailShell.tsx +4 -4
  149. package/apps/shared/components/mail/listPreferences.ts +2 -2
  150. package/apps/shared/components/mail/pinnedSigners.ts +45 -19
  151. package/apps/shared/components/mail/reading/EncryptedBody.tsx +2 -2
  152. package/apps/shared/components/mail/reading/MessageBody.tsx +6 -6
  153. package/apps/shared/components/mail/reading/MessageCard.tsx +3 -3
  154. package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +3 -3
  155. package/apps/shared/components/mail/reading/PendingMessageCard.tsx +1 -1
  156. package/apps/shared/components/mail/reading/bodyContent.ts +3 -3
  157. package/apps/shared/components/mail/reading/bodyHtml.ts +1 -1
  158. package/apps/shared/components/mail/reading/conversationPrint.ts +76 -0
  159. package/apps/shared/components/mail/reading/messageExport.ts +1 -1
  160. package/apps/shared/components/mail/reading/printMessage.ts +46 -9
  161. package/apps/shared/components/mail/reading/useMessageActions.ts +28 -21
  162. package/apps/shared/components/mail/unreadStyle.tsx +1 -1
  163. package/apps/shared/components/mail/verificationSeals.ts +16 -12
  164. package/apps/shared/components/mail/writableMailboxes.ts +14 -7
  165. package/apps/shared/components/rules/RuleBuilder.tsx +1 -1
  166. package/apps/shared/components/settings/SigningCertificateCard.tsx +4 -4
  167. package/apps/shared/components/settings/layout/SettingsShell.tsx +8 -6
  168. package/apps/shared/components/sharing/PrincipalListField.tsx +1 -1
  169. package/apps/shared/components/sharing/PrincipalPicker.tsx +1 -1
  170. package/apps/shared/components/sharing/PrincipalResolver.tsx +4 -4
  171. package/apps/shared/components/tasks/TasksSidebar.tsx +7 -5
  172. package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -7
  173. package/apps/shared/keyboard/ShortcutsDialog.tsx +1 -1
  174. package/apps/shared/keyboard/keymap.ts +1 -0
  175. package/apps/shared/mail/decryptedMessages.ts +116 -0
  176. package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
  177. package/apps/shared/mail/folderCounts.ts +8 -4
  178. package/apps/shared/mail/folderOfType.ts +5 -3
  179. package/apps/shared/mail/folderTree.ts +1 -1
  180. package/apps/shared/mail/listSnapshots.ts +2 -2
  181. package/apps/shared/mail/messageReadState.ts +6 -5
  182. package/apps/shared/mail/newMailNotifications.ts +2 -2
  183. package/apps/shared/mail/outbox/composeBridge.ts +2 -2
  184. package/apps/shared/mail/outbox/outboxState.ts +1 -1
  185. package/apps/shared/mail/outbox/outgoingReplies.ts +2 -2
  186. package/apps/shared/mail/outbox/sendDecision.ts +2 -2
  187. package/apps/shared/mail/outbox/sendJob.ts +40 -35
  188. package/apps/shared/mail/outbox/sendOutcomes.ts +20 -15
  189. package/apps/shared/mail/outbox/useOutboxStatus.ts +5 -3
  190. package/apps/shared/mail/permanentDelete.ts +8 -7
  191. package/apps/shared/mail/primaryMailbox.ts +1 -1
  192. package/apps/shared/mail/reportNotices.ts +1 -1
  193. package/apps/shared/mail/senderBlocking.ts +36 -20
  194. package/apps/shared/mail/useMailConnection.ts +12 -10
  195. package/apps/shared/mail/useMailLiveUpdates.ts +3 -3
  196. package/apps/shared/mail/useMailboxUpdateAccess.ts +35 -11
  197. package/apps/shared/mail/useMarkMessageRead.ts +14 -7
  198. package/apps/shared/mail/useNewMailNotifications.ts +1 -1
  199. package/apps/shared/mail/usePermanentDelete.tsx +5 -3
  200. package/apps/shared/navigation/pageTitle.ts +1 -1
  201. package/apps/shared/notifications/NotificationCenter.tsx +1 -1
  202. package/apps/shared/notifications/NotificationHistoryDialog.tsx +2 -2
  203. package/apps/shared/notifications/apiErrors.ts +2 -2
  204. package/apps/shared/notifications/pushStatus.ts +1 -1
  205. package/apps/shared/notifications/systemErrors.ts +1 -1
  206. package/apps/shared/search/LocalIndexLifecycle.tsx +18 -12
  207. package/apps/shared/search/crossMailboxSearch.ts +3 -3
  208. package/apps/shared/search/localIndexBuilder.ts +24 -12
  209. package/apps/shared/search/localIndexKey.ts +1 -1
  210. package/apps/shared/search/localIndexRpcClient.ts +150 -30
  211. package/apps/shared/search/localIndexTransport.ts +84 -0
  212. package/apps/shared/search/localIndexWorker.ts +1 -1
  213. package/apps/shared/search/searchTier2.ts +3 -3
  214. package/apps/shared/signing/enrollmentTracker.ts +3 -3
  215. package/apps/shared/signing/enrollmentView.ts +1 -1
  216. package/apps/shared/signing/signingInfo.ts +1 -1
  217. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +6 -4
  218. package/apps/shared/styles/app.css +14 -23
  219. package/apps/www/_layout.tsx +2 -2
  220. package/apps/www/calendar/index.tsx +20 -18
  221. package/apps/www/contacts/[uid].tsx +8 -6
  222. package/apps/www/contacts/index.tsx +19 -17
  223. package/apps/www/index.tsx +68 -48
  224. package/apps/www/messages/[uid].tsx +11 -9
  225. package/apps/www/settings/auto-reply/index.tsx +6 -4
  226. package/apps/www/settings/blocked-senders/index.tsx +9 -7
  227. package/apps/www/settings/encryption/index.tsx +38 -32
  228. package/apps/www/settings/filters/[uid].tsx +19 -14
  229. package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
  230. package/apps/www/settings/filters/index.tsx +4 -4
  231. package/apps/www/settings/filters/new/index.tsx +10 -8
  232. package/apps/www/settings/labels/index.tsx +12 -10
  233. package/apps/www/settings/privacy/index.tsx +18 -14
  234. package/apps/www/settings/profile/index.tsx +16 -11
  235. package/apps/www/settings/read-receipts/index.tsx +17 -12
  236. package/apps/www/settings/sharing/index.tsx +6 -6
  237. package/apps/www/settings/signatures/[uid].tsx +5 -5
  238. package/apps/www/settings/signatures/index.tsx +4 -4
  239. package/apps/www/settings/signatures/new/index.tsx +4 -4
  240. package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
  241. package/apps/www/tasks/index.tsx +28 -23
  242. package/dist/apps/admin/_layout.d.ts +1 -1
  243. package/dist/apps/admin/_layout.js +1 -1
  244. package/dist/apps/admin/audit-log/index.d.ts +1 -1
  245. package/dist/apps/admin/audit-log/index.js +4 -4
  246. package/dist/apps/admin/branding/index.js +3 -3
  247. package/dist/apps/admin/data-requests/index.js +8 -8
  248. package/dist/apps/admin/distribution-lists/[uid].js +3 -3
  249. package/dist/apps/admin/distribution-lists/index.js +4 -4
  250. package/dist/apps/admin/distribution-lists/new/index.js +5 -5
  251. package/dist/apps/admin/domains/[uid].js +6 -6
  252. package/dist/apps/admin/domains/index.js +4 -4
  253. package/dist/apps/admin/domains/new/index.js +5 -5
  254. package/dist/apps/admin/encryption-policy/index.js +1 -1
  255. package/dist/apps/admin/escrow-scopes/[uid].d.ts +1 -1
  256. package/dist/apps/admin/escrow-scopes/[uid].js +7 -7
  257. package/dist/apps/admin/escrow-scopes/index.js +4 -4
  258. package/dist/apps/admin/escrow-scopes/new/index.js +5 -5
  259. package/dist/apps/admin/index.js +6 -6
  260. package/dist/apps/admin/ingest-queue/index.js +4 -4
  261. package/dist/apps/admin/mailbox-policy/index.js +1 -1
  262. package/dist/apps/admin/mailboxes/[uid].js +5 -5
  263. package/dist/apps/admin/quarantine/index.js +5 -5
  264. package/dist/apps/admin/retention-policy/index.js +3 -3
  265. package/dist/apps/admin/signing-certificates/index.js +5 -5
  266. package/dist/apps/admin/transport-rules/[uid].js +5 -5
  267. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +1 -1
  268. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +2 -2
  269. package/dist/apps/admin/transport-rules/index.js +4 -4
  270. package/dist/apps/admin/transport-rules/new/index.js +5 -5
  271. package/dist/apps/escrow/_layout.d.ts +1 -1
  272. package/dist/apps/escrow/audit-log/index.d.ts +1 -1
  273. package/dist/apps/escrow/audit-log/index.js +4 -4
  274. package/dist/apps/escrow/index.js +4 -4
  275. package/dist/apps/escrow/matters/[uid].js +10 -10
  276. package/dist/apps/escrow/matters/new/index.js +6 -6
  277. package/dist/apps/shared/appearance/AppearanceForm.js +3 -3
  278. package/dist/apps/shared/appearance/AppearanceHead.js +1 -1
  279. package/dist/apps/shared/appearance/AppearanceProvider.d.ts +1 -1
  280. package/dist/apps/shared/appearance/AppearanceProvider.js +3 -3
  281. package/dist/apps/shared/appearance/appearanceCache.d.ts +1 -1
  282. package/dist/apps/shared/appearance/appearanceCache.js +1 -1
  283. package/dist/apps/shared/appearance/appearanceContext.d.ts +1 -1
  284. package/dist/apps/shared/appearance/theme.d.ts +1 -1
  285. package/dist/apps/shared/auth/adminAccess.js +1 -1
  286. package/dist/apps/shared/calendar/bookingPlugin.js +1 -1
  287. package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +1 -1
  288. package/dist/apps/shared/calendar/calendarReminders.d.ts +1 -1
  289. package/dist/apps/shared/calendar/useCalendarReminders.js +1 -1
  290. package/dist/apps/shared/components/admin/diagnostics/DiagnosticsManager.js +1 -1
  291. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.d.ts +1 -1
  292. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +2 -2
  293. package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +2 -2
  294. package/dist/apps/shared/components/admin/diagnostics/PackagesTable.js +1 -1
  295. package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
  296. package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +2 -2
  297. package/dist/apps/shared/components/admin/diagnostics/VersionsPanel.js +1 -1
  298. package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.js +1 -1
  299. package/dist/apps/shared/components/admin/diagnostics/format.js +1 -1
  300. package/dist/apps/shared/components/admin/diagnostics/logClient.js +1 -1
  301. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +1 -1
  302. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
  303. package/dist/apps/shared/components/admin/elevation.js +1 -1
  304. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -3
  305. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  306. package/dist/apps/shared/components/admin/layout/AdminShell.js +7 -7
  307. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +1 -1
  308. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +6 -6
  309. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +1 -1
  310. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +10 -8
  311. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
  312. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +1 -1
  313. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +1 -1
  314. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +7 -5
  315. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +5 -5
  316. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +1 -1
  317. package/dist/apps/shared/components/admin/settings/BrandingForm.js +5 -5
  318. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +1 -1
  319. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +5 -5
  320. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +1 -1
  321. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +4 -4
  322. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +2 -2
  323. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +1 -1
  324. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +14 -12
  325. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +1 -1
  326. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +4 -4
  327. package/dist/apps/shared/components/admin/settings/PluginsManager.js +5 -5
  328. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +1 -1
  329. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +5 -5
  330. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +7 -7
  331. package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +4 -4
  332. package/dist/apps/shared/components/admin/setup/SetupWizard.js +27 -23
  333. package/dist/apps/shared/components/admin/signOut.js +1 -1
  334. package/dist/apps/shared/components/admin/usePagedList.js +2 -2
  335. package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +3 -3
  336. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +1 -1
  337. package/dist/apps/shared/components/calendar/CalendarListSidebar.js +2 -2
  338. package/dist/apps/shared/components/calendar/DescriptionEditor.js +1 -1
  339. package/dist/apps/shared/components/calendar/EventDescriptionView.js +1 -1
  340. package/dist/apps/shared/components/calendar/EventDetails.d.ts +2 -2
  341. package/dist/apps/shared/components/calendar/EventDetails.js +16 -14
  342. package/dist/apps/shared/components/calendar/EventEditor.d.ts +2 -2
  343. package/dist/apps/shared/components/calendar/EventEditor.js +22 -20
  344. package/dist/apps/shared/components/calendar/EventExpandedForm.js +2 -2
  345. package/dist/apps/shared/components/calendar/EventFormParts.d.ts +1 -1
  346. package/dist/apps/shared/components/calendar/EventFormParts.js +1 -1
  347. package/dist/apps/shared/components/calendar/EventModal.d.ts +2 -2
  348. package/dist/apps/shared/components/calendar/EventModal.js +3 -3
  349. package/dist/apps/shared/components/calendar/EventQuickForm.js +3 -3
  350. package/dist/apps/shared/components/calendar/EventShell.js +1 -1
  351. package/dist/apps/shared/components/calendar/FindATime.js +6 -4
  352. package/dist/apps/shared/components/calendar/GuestInput.d.ts +2 -2
  353. package/dist/apps/shared/components/calendar/MonthView.d.ts +1 -1
  354. package/dist/apps/shared/components/calendar/MonthView.js +1 -1
  355. package/dist/apps/shared/components/calendar/QuickCreateFaces.js +1 -1
  356. package/dist/apps/shared/components/calendar/QuickFaceFrame.js +1 -1
  357. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +1 -1
  358. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +1 -1
  359. package/dist/apps/shared/components/calendar/RequestChangeForm.js +8 -6
  360. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +1 -1
  361. package/dist/apps/shared/components/calendar/ResourcePicker.js +7 -5
  362. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +1 -1
  363. package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +1 -1
  364. package/dist/apps/shared/components/calendar/TaskQuickForm.js +9 -7
  365. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +1 -1
  366. package/dist/apps/shared/components/calendar/TimeGridView.js +2 -2
  367. package/dist/apps/shared/components/calendar/allDay.d.ts +2 -2
  368. package/dist/apps/shared/components/calendar/allDay.js +1 -1
  369. package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +2 -2
  370. package/dist/apps/shared/components/calendar/eventDialogFields.js +2 -2
  371. package/dist/apps/shared/components/calendar/eventForm.d.ts +3 -3
  372. package/dist/apps/shared/components/calendar/eventFormat.d.ts +1 -1
  373. package/dist/apps/shared/components/calendar/eventFormat.js +2 -2
  374. package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +1 -1
  375. package/dist/apps/shared/components/calendar/findTimeGrid.js +1 -1
  376. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
  377. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +11 -9
  378. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +1 -1
  379. package/dist/apps/shared/components/contacts/ContactDetailPane.js +2 -2
  380. package/dist/apps/shared/components/contacts/ContactForm.d.ts +2 -2
  381. package/dist/apps/shared/components/contacts/ContactForm.js +12 -8
  382. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +1 -1
  383. package/dist/apps/shared/components/contacts/ContactsSidebar.js +7 -5
  384. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +1 -1
  385. package/dist/apps/shared/components/contacts/KeyChangeReview.js +5 -5
  386. package/dist/apps/shared/components/contacts/contactKeys.d.ts +2 -2
  387. package/dist/apps/shared/components/contacts/contactKeys.js +2 -2
  388. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
  389. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +9 -7
  390. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +6 -6
  391. package/dist/apps/shared/components/forms/StringListField.js +1 -1
  392. package/dist/apps/shared/components/layout/AppShell.d.ts +2 -2
  393. package/dist/apps/shared/components/layout/AppShell.js +11 -9
  394. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +1 -1
  395. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +1 -1
  396. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +9 -9
  397. package/dist/apps/shared/components/layout/MailboxProvisioning.js +8 -6
  398. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +1 -1
  399. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +9 -9
  400. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +2 -2
  401. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +5 -5
  402. package/dist/apps/shared/components/layout/UserMenu.js +6 -4
  403. package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
  404. package/dist/apps/shared/components/mail/ConversationList.js +23 -8
  405. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
  406. package/dist/apps/shared/components/mail/ConversationThreadPane.js +19 -13
  407. package/dist/apps/shared/components/mail/InviteCard.js +10 -8
  408. package/dist/apps/shared/components/mail/LazyReadingPane.js +2 -2
  409. package/dist/apps/shared/components/mail/MailAddress.d.ts +1 -1
  410. package/dist/apps/shared/components/mail/MailAddress.js +1 -1
  411. package/dist/apps/shared/components/mail/MailListToolbar.d.ts +2 -2
  412. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +2 -2
  413. package/dist/apps/shared/components/mail/MenuButton.js +1 -1
  414. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +3 -3
  415. package/dist/apps/shared/components/mail/MessageDetailPane.js +61 -46
  416. package/dist/apps/shared/components/mail/MoveToFolderDialog.d.ts +1 -1
  417. package/dist/apps/shared/components/mail/MoveToFolderDialog.js +8 -6
  418. package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +1 -1
  419. package/dist/apps/shared/components/mail/PermanentDeleteDialog.js +2 -2
  420. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +10 -1
  421. package/dist/apps/shared/components/mail/compose/ComposeContext.js +4 -2
  422. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +34 -30
  423. package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +4 -4
  424. package/dist/apps/shared/components/mail/compose/EmojiPicker.js +2 -2
  425. package/dist/apps/shared/components/mail/compose/GifPicker.js +3 -3
  426. package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +1 -1
  427. package/dist/apps/shared/components/mail/compose/RecipientInput.js +1 -1
  428. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.js +1 -1
  429. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +2 -2
  430. package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +1 -1
  431. package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +3 -3
  432. package/dist/apps/shared/components/mail/compose/quotedBody.js +3 -3
  433. package/dist/apps/shared/components/mail/compose/recipients.d.ts +1 -1
  434. package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +3 -3
  435. package/dist/apps/shared/components/mail/invite/InviteRowChip.js +7 -9
  436. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +2 -2
  437. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +11 -9
  438. package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +1 -1
  439. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +1 -1
  440. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +1 -1
  441. package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +2 -2
  442. package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +9 -3
  443. package/dist/apps/shared/components/mail/invite/inviteStore.js +13 -6
  444. package/dist/apps/shared/components/mail/labelMenu.d.ts +1 -1
  445. package/dist/apps/shared/components/mail/labelMenu.js +9 -7
  446. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +1 -1
  447. package/dist/apps/shared/components/mail/layout/MailShell.js +3 -3
  448. package/dist/apps/shared/components/mail/listPreferences.d.ts +2 -2
  449. package/dist/apps/shared/components/mail/listPreferences.js +1 -1
  450. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +12 -5
  451. package/dist/apps/shared/components/mail/pinnedSigners.js +37 -18
  452. package/dist/apps/shared/components/mail/reading/EncryptedBody.js +2 -2
  453. package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +2 -2
  454. package/dist/apps/shared/components/mail/reading/MessageBody.js +4 -4
  455. package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +1 -1
  456. package/dist/apps/shared/components/mail/reading/MessageCard.js +2 -2
  457. package/dist/apps/shared/components/mail/reading/MessageSourceDialog.js +3 -3
  458. package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +1 -1
  459. package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +2 -2
  460. package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -2
  461. package/dist/apps/shared/components/mail/reading/bodyHtml.js +1 -1
  462. package/dist/apps/shared/components/mail/reading/conversationPrint.d.ts +15 -0
  463. package/dist/apps/shared/components/mail/reading/conversationPrint.js +69 -0
  464. package/dist/apps/shared/components/mail/reading/messageExport.js +1 -1
  465. package/dist/apps/shared/components/mail/reading/printMessage.d.ts +9 -3
  466. package/dist/apps/shared/components/mail/reading/printMessage.js +33 -6
  467. package/dist/apps/shared/components/mail/reading/useMessageActions.d.ts +1 -1
  468. package/dist/apps/shared/components/mail/reading/useMessageActions.js +18 -16
  469. package/dist/apps/shared/components/mail/unreadStyle.d.ts +1 -1
  470. package/dist/apps/shared/components/mail/verificationSeals.d.ts +27 -6
  471. package/dist/apps/shared/components/mail/verificationSeals.js +15 -11
  472. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +8 -3
  473. package/dist/apps/shared/components/mail/writableMailboxes.js +12 -6
  474. package/dist/apps/shared/components/rules/RuleBuilder.js +1 -1
  475. package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +1 -1
  476. package/dist/apps/shared/components/settings/SigningCertificateCard.js +3 -3
  477. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
  478. package/dist/apps/shared/components/settings/layout/SettingsShell.js +8 -6
  479. package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +1 -1
  480. package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +1 -1
  481. package/dist/apps/shared/components/sharing/PrincipalPicker.js +1 -1
  482. package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +1 -1
  483. package/dist/apps/shared/components/sharing/PrincipalResolver.js +3 -3
  484. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +1 -1
  485. package/dist/apps/shared/components/tasks/TasksSidebar.js +7 -5
  486. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
  487. package/dist/apps/shared/components/tasks/layout/TasksShell.js +9 -7
  488. package/dist/apps/shared/keyboard/ShortcutsDialog.js +1 -1
  489. package/dist/apps/shared/keyboard/keymap.d.ts +6 -0
  490. package/dist/apps/shared/keyboard/keymap.js +1 -0
  491. package/dist/apps/shared/mail/decryptedMessages.d.ts +27 -0
  492. package/dist/apps/shared/mail/decryptedMessages.js +97 -0
  493. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -3
  494. package/dist/apps/shared/mail/findWellKnownFolderUid.js +5 -4
  495. package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
  496. package/dist/apps/shared/mail/folderCounts.js +6 -4
  497. package/dist/apps/shared/mail/folderOfType.d.ts +3 -2
  498. package/dist/apps/shared/mail/folderOfType.js +4 -4
  499. package/dist/apps/shared/mail/folderTree.d.ts +1 -1
  500. package/dist/apps/shared/mail/listSnapshots.d.ts +2 -2
  501. package/dist/apps/shared/mail/messageReadState.d.ts +4 -3
  502. package/dist/apps/shared/mail/messageReadState.js +5 -5
  503. package/dist/apps/shared/mail/newMailNotifications.d.ts +1 -1
  504. package/dist/apps/shared/mail/newMailNotifications.js +1 -1
  505. package/dist/apps/shared/mail/outbox/composeBridge.d.ts +2 -2
  506. package/dist/apps/shared/mail/outbox/outboxState.d.ts +1 -1
  507. package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +2 -2
  508. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +2 -2
  509. package/dist/apps/shared/mail/outbox/sendDecision.js +1 -1
  510. package/dist/apps/shared/mail/outbox/sendJob.d.ts +10 -6
  511. package/dist/apps/shared/mail/outbox/sendJob.js +39 -35
  512. package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +6 -3
  513. package/dist/apps/shared/mail/outbox/sendOutcomes.js +19 -15
  514. package/dist/apps/shared/mail/outbox/useOutboxStatus.js +5 -3
  515. package/dist/apps/shared/mail/permanentDelete.d.ts +4 -3
  516. package/dist/apps/shared/mail/permanentDelete.js +8 -8
  517. package/dist/apps/shared/mail/primaryMailbox.d.ts +1 -1
  518. package/dist/apps/shared/mail/primaryMailbox.js +1 -1
  519. package/dist/apps/shared/mail/reportNotices.d.ts +1 -1
  520. package/dist/apps/shared/mail/senderBlocking.d.ts +5 -4
  521. package/dist/apps/shared/mail/senderBlocking.js +19 -16
  522. package/dist/apps/shared/mail/useMailConnection.d.ts +1 -1
  523. package/dist/apps/shared/mail/useMailConnection.js +12 -10
  524. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +2 -2
  525. package/dist/apps/shared/mail/useMailLiveUpdates.js +2 -2
  526. package/dist/apps/shared/mail/useMailboxUpdateAccess.d.ts +3 -2
  527. package/dist/apps/shared/mail/useMailboxUpdateAccess.js +31 -10
  528. package/dist/apps/shared/mail/useMarkMessageRead.d.ts +1 -1
  529. package/dist/apps/shared/mail/useMarkMessageRead.js +5 -3
  530. package/dist/apps/shared/mail/useNewMailNotifications.d.ts +1 -1
  531. package/dist/apps/shared/mail/usePermanentDelete.d.ts +1 -1
  532. package/dist/apps/shared/mail/usePermanentDelete.js +4 -2
  533. package/dist/apps/shared/navigation/pageTitle.d.ts +1 -1
  534. package/dist/apps/shared/notifications/NotificationCenter.js +1 -1
  535. package/dist/apps/shared/notifications/NotificationHistoryDialog.js +2 -2
  536. package/dist/apps/shared/notifications/apiErrors.js +2 -2
  537. package/dist/apps/shared/notifications/pushStatus.js +1 -1
  538. package/dist/apps/shared/notifications/systemErrors.js +1 -1
  539. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +2 -2
  540. package/dist/apps/shared/search/LocalIndexLifecycle.js +15 -10
  541. package/dist/apps/shared/search/crossMailboxSearch.d.ts +1 -1
  542. package/dist/apps/shared/search/crossMailboxSearch.js +2 -2
  543. package/dist/apps/shared/search/localIndexBuilder.d.ts +4 -3
  544. package/dist/apps/shared/search/localIndexBuilder.js +15 -12
  545. package/dist/apps/shared/search/localIndexKey.js +1 -1
  546. package/dist/apps/shared/search/localIndexRpcClient.d.ts +43 -31
  547. package/dist/apps/shared/search/localIndexRpcClient.js +113 -20
  548. package/dist/apps/shared/search/localIndexTransport.d.ts +77 -0
  549. package/dist/apps/shared/search/localIndexTransport.js +1 -0
  550. package/dist/apps/shared/search/localIndexWorker.d.ts +1 -1
  551. package/dist/apps/shared/search/searchTier2.d.ts +3 -3
  552. package/dist/apps/shared/signing/enrollmentTracker.d.ts +1 -1
  553. package/dist/apps/shared/signing/enrollmentTracker.js +3 -3
  554. package/dist/apps/shared/signing/enrollmentView.d.ts +1 -1
  555. package/dist/apps/shared/signing/signingInfo.d.ts +1 -1
  556. package/dist/apps/shared/signing/signingInfo.js +1 -1
  557. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +1 -1
  558. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +5 -3
  559. package/dist/apps/shared/styles/app.css +14 -23
  560. package/dist/apps/www/_layout.d.ts +1 -1
  561. package/dist/apps/www/_layout.js +1 -1
  562. package/dist/apps/www/calendar/index.d.ts +1 -1
  563. package/dist/apps/www/calendar/index.js +20 -18
  564. package/dist/apps/www/contacts/[uid].d.ts +1 -1
  565. package/dist/apps/www/contacts/[uid].js +8 -6
  566. package/dist/apps/www/contacts/index.d.ts +1 -1
  567. package/dist/apps/www/contacts/index.js +19 -17
  568. package/dist/apps/www/index.d.ts +1 -1
  569. package/dist/apps/www/index.js +64 -50
  570. package/dist/apps/www/messages/[uid].d.ts +1 -1
  571. package/dist/apps/www/messages/[uid].js +11 -9
  572. package/dist/apps/www/settings/appearance/index.d.ts +1 -1
  573. package/dist/apps/www/settings/auto-reply/index.d.ts +1 -1
  574. package/dist/apps/www/settings/auto-reply/index.js +6 -4
  575. package/dist/apps/www/settings/blocked-senders/index.d.ts +1 -1
  576. package/dist/apps/www/settings/blocked-senders/index.js +6 -4
  577. package/dist/apps/www/settings/encryption/index.d.ts +1 -1
  578. package/dist/apps/www/settings/encryption/index.js +31 -29
  579. package/dist/apps/www/settings/filters/[uid].d.ts +1 -1
  580. package/dist/apps/www/settings/filters/[uid].js +11 -9
  581. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +2 -2
  582. package/dist/apps/www/settings/filters/index.d.ts +1 -1
  583. package/dist/apps/www/settings/filters/index.js +4 -4
  584. package/dist/apps/www/settings/filters/new/index.d.ts +1 -1
  585. package/dist/apps/www/settings/filters/new/index.js +10 -8
  586. package/dist/apps/www/settings/labels/index.d.ts +1 -1
  587. package/dist/apps/www/settings/labels/index.js +12 -10
  588. package/dist/apps/www/settings/privacy/index.d.ts +1 -1
  589. package/dist/apps/www/settings/privacy/index.js +18 -14
  590. package/dist/apps/www/settings/profile/index.d.ts +1 -1
  591. package/dist/apps/www/settings/profile/index.js +7 -5
  592. package/dist/apps/www/settings/read-receipts/index.d.ts +1 -1
  593. package/dist/apps/www/settings/read-receipts/index.js +5 -3
  594. package/dist/apps/www/settings/sharing/index.d.ts +1 -1
  595. package/dist/apps/www/settings/sharing/index.js +6 -6
  596. package/dist/apps/www/settings/signatures/[uid].d.ts +1 -1
  597. package/dist/apps/www/settings/signatures/[uid].js +5 -5
  598. package/dist/apps/www/settings/signatures/index.d.ts +1 -1
  599. package/dist/apps/www/settings/signatures/index.js +4 -4
  600. package/dist/apps/www/settings/signatures/new/index.d.ts +1 -1
  601. package/dist/apps/www/settings/signatures/new/index.js +4 -4
  602. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +1 -1
  603. package/dist/apps/www/settings/signatures/signatureDefaults.js +1 -1
  604. package/dist/apps/www/tasks/index.d.ts +1 -1
  605. package/dist/apps/www/tasks/index.js +17 -15
  606. package/dist/lib/admin/auditLogApi.d.ts +32 -0
  607. package/dist/lib/admin/auditLogApi.js +27 -0
  608. package/dist/lib/admin/distributionListsApi.d.ts +47 -0
  609. package/dist/lib/admin/distributionListsApi.js +34 -0
  610. package/dist/lib/admin/domainsApi.d.ts +75 -0
  611. package/dist/lib/admin/domainsApi.js +44 -0
  612. package/dist/lib/admin/escrowAccessRequestsApi.d.ts +79 -0
  613. package/dist/lib/admin/escrowAccessRequestsApi.js +46 -0
  614. package/dist/lib/admin/escrowAuditLogApi.d.ts +66 -0
  615. package/dist/lib/admin/escrowAuditLogApi.js +31 -0
  616. package/dist/lib/admin/escrowScopesApi.d.ts +78 -0
  617. package/dist/lib/admin/escrowScopesApi.js +50 -0
  618. package/dist/lib/admin/leftoverMailboxApi.d.ts +73 -0
  619. package/dist/lib/admin/leftoverMailboxApi.js +67 -0
  620. package/dist/lib/admin/mailboxPolicyApi.d.ts +27 -0
  621. package/dist/lib/admin/mailboxPolicyApi.js +21 -0
  622. package/dist/lib/admin/matterExportApi.d.ts +40 -0
  623. package/dist/lib/admin/matterExportApi.js +39 -0
  624. package/dist/lib/admin/matterSearchApi.d.ts +20 -0
  625. package/dist/lib/admin/matterSearchApi.js +27 -0
  626. package/dist/lib/admin/mattersApi.d.ts +56 -0
  627. package/dist/lib/admin/mattersApi.js +40 -0
  628. package/dist/lib/admin/pluginsApi.d.ts +265 -0
  629. package/dist/lib/admin/pluginsApi.js +102 -0
  630. package/dist/lib/admin/retentionPolicyApi.d.ts +32 -0
  631. package/dist/lib/admin/retentionPolicyApi.js +29 -0
  632. package/dist/lib/admin/setupApi.d.ts +23 -0
  633. package/dist/lib/admin/setupApi.js +26 -0
  634. package/dist/lib/admin/transportRulesApi.d.ts +66 -0
  635. package/dist/lib/admin/transportRulesApi.js +43 -0
  636. package/dist/lib/appearance/preferencesApi.d.ts +128 -0
  637. package/dist/lib/appearance/preferencesApi.js +257 -0
  638. package/dist/lib/auth/profileApi.d.ts +33 -0
  639. package/dist/lib/auth/profileApi.js +52 -0
  640. package/dist/lib/auth/session.d.ts +70 -0
  641. package/dist/lib/auth/session.js +210 -0
  642. package/dist/lib/branding/brandingApi.d.ts +47 -0
  643. package/dist/lib/branding/brandingApi.js +61 -0
  644. package/dist/lib/branding/useBranding.d.ts +23 -0
  645. package/dist/lib/branding/useBranding.js +65 -0
  646. package/dist/lib/calendar/calendarApi.d.ts +230 -0
  647. package/dist/lib/calendar/calendarApi.js +106 -0
  648. package/dist/lib/calendar/calendarColors.d.ts +18 -0
  649. package/dist/lib/calendar/calendarColors.js +39 -0
  650. package/dist/lib/calendar/calendarDragIds.d.ts +42 -0
  651. package/dist/lib/calendar/calendarDragIds.js +92 -0
  652. package/dist/lib/calendar/calendarMutations.d.ts +68 -0
  653. package/dist/lib/calendar/calendarMutations.js +190 -0
  654. package/dist/lib/calendar/eventDescription.d.ts +43 -0
  655. package/dist/lib/calendar/eventDescription.js +195 -0
  656. package/dist/lib/calendar/freeBusyApi.d.ts +100 -0
  657. package/dist/lib/calendar/freeBusyApi.js +119 -0
  658. package/dist/lib/calendar/inviteApi.d.ts +121 -0
  659. package/dist/lib/calendar/inviteApi.js +54 -0
  660. package/dist/lib/calendar/recurrence.d.ts +60 -0
  661. package/dist/lib/calendar/recurrence.js +225 -0
  662. package/dist/lib/components/avatar/ContactAvatar.d.ts +8 -0
  663. package/dist/lib/components/avatar/ContactAvatar.js +26 -0
  664. package/dist/lib/components/buttons/Button.d.ts +9 -0
  665. package/dist/lib/components/buttons/Button.js +14 -0
  666. package/dist/lib/components/buttons/CopyButton.d.ts +18 -0
  667. package/dist/lib/components/buttons/CopyButton.js +14 -0
  668. package/dist/lib/components/feedback/Alert.d.ts +4 -0
  669. package/dist/lib/components/feedback/Alert.js +4 -0
  670. package/dist/lib/components/feedback/Skeleton.d.ts +21 -0
  671. package/dist/lib/components/feedback/Skeleton.js +14 -0
  672. package/dist/lib/components/forms/FormField.d.ts +8 -0
  673. package/dist/lib/components/forms/FormField.js +5 -0
  674. package/dist/lib/components/navigation/BottomTabBar.d.ts +27 -0
  675. package/dist/lib/components/navigation/BottomTabBar.js +32 -0
  676. package/dist/lib/components/overlays/Drawer.d.ts +20 -0
  677. package/dist/lib/components/overlays/Drawer.js +27 -0
  678. package/dist/lib/components/overlays/Modal.d.ts +17 -0
  679. package/dist/lib/components/overlays/Modal.js +25 -0
  680. package/dist/lib/components/overlays/PopoverPortal.d.ts +23 -0
  681. package/dist/lib/components/overlays/PopoverPortal.js +53 -0
  682. package/dist/lib/components/overlays/overlayStack.d.ts +31 -0
  683. package/dist/lib/components/overlays/overlayStack.js +143 -0
  684. package/dist/lib/components/pickers/MiniDatePicker.d.ts +13 -0
  685. package/dist/lib/components/pickers/MiniDatePicker.js +42 -0
  686. package/dist/lib/contacts/contactsApi.d.ts +174 -0
  687. package/dist/lib/contacts/contactsApi.js +139 -0
  688. package/dist/lib/contacts/vcard.d.ts +23 -0
  689. package/dist/lib/contacts/vcard.js +179 -0
  690. package/dist/lib/crypto/composeSecurity.d.ts +67 -0
  691. package/dist/lib/crypto/composeSecurity.js +93 -0
  692. package/dist/lib/crypto/encoding.d.ts +9 -0
  693. package/dist/lib/crypto/encoding.js +32 -0
  694. package/dist/lib/crypto/escrowKeys.d.ts +25 -0
  695. package/dist/lib/crypto/escrowKeys.js +59 -0
  696. package/dist/lib/crypto/idleTimeout.d.ts +16 -0
  697. package/dist/lib/crypto/idleTimeout.js +47 -0
  698. package/dist/lib/crypto/keySession.d.ts +159 -0
  699. package/dist/lib/crypto/keySession.js +367 -0
  700. package/dist/lib/crypto/keys.d.ts +50 -0
  701. package/dist/lib/crypto/keys.js +89 -0
  702. package/dist/lib/crypto/keyvaultApi.d.ts +394 -0
  703. package/dist/lib/crypto/keyvaultApi.js +350 -0
  704. package/dist/lib/crypto/masterKey.d.ts +59 -0
  705. package/dist/lib/crypto/masterKey.js +104 -0
  706. package/dist/lib/crypto/masterKeyWraps.d.ts +108 -0
  707. package/dist/lib/crypto/masterKeyWraps.js +228 -0
  708. package/dist/lib/crypto/messageSecurity.d.ts +248 -0
  709. package/dist/lib/crypto/messageSecurity.js +367 -0
  710. package/dist/lib/crypto/mime.d.ts +143 -0
  711. package/dist/lib/crypto/mime.js +504 -0
  712. package/dist/lib/crypto/passkeyUnlock.d.ts +20 -0
  713. package/dist/lib/crypto/passkeyUnlock.js +79 -0
  714. package/dist/lib/crypto/passwordUnlock.d.ts +39 -0
  715. package/dist/lib/crypto/passwordUnlock.js +73 -0
  716. package/dist/lib/crypto/recoveryCode.d.ts +28 -0
  717. package/dist/lib/crypto/recoveryCode.js +86 -0
  718. package/dist/lib/crypto/signingProviderApi.d.ts +95 -0
  719. package/dist/lib/crypto/signingProviderApi.js +60 -0
  720. package/dist/lib/crypto/smime.d.ts +128 -0
  721. package/dist/lib/crypto/smime.js +402 -0
  722. package/dist/lib/crypto/smimeMessage.d.ts +132 -0
  723. package/dist/lib/crypto/smimeMessage.js +341 -0
  724. package/dist/lib/crypto/useIdleKeyTimeout.d.ts +10 -0
  725. package/dist/lib/crypto/useIdleKeyTimeout.js +163 -0
  726. package/dist/lib/crypto/verificationSeal.d.ts +56 -0
  727. package/dist/lib/crypto/verificationSeal.js +220 -0
  728. package/dist/lib/mail/compose/composeQuoting.d.ts +88 -0
  729. package/dist/lib/mail/compose/composeQuoting.js +204 -0
  730. package/dist/lib/mail/compose/emojiData.d.ts +9 -0
  731. package/dist/lib/mail/compose/emojiData.js +18 -0
  732. package/dist/lib/mail/compose/giphyApi.d.ts +17 -0
  733. package/dist/lib/mail/compose/giphyApi.js +20 -0
  734. package/dist/lib/mail/conversationsApi.d.ts +80 -0
  735. package/dist/lib/mail/conversationsApi.js +44 -0
  736. package/dist/lib/mail/dataExportApi.d.ts +50 -0
  737. package/dist/lib/mail/dataExportApi.js +40 -0
  738. package/dist/lib/mail/directoryApi.d.ts +49 -0
  739. package/dist/lib/mail/directoryApi.js +101 -0
  740. package/dist/lib/mail/erasureRequestApi.d.ts +45 -0
  741. package/dist/lib/mail/erasureRequestApi.js +43 -0
  742. package/dist/lib/mail/flaggedMessages.d.ts +22 -0
  743. package/dist/lib/mail/flaggedMessages.js +73 -0
  744. package/dist/lib/mail/focusedInboxOverridesApi.d.ts +37 -0
  745. package/dist/lib/mail/focusedInboxOverridesApi.js +34 -0
  746. package/dist/lib/mail/labelsApi.d.ts +47 -0
  747. package/dist/lib/mail/labelsApi.js +38 -0
  748. package/dist/lib/mail/mailAddress.d.ts +27 -0
  749. package/dist/lib/mail/mailAddress.js +54 -0
  750. package/dist/lib/mail/mailApi.d.ts +850 -0
  751. package/dist/lib/mail/mailApi.js +602 -0
  752. package/dist/lib/mail/mailDetailHooks.d.ts +10 -0
  753. package/dist/lib/mail/mailDetailHooks.js +53 -0
  754. package/dist/lib/mail/mailFilterRulesApi.d.ts +76 -0
  755. package/dist/lib/mail/mailFilterRulesApi.js +45 -0
  756. package/dist/lib/mail/mailSignaturesApi.d.ts +49 -0
  757. package/dist/lib/mail/mailSignaturesApi.js +42 -0
  758. package/dist/lib/mail/mailboxAccessApi.d.ts +74 -0
  759. package/dist/lib/mail/mailboxAccessApi.js +56 -0
  760. package/dist/lib/mail/mailboxImportApi.d.ts +53 -0
  761. package/dist/lib/mail/mailboxImportApi.js +51 -0
  762. package/dist/lib/mail/messageBodySanitizer.d.ts +16 -0
  763. package/dist/lib/mail/messageBodySanitizer.js +118 -0
  764. package/dist/lib/mail/pushClient.d.ts +106 -0
  765. package/dist/lib/mail/pushClient.js +317 -0
  766. package/dist/lib/mail/sendEvents.d.ts +33 -0
  767. package/dist/lib/mail/sendEvents.js +44 -0
  768. package/dist/lib/mail/sendFailure.d.ts +16 -0
  769. package/dist/lib/mail/sendFailure.js +86 -0
  770. package/dist/lib/mail/senderListsApi.d.ts +69 -0
  771. package/dist/lib/mail/senderListsApi.js +126 -0
  772. package/dist/lib/search/queryGrammar.d.ts +51 -0
  773. package/dist/lib/search/queryGrammar.js +111 -0
  774. package/dist/lib/search/searchApi.d.ts +100 -0
  775. package/dist/lib/search/searchApi.js +107 -0
  776. package/dist/lib/search/searchScoring.d.ts +34 -0
  777. package/dist/lib/search/searchScoring.js +44 -0
  778. package/dist/lib/search/searchTier3.d.ts +64 -0
  779. package/dist/lib/search/searchTier3.js +335 -0
  780. package/dist/lib/tasks/tasksApi.d.ts +85 -0
  781. package/dist/lib/tasks/tasksApi.js +55 -0
  782. package/dist/lib/util/api.d.ts +160 -0
  783. package/dist/lib/util/api.js +251 -0
  784. package/dist/lib/util/apiClientContext.d.ts +7 -0
  785. package/dist/lib/util/apiClientContext.js +32 -0
  786. package/dist/lib/util/apiQuery.d.ts +32 -0
  787. package/dist/lib/util/apiQuery.js +42 -0
  788. package/dist/lib/util/clipboard.d.ts +7 -0
  789. package/dist/lib/util/clipboard.js +56 -0
  790. package/dist/lib/util/dateInput.d.ts +6 -0
  791. package/dist/lib/util/dateInput.js +14 -0
  792. package/dist/lib/util/timeZone.d.ts +12 -0
  793. package/dist/lib/util/timeZone.js +32 -0
  794. package/dist/lib/util/useCopyToClipboard.d.ts +12 -0
  795. package/dist/lib/util/useCopyToClipboard.js +34 -0
  796. package/dist/lib/util/useIsMobile.d.ts +10 -0
  797. package/dist/lib/util/useIsMobile.js +29 -0
  798. package/dist/lib/videoconf/videoMeetingsApi.d.ts +116 -0
  799. package/dist/lib/videoconf/videoMeetingsApi.js +49 -0
  800. package/lib/admin/auditLogApi.ts +48 -0
  801. package/lib/admin/distributionListsApi.ts +77 -0
  802. package/lib/admin/domainsApi.ts +113 -0
  803. package/lib/admin/escrowAccessRequestsApi.ts +110 -0
  804. package/lib/admin/escrowAuditLogApi.ts +101 -0
  805. package/lib/admin/escrowScopesApi.ts +112 -0
  806. package/lib/admin/leftoverMailboxApi.ts +120 -0
  807. package/lib/admin/mailboxPolicyApi.ts +38 -0
  808. package/lib/admin/matterExportApi.ts +62 -0
  809. package/lib/admin/matterSearchApi.ts +35 -0
  810. package/lib/admin/mattersApi.ts +86 -0
  811. package/lib/admin/pluginsApi.ts +339 -0
  812. package/lib/admin/retentionPolicyApi.ts +46 -0
  813. package/lib/admin/setupApi.ts +40 -0
  814. package/lib/admin/transportRulesApi.ts +106 -0
  815. package/lib/appearance/preferencesApi.ts +335 -0
  816. package/lib/auth/profileApi.ts +77 -0
  817. package/lib/auth/session.ts +238 -0
  818. package/lib/branding/brandingApi.ts +97 -0
  819. package/lib/branding/useBranding.ts +81 -0
  820. package/lib/calendar/calendarApi.ts +309 -0
  821. package/lib/calendar/calendarColors.ts +45 -0
  822. package/lib/calendar/calendarDragIds.ts +112 -0
  823. package/lib/calendar/calendarMutations.ts +236 -0
  824. package/lib/calendar/eventDescription.ts +211 -0
  825. package/lib/calendar/freeBusyApi.ts +197 -0
  826. package/lib/calendar/inviteApi.ts +154 -0
  827. package/lib/calendar/recurrence.ts +285 -0
  828. package/lib/components/avatar/ContactAvatar.tsx +47 -0
  829. package/lib/components/buttons/Button.tsx +40 -0
  830. package/lib/components/buttons/CopyButton.tsx +45 -0
  831. package/lib/components/feedback/Alert.tsx +13 -0
  832. package/lib/components/feedback/Skeleton.tsx +38 -0
  833. package/lib/components/forms/FormField.tsx +23 -0
  834. package/lib/components/navigation/BottomTabBar.tsx +66 -0
  835. package/lib/components/overlays/Drawer.tsx +72 -0
  836. package/lib/components/overlays/Modal.tsx +64 -0
  837. package/lib/components/overlays/PopoverPortal.tsx +74 -0
  838. package/lib/components/overlays/overlayStack.ts +165 -0
  839. package/lib/components/pickers/MiniDatePicker.tsx +90 -0
  840. package/lib/contacts/contactsApi.ts +289 -0
  841. package/lib/contacts/vcard.ts +197 -0
  842. package/lib/crypto/composeSecurity.ts +140 -0
  843. package/lib/crypto/encoding.ts +36 -0
  844. package/lib/crypto/escrowKeys.ts +74 -0
  845. package/lib/crypto/idleTimeout.ts +49 -0
  846. package/lib/crypto/keySession.ts +483 -0
  847. package/lib/crypto/keys.ts +105 -0
  848. package/lib/crypto/keyvaultApi.ts +674 -0
  849. package/lib/crypto/masterKey.ts +134 -0
  850. package/lib/crypto/masterKeyWraps.ts +269 -0
  851. package/lib/crypto/messageSecurity.ts +600 -0
  852. package/lib/crypto/mime.ts +568 -0
  853. package/lib/crypto/passkeyUnlock.ts +103 -0
  854. package/lib/crypto/passwordUnlock.ts +98 -0
  855. package/lib/crypto/recoveryCode.ts +93 -0
  856. package/lib/crypto/signingProviderApi.ts +135 -0
  857. package/lib/crypto/smime.ts +459 -0
  858. package/lib/crypto/smimeMessage.ts +491 -0
  859. package/lib/crypto/useIdleKeyTimeout.ts +176 -0
  860. package/lib/crypto/verificationSeal.ts +288 -0
  861. package/lib/mail/compose/composeQuoting.ts +243 -0
  862. package/lib/mail/compose/emojiData.ts +34 -0
  863. package/lib/mail/compose/giphyApi.ts +31 -0
  864. package/lib/mail/conversationsApi.ts +123 -0
  865. package/lib/mail/dataExportApi.ts +73 -0
  866. package/lib/mail/directoryApi.ts +161 -0
  867. package/lib/mail/erasureRequestApi.ts +71 -0
  868. package/lib/mail/flaggedMessages.ts +80 -0
  869. package/lib/mail/focusedInboxOverridesApi.ts +64 -0
  870. package/lib/mail/labelsApi.ts +71 -0
  871. package/lib/mail/mailAddress.ts +76 -0
  872. package/lib/mail/mailApi.ts +1286 -0
  873. package/lib/mail/mailDetailHooks.ts +57 -0
  874. package/lib/mail/mailFilterRulesApi.ts +116 -0
  875. package/lib/mail/mailSignaturesApi.ts +84 -0
  876. package/lib/mail/mailboxAccessApi.ts +106 -0
  877. package/lib/mail/mailboxImportApi.ts +87 -0
  878. package/lib/mail/messageBodySanitizer.ts +129 -0
  879. package/lib/mail/pushClient.ts +375 -0
  880. package/lib/mail/sendEvents.ts +72 -0
  881. package/lib/mail/sendFailure.ts +98 -0
  882. package/lib/mail/senderListsApi.ts +161 -0
  883. package/lib/search/queryGrammar.ts +179 -0
  884. package/lib/search/searchApi.ts +199 -0
  885. package/lib/search/searchScoring.ts +46 -0
  886. package/lib/search/searchTier3.ts +406 -0
  887. package/lib/tasks/tasksApi.ts +128 -0
  888. package/lib/util/api.ts +318 -0
  889. package/lib/util/apiClientContext.ts +35 -0
  890. package/lib/util/apiQuery.ts +61 -0
  891. package/lib/util/clipboard.ts +55 -0
  892. package/lib/util/dateInput.ts +15 -0
  893. package/lib/util/timeZone.ts +33 -0
  894. package/lib/util/useCopyToClipboard.ts +48 -0
  895. package/lib/util/useIsMobile.ts +34 -0
  896. package/lib/videoconf/videoMeetingsApi.ts +144 -0
  897. package/package.json +10 -4
@@ -0,0 +1,225 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /**
6
+ * RFC5545 recurrence expansion, entirely client-side — `@rapidmx/restapi` stores/returns
7
+ * `RecurrenceRule` as-is and does no expansion of its own (see `calendarApi.ts`'s own header
8
+ * comment). Built on the `rrule` package.
9
+ */
10
+ // `rrule` ships a real ESM build (resolved by the client bundler via its own module graph, where
11
+ // named imports work normally) alongside a separate CJS build with no `"exports"` map (resolved by
12
+ // this framework's *server-side* render path via Node's own loader, which falls back to the CJS
13
+ // build since "module" is a bundler-only convention Node itself doesn't honor). Node's static
14
+ // named-export detection for that CJS build doesn't pick up `RRule` (confirmed directly: SSR-ing the
15
+ // calendar page threw "does not provide an export named 'RRule'"), so a plain named import breaks
16
+ // under SSR even though it works in the browser. A namespace import sidesteps the static check
17
+ // entirely; reading `.default` afterward reaches the same class via Node's CJS interop (`default`
18
+ // always aliases `module.exports` for a CJS module) without disturbing the ESM path, where `.default`
19
+ // simply doesn't exist and the direct named property is used instead.
20
+ import * as RRuleNS from "rrule";
21
+ /** Extracted so the CJS-interop fallback branch can be exercised directly with a plain object,
22
+ * without needing to fight a module mock into reproducing Node's exact interop shape. */
23
+ export function resolveRRuleExport(ns) {
24
+ return ns.RRule ?? ns.default.RRule;
25
+ }
26
+ const RRule = resolveRRuleExport(RRuleNS);
27
+ const FREQ_MAP = {
28
+ yearly: RRule.YEARLY,
29
+ monthly: RRule.MONTHLY,
30
+ weekly: RRule.WEEKLY,
31
+ daily: RRule.DAILY,
32
+ };
33
+ // `RRule`'s own `.toText()` formatter requires actual `Weekday` instances in `byweekday` — passing the
34
+ // raw two-letter strings works for occurrence expansion (`.between()`) but throws inside `.toText()`
35
+ // (confirmed by reproducing it directly against this exact package version).
36
+ const WEEKDAY_OBJECT = {
37
+ MO: RRule.MO,
38
+ TU: RRule.TU,
39
+ WE: RRule.WE,
40
+ TH: RRule.TH,
41
+ FR: RRule.FR,
42
+ SA: RRule.SA,
43
+ SU: RRule.SU,
44
+ };
45
+ function createRRule(rule, dtstart, until, tzid) {
46
+ return new RRule({
47
+ freq: FREQ_MAP[rule.freq],
48
+ interval: rule.interval,
49
+ dtstart,
50
+ tzid,
51
+ byweekday: rule.byDay?.map((code) => WEEKDAY_OBJECT[code]),
52
+ bymonthday: rule.byMonthDay,
53
+ bymonth: rule.byMonth,
54
+ count: rule.count,
55
+ until,
56
+ });
57
+ }
58
+ /**
59
+ * Builds an `RRule` instance from this app's `RecurrenceRule` shape, anchored at `dtstart`. Pass the
60
+ * event's IANA `tzid` so the rule carries it (e.g. `DTSTART;TZID=America/New_York:...` from
61
+ * `.toString()`) — note that, per `rrule`'s own convention, a rule with a non-UTC `tzid` expects
62
+ * `dtstart` to be a "floating" wall-clock time expressed as a UTC `Date` and rezones its generated
63
+ * dates using the *runtime's* local zone, which is why `expandOccurrences()` below does its own
64
+ * timezone conversion instead of relying on this.
65
+ */
66
+ export function buildRRule(rule, dtstart, tzid) {
67
+ return createRRule(rule, dtstart, rule.until ? new Date(rule.until) : null, tzid ?? null);
68
+ }
69
+ const MS_PER_DAY = 24 * 60 * 60 * 1000;
70
+ function positiveMs(ms) {
71
+ return ((ms % 1000) + 1000) % 1000;
72
+ }
73
+ /** The runtime's own local zone — used for a "floating" event with no (or an unrecognized) timezone. */
74
+ const LOCAL_ZONE = {
75
+ toWall(instantMs) {
76
+ const d = new Date(instantMs);
77
+ return Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
78
+ },
79
+ fromWall(wallMs) {
80
+ const w = new Date(wallMs);
81
+ return new Date(w.getUTCFullYear(), w.getUTCMonth(), w.getUTCDate(), w.getUTCHours(), w.getUTCMinutes(), w.getUTCSeconds(), w.getUTCMilliseconds()).getTime();
82
+ },
83
+ };
84
+ /** UTC itself - used for all-day events, whose dates are stored as UTC midnight (date-only values). */
85
+ const UTC_ZONE = {
86
+ toWall: (instantMs) => instantMs,
87
+ fromWall: (wallMs) => wallMs,
88
+ };
89
+ function ianaZone(formatter) {
90
+ const toWall = (instantMs) => {
91
+ const fields = {};
92
+ for (const part of formatter.formatToParts(new Date(instantMs))) {
93
+ fields[part.type] = Number(part.value);
94
+ }
95
+ // `% 24`: some engines render midnight as hour "24" even with `hourCycle: "h23"`.
96
+ return Date.UTC(fields.year, fields.month - 1, fields.day, fields.hour % 24, fields.minute, fields.second, positiveMs(instantMs));
97
+ };
98
+ return {
99
+ toWall,
100
+ // RFC 5545 §3.3.5 resolution against the offsets in effect a day before and a day after (zones
101
+ // change offset at most once in that window): an ambiguous (fall-back) wall time resolves to its
102
+ // first occurrence (the earlier instant); a nonexistent (spring-forward) one is interpreted with
103
+ // the offset from *before* the transition, so 02:30 on a US spring-forward day becomes 03:30 EDT.
104
+ fromWall(wallMs) {
105
+ const offsetBefore = toWall(wallMs - MS_PER_DAY) - (wallMs - MS_PER_DAY);
106
+ const offsetAfter = toWall(wallMs + MS_PER_DAY) - (wallMs + MS_PER_DAY);
107
+ const valid = [wallMs - offsetBefore, wallMs - offsetAfter].filter((instant) => toWall(instant) === wallMs);
108
+ return valid.length > 0 ? Math.min(...valid) : wallMs - offsetBefore;
109
+ },
110
+ };
111
+ }
112
+ const zoneCache = new Map();
113
+ /** Resolves `timezone` (an IANA zone id) to a converter, falling back to the runtime's local zone when
114
+ * it's empty or not a zone `Intl` recognizes. */
115
+ function resolveZone(timezone) {
116
+ const key = timezone ?? "";
117
+ let zone = zoneCache.get(key);
118
+ if (!zone) {
119
+ try {
120
+ zone = key
121
+ ? ianaZone(new Intl.DateTimeFormat("en-US", {
122
+ timeZone: key,
123
+ hourCycle: "h23",
124
+ year: "numeric",
125
+ month: "2-digit",
126
+ day: "2-digit",
127
+ hour: "2-digit",
128
+ minute: "2-digit",
129
+ second: "2-digit",
130
+ }))
131
+ : LOCAL_ZONE;
132
+ }
133
+ catch {
134
+ zone = LOCAL_ZONE;
135
+ }
136
+ zoneCache.set(key, zone);
137
+ }
138
+ return zone;
139
+ }
140
+ /**
141
+ * Converts an instant to the "wall-clock as UTC" milliseconds recurrence expansion works in for an event
142
+ * with this `timezone`/`allDay` - UTC for an all-day event (stored as UTC-midnight dates), the event's IANA
143
+ * zone otherwise (the runtime's local zone when empty or unrecognized). Exported for `calendarMutations.ts`,
144
+ * which shifts a series' exception dates by the same wall-clock delta as its start.
145
+ */
146
+ export function toEventWallClock(instantMs, timezone, allDay) {
147
+ return (allDay ? UTC_ZONE : resolveZone(timezone)).toWall(instantMs);
148
+ }
149
+ /** Inverse of `toEventWallClock()` (DST gaps/overlaps resolved per RFC 5545 - see `ianaZone()`). */
150
+ export function fromEventWallClock(wallMs, timezone, allDay) {
151
+ return (allDay ? UTC_ZONE : resolveZone(timezone)).fromWall(wallMs);
152
+ }
153
+ /**
154
+ * Expands `event` into every occurrence whose interval overlaps `[rangeStart, rangeEnd]`. A
155
+ * non-recurring event yields itself (in a one-element array) if it overlaps, or `[]` otherwise —
156
+ * callers don't need to special-case recurring vs. not.
157
+ *
158
+ * Recurrence is expanded in the event's own `timezone` (an IANA zone id; an empty or unrecognized
159
+ * value falls back to the runtime's local zone, i.e. floating time), so every occurrence keeps the
160
+ * master's local wall-clock start/end time and local weekday — a weekly Monday 23:00
161
+ * America/New_York event stays on Monday 23:00 New York time across DST changes, rather than being
162
+ * expanded on the UTC weekday/time of its first instance. An all-day event is the exception: its dates are
163
+ * UTC-midnight date-only values, so it expands in UTC regardless of `timezone` - expanding a
164
+ * `2026-09-14T00:00Z` Monday in America/New_York would otherwise see a Sunday-evening start and put every
165
+ * occurrence on the wrong date. A timed occurrence that falls in a DST gap starts at the pre-transition
166
+ * offset (RFC 5545) and keeps its wall-clock duration.
167
+ */
168
+ export function expandOccurrences(event, rangeStart, rangeEnd) {
169
+ const start = new Date(event.startDate);
170
+ const end = new Date(event.endDate);
171
+ if (!event.recurrenceRule) {
172
+ const overlaps = start < rangeEnd && end > rangeStart;
173
+ return overlaps ? [{ ...event, occurrenceKey: event.uid, isRecurringOccurrence: false }] : [];
174
+ }
175
+ const zone = event.allDay ? UTC_ZONE : resolveZone(event.timezone);
176
+ const startWall = zone.toWall(start.getTime());
177
+ // The duration in wall-clock terms, so an occurrence also keeps its local end time across DST.
178
+ const wallDurationMs = zone.toWall(end.getTime()) - startWall;
179
+ const { until } = event.recurrenceRule;
180
+ const rule = createRRule(event.recurrenceRule, new Date(startWall), until ? new Date(zone.toWall(new Date(until).getTime())) : null, null);
181
+ // Query in the wall-clock frame, widened by one occurrence's duration (so an occurrence that started
182
+ // before `rangeStart` but is still in progress isn't missed) plus a day on each side to absorb the
183
+ // zone's offset; the exact instant-based overlap filter at the end trims the excess.
184
+ const queryStart = new Date(zone.toWall(rangeStart.getTime()) - wallDurationMs - MS_PER_DAY);
185
+ const queryEnd = new Date(zone.toWall(rangeEnd.getTime()) + MS_PER_DAY);
186
+ const occurrenceStarts = rule
187
+ .between(queryStart, queryEnd, true)
188
+ .map((occWall) => ({ start: new Date(zone.fromWall(occWall.getTime())), wall: occWall.getTime() }));
189
+ const exceptions = new Set(event.recurrenceRule.exceptions.map((d) => new Date(d).getTime()));
190
+ return occurrenceStarts
191
+ .filter((occ) => !exceptions.has(occ.start.getTime()))
192
+ .map(({ start: occStart, wall }) => {
193
+ // Non-zero only when the start fell in a DST gap and was pushed forward - the end moves with it.
194
+ const gapShiftMs = zone.toWall(occStart.getTime()) - wall;
195
+ const occEnd = new Date(zone.fromWall(wall + gapShiftMs + wallDurationMs));
196
+ return {
197
+ ...event,
198
+ startDate: occStart.toISOString(),
199
+ endDate: occEnd.toISOString(),
200
+ recurrenceId: occStart.toISOString(),
201
+ occurrenceKey: `${event.uid}::${occStart.toISOString()}`,
202
+ isRecurringOccurrence: true,
203
+ };
204
+ })
205
+ .filter((occ) => new Date(occ.startDate) < rangeEnd && new Date(occ.endDate) > rangeStart);
206
+ }
207
+ /** Expands every event in `events` and flattens the result — the usual entry point for a grid view. */
208
+ export function expandAllOccurrences(events, rangeStart, rangeEnd) {
209
+ return events.flatMap((event) => expandOccurrences(event, rangeStart, rangeEnd));
210
+ }
211
+ /** A human-readable summary of `rule` (e.g. "every 2 weeks on Monday, Wednesday until Jan 1, 2027"). */
212
+ export function describeRecurrence(rule) {
213
+ const rrule = buildRRule(rule, new Date());
214
+ return rrule.toText();
215
+ }
216
+ export const WEEKDAY_CODES = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"];
217
+ export const WEEKDAY_LABELS = {
218
+ MO: "Mon",
219
+ TU: "Tue",
220
+ WE: "Wed",
221
+ TH: "Thu",
222
+ FR: "Fri",
223
+ SA: "Sat",
224
+ SU: "Sun",
225
+ };
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export interface ContactAvatarProps {
3
+ displayName: string;
4
+ size?: number;
5
+ }
6
+ /** A small circular initials avatar for a contact, matching Outlook People's list-row avatars — deterministic
7
+ * per name (same contact always gets the same color/initials), no photo-upload dependency. */
8
+ export default function ContactAvatar({ displayName, size }: ContactAvatarProps): React.JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** A fixed palette of background colors, cycled by a hash of the contact's name — no photo upload feature
3
+ * exists yet (`Contact.photoBlobKey` is modeled server-side but nothing in this app sets/reads it), so every
4
+ * contact gets one of these deterministically rather than a plain generic gray circle for everyone. */
5
+ const PALETTE = ["#7c3aed", "#2563eb", "#0891b2", "#059669", "#d97706", "#dc2626", "#db2777", "#4f46e5"];
6
+ function initialsOf(displayName) {
7
+ const parts = displayName.trim().split(/\s+/).filter(Boolean);
8
+ if (parts.length === 0) {
9
+ return "?";
10
+ }
11
+ const first = parts[0][0];
12
+ const last = parts.length > 1 ? parts[parts.length - 1][0] : "";
13
+ return (first + last).toUpperCase();
14
+ }
15
+ function colorOf(displayName) {
16
+ let hash = 0;
17
+ for (let i = 0; i < displayName.length; i++) {
18
+ hash = (hash * 31 + displayName.charCodeAt(i)) | 0;
19
+ }
20
+ return PALETTE[Math.abs(hash) % PALETTE.length];
21
+ }
22
+ /** A small circular initials avatar for a contact, matching Outlook People's list-row avatars — deterministic
23
+ * per name (same contact always gets the same color/initials), no photo-upload dependency. */
24
+ export default function ContactAvatar({ displayName, size = 32 }) {
25
+ return (_jsx("span", { "aria-hidden": "true", style: { width: size, height: size, backgroundColor: colorOf(displayName), fontSize: size * 0.4 }, className: "inline-flex items-center justify-center rounded-full text-white font-semibold shrink-0", children: initialsOf(displayName) }));
26
+ }
@@ -0,0 +1,9 @@
1
+ import React, { ButtonHTMLAttributes } from "react";
2
+ export type ButtonVariant = "primary" | "secondary" | "text";
3
+ export interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "className"> {
4
+ variant?: ButtonVariant;
5
+ /** Renders a small spinner before the button's content. */
6
+ loading?: boolean;
7
+ className?: string;
8
+ }
9
+ export default function Button({ variant, loading, className, children, ...rest }: ButtonProps): React.JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const BASE = "inline-flex items-center justify-center gap-2 font-semibold text-sm rounded-sm border transition-colors disabled:opacity-55 disabled:cursor-not-allowed active:translate-y-px";
3
+ /** Primary is gold (the brand's action color, per the style guide's "gold gradient fill" convention);
4
+ * secondary/text hover accents follow the guide's "turning gold on hover" rule too. Teal (`primary`
5
+ * the color token, confusingly named the same as this `primary` variant) stays reserved for
6
+ * structural/navigational chrome — active nav items, links, focus rings — not call-to-action buttons. */
7
+ const VARIANTS = {
8
+ primary: "w-full py-2.5 px-4 bg-gradient-to-b from-accent-soft to-accent border-transparent text-text-on-accent hover:not-disabled:from-accent hover:not-disabled:to-accent-dark",
9
+ secondary: "w-full py-2.5 px-4 bg-transparent border-border text-text hover:not-disabled:border-accent hover:not-disabled:text-accent-dark",
10
+ text: "w-auto py-1 px-0.5 border-transparent bg-transparent text-accent-dark hover:not-disabled:underline",
11
+ };
12
+ export default function Button({ variant = "primary", loading, className, children, ...rest }) {
13
+ return (_jsxs("button", { className: [BASE, VARIANTS[variant], className].filter(Boolean).join(" "), ...rest, children: [loading && (_jsx("span", { className: "w-4 h-4 rounded-full border-2 border-current/30 border-t-current animate-spin" })), children] }));
14
+ }
@@ -0,0 +1,18 @@
1
+ import React, { ReactNode } from "react";
2
+ export interface CopyButtonProps {
3
+ /** The text put on the clipboard. */
4
+ value: string;
5
+ /** The button's accessible name - say what is copied, e.g. "Copy value for the SPF record". */
6
+ label: string;
7
+ /** The visible caption. Defaults to "Copy". */
8
+ children?: ReactNode;
9
+ className?: string;
10
+ }
11
+ /**
12
+ * A small "Copy" button for a value someone has to paste elsewhere (a DNS record, a code). Copies through
13
+ * `copyTextToClipboard()` - the async Clipboard API, then a hidden-textarea `execCommand` fallback - and
14
+ * announces the result next to the button in a polite live region ("Copied", or "Couldn't copy" when both
15
+ * routes fail, in which case the value is still on screen to select by hand). The live region is always
16
+ * rendered, empty until there is something to say, so screen readers pick the change up.
17
+ */
18
+ export default function CopyButton({ value, label, children, className }: CopyButtonProps): React.JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import useCopyToClipboard from "../../util/useCopyToClipboard.js";
3
+ import Button from "./Button.js";
4
+ /**
5
+ * A small "Copy" button for a value someone has to paste elsewhere (a DNS record, a code). Copies through
6
+ * `copyTextToClipboard()` - the async Clipboard API, then a hidden-textarea `execCommand` fallback - and
7
+ * announces the result next to the button in a polite live region ("Copied", or "Couldn't copy" when both
8
+ * routes fail, in which case the value is still on screen to select by hand). The live region is always
9
+ * rendered, empty until there is something to say, so screen readers pick the change up.
10
+ */
11
+ export default function CopyButton({ value, label, children = "Copy", className }) {
12
+ const { status, copy } = useCopyToClipboard();
13
+ return (_jsxs("span", { className: "inline-flex items-center gap-2 shrink-0", children: [_jsx(Button, { type: "button", variant: "secondary", "aria-label": label, className: ["!w-auto !py-1 !px-2 text-xs", className].filter(Boolean).join(" "), onClick: () => void copy(value), children: children }), _jsx("span", { role: "status", "aria-live": "polite", className: status === "failed" ? "text-xs text-danger" : "text-xs text-success", children: status === "copied" ? "Copied" : status === "failed" ? "Couldn’t copy" : "" })] }));
14
+ }
@@ -0,0 +1,4 @@
1
+ import React, { ReactNode } from "react";
2
+ export default function Alert({ children }: {
3
+ children: ReactNode;
4
+ }): React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export default function Alert({ children }) {
3
+ return (_jsx("div", { className: "flex gap-2 items-start py-3 px-3.5 rounded-sm text-sm mb-5 bg-danger-bg text-danger", role: "alert", children: children }));
4
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ export interface SkeletonProps {
3
+ /** Tailwind width class, e.g. `"w-32"` or `"w-full"`. Defaults to full width. */
4
+ width?: string;
5
+ /** Tailwind height class, e.g. `"h-4"`. Defaults to a text-line height. */
6
+ height?: string;
7
+ /** Extra classes — e.g. `"rounded-full"` for an avatar placeholder instead of the default bar shape. */
8
+ className?: string;
9
+ }
10
+ /** A single pulsing placeholder bar — the shared building block every skeleton layout in this app
11
+ * composes from, so a loading list/sidebar/page reads as "this shape is about to have real content"
12
+ * rather than either a blank pane or a spinner (this app's convention going forward for anything that
13
+ * takes a network round trip to render — see the shells' own `Skeleton`-based "checking" state). */
14
+ export default function Skeleton({ width, height, className }: SkeletonProps): React.JSX.Element;
15
+ /** A vertical stack of `count` skeleton rows, each an icon-sized block plus a text-line bar — the
16
+ * shape shared by every list-style loading state in this app (folder trees, message/contact/task
17
+ * lists, sidebar nav items). */
18
+ export declare function SkeletonList({ count, className }: {
19
+ count?: number;
20
+ className?: string;
21
+ }): React.JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /** A single pulsing placeholder bar — the shared building block every skeleton layout in this app
3
+ * composes from, so a loading list/sidebar/page reads as "this shape is about to have real content"
4
+ * rather than either a blank pane or a spinner (this app's convention going forward for anything that
5
+ * takes a network round trip to render — see the shells' own `Skeleton`-based "checking" state). */
6
+ export default function Skeleton({ width = "w-full", height = "h-4", className = "" }) {
7
+ return _jsx("div", { "aria-hidden": "true", className: ["animate-pulse rounded-sm bg-border", width, height, className].join(" ") });
8
+ }
9
+ /** A vertical stack of `count` skeleton rows, each an icon-sized block plus a text-line bar — the
10
+ * shape shared by every list-style loading state in this app (folder trees, message/contact/task
11
+ * lists, sidebar nav items). */
12
+ export function SkeletonList({ count = 5, className = "" }) {
13
+ return (_jsx("div", { "aria-hidden": "true", className: ["flex flex-col gap-2", className].join(" "), children: Array.from({ length: count }, (_, i) => (_jsxs("div", { className: "flex items-center gap-2.5 py-1", children: [_jsx(Skeleton, { width: "w-6", height: "h-6", className: "rounded-full shrink-0" }), _jsx(Skeleton, { width: i % 2 === 0 ? "w-3/4" : "w-1/2" })] }, i))) }));
14
+ }
@@ -0,0 +1,8 @@
1
+ import React, { ReactNode } from "react";
2
+ export interface FormFieldProps {
3
+ label: string;
4
+ htmlFor: string;
5
+ children: ReactNode;
6
+ }
7
+ /** The repeated `.rr-field` label+input wrapper. The input (and any hint/error text) is passed as children. */
8
+ export default function FormField({ label, htmlFor, children }: FormFieldProps): React.JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /** The repeated `.rr-field` label+input wrapper. The input (and any hint/error text) is passed as children. */
3
+ export default function FormField({ label, htmlFor, children }) {
4
+ return (_jsxs("div", { className: "mb-4", children: [_jsx("label", { htmlFor: htmlFor, className: "block text-sm font-semibold mb-1.5 text-text", children: label }), children] }));
5
+ }
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import type { IconType } from "react-icons";
3
+ /** A single icon-rail/bottom-tab entry — deliberately generic (not tied to `AppShell`'s own
4
+ * `AppDef`/`AppShellApp`) so both `AppShell` (www) and `AdminShell` (admin) can share this component
5
+ * for their own, differently-shaped nav item sets. */
6
+ export interface NavItem {
7
+ id: string;
8
+ href: string;
9
+ label: string;
10
+ icon: IconType;
11
+ }
12
+ export interface BottomTabBarProps {
13
+ apps: NavItem[];
14
+ active: string;
15
+ }
16
+ /**
17
+ * The mobile counterpart to an icon rail (`AppShell`'s Mail/Calendar/Contacts/Tasks, or `AdminShell`'s
18
+ * Mailboxes/Quarantine/Ingest Queue) — same data, same full-page-nav `<a href>` links (this framework
19
+ * has no client-side router), just relocated to a fixed bottom bar instead of a persistent left rail,
20
+ * which doesn't fit below the `md` breakpoint. Only ever rendered alongside that rail (`md:hidden` here,
21
+ * `hidden md:flex` there) — never both hidden or both visible at once.
22
+ *
23
+ * A few items share the width equally; a long list (the admin console has ten or so) doesn't fit at a readable size, so each
24
+ * item keeps a minimum width, its label wraps onto a second line rather than running into its neighbour's, and the bar scrolls
25
+ * sideways - opening with the active item in view.
26
+ */
27
+ export default function BottomTabBar({ apps, active }: BottomTabBarProps): React.JSX.Element;
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ ///////////////////////////////////////////////////////////////////////////////
3
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
4
+ // SPDX-License-Identifier: MPL-2.0
5
+ ///////////////////////////////////////////////////////////////////////////////
6
+ import { useEffect, useRef } from "react";
7
+ /**
8
+ * The mobile counterpart to an icon rail (`AppShell`'s Mail/Calendar/Contacts/Tasks, or `AdminShell`'s
9
+ * Mailboxes/Quarantine/Ingest Queue) — same data, same full-page-nav `<a href>` links (this framework
10
+ * has no client-side router), just relocated to a fixed bottom bar instead of a persistent left rail,
11
+ * which doesn't fit below the `md` breakpoint. Only ever rendered alongside that rail (`md:hidden` here,
12
+ * `hidden md:flex` there) — never both hidden or both visible at once.
13
+ *
14
+ * A few items share the width equally; a long list (the admin console has ten or so) doesn't fit at a readable size, so each
15
+ * item keeps a minimum width, its label wraps onto a second line rather than running into its neighbour's, and the bar scrolls
16
+ * sideways - opening with the active item in view.
17
+ */
18
+ export default function BottomTabBar({ apps, active }) {
19
+ const activeRef = useRef(null);
20
+ useEffect(() => {
21
+ const item = activeRef.current;
22
+ const bar = item?.parentElement;
23
+ if (item && bar && bar.scrollWidth > bar.clientWidth) {
24
+ // Set directly rather than `scrollIntoView()`, which would scroll the page as well.
25
+ bar.scrollLeft = item.offsetLeft - (bar.clientWidth - item.offsetWidth) / 2;
26
+ }
27
+ }, [active]);
28
+ return (_jsx("nav", { "aria-label": "Mobile navigation", className: "md:hidden fixed bottom-0 inset-x-0 z-30 h-14 bg-surface border-t border-border flex items-stretch overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: apps.map(({ id, href, label, icon: Icon }) => (_jsxs("a", { href: href, ref: id === active ? activeRef : undefined, "aria-current": id === active ? "page" : undefined, className: [
29
+ "flex-1 shrink-0 min-w-[4.75rem] px-1 flex flex-col items-center justify-center gap-0.5 text-[10px] leading-tight text-center font-medium",
30
+ id === active ? "text-primary-dark" : "text-text-muted",
31
+ ].join(" "), children: [_jsx(Icon, { size: 20, "aria-hidden": "true" }), label] }, id))) }));
32
+ }
@@ -0,0 +1,20 @@
1
+ import React, { ReactNode } from "react";
2
+ export interface DrawerProps {
3
+ open: boolean;
4
+ onClose: () => void;
5
+ title: string;
6
+ /** Which edge the drawer slides in from. Defaults to "left" (matches every current call site — a
7
+ * secondary sidebar or nav list). */
8
+ side?: "left" | "right";
9
+ /** Fill the whole window instead of a 18rem strip beside a dimmed page - what a phone's navigation drawer wants, where a sliver of the page behind
10
+ * it is only a mis-tap waiting to happen. The panel keeps the safe-area insets clear of a notch and the home indicator. Defaults to `false`. */
11
+ fullScreen?: boolean;
12
+ children: ReactNode;
13
+ }
14
+ /**
15
+ * An off-canvas panel for mobile, portal-rendered to `document.body` like `Modal.tsx` — same
16
+ * backdrop/focus-trap/Escape-key contract (shared via `overlayStack.ts`), just styled as a slide-in edge panel
17
+ * instead of a centered card. Used to hold a secondary sidebar's content below the `md` breakpoint,
18
+ * where it doesn't fit alongside the primary content.
19
+ */
20
+ export default function Drawer({ open, onClose, title, side, fullScreen, children }: DrawerProps): React.ReactPortal | null;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ ///////////////////////////////////////////////////////////////////////////////
3
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
4
+ // SPDX-License-Identifier: MPL-2.0
5
+ ///////////////////////////////////////////////////////////////////////////////
6
+ import { useRef } from "react";
7
+ import { createPortal } from "react-dom";
8
+ import { OverlayDepthContext, useOverlayDialog } from "./overlayStack.js";
9
+ /**
10
+ * An off-canvas panel for mobile, portal-rendered to `document.body` like `Modal.tsx` — same
11
+ * backdrop/focus-trap/Escape-key contract (shared via `overlayStack.ts`), just styled as a slide-in edge panel
12
+ * instead of a centered card. Used to hold a secondary sidebar's content below the `md` breakpoint,
13
+ * where it doesn't fit alongside the primary content.
14
+ */
15
+ export default function Drawer({ open, onClose, title, side = "left", fullScreen = false, children }) {
16
+ const dialogRef = useRef(null);
17
+ const childDepth = useOverlayDialog(open, dialogRef, onClose);
18
+ if (!open) {
19
+ return null;
20
+ }
21
+ return createPortal(_jsx("div", { className: "fixed inset-0 bg-black/50 z-[1000]", onMouseDown: (e) => e.target === e.currentTarget && onClose(), children: _jsxs("div", { className: [
22
+ fullScreen
23
+ ? "fixed inset-0 w-full overflow-y-auto bg-surface p-5 pt-[max(1.25rem,env(safe-area-inset-top))] pb-[max(1.25rem,env(safe-area-inset-bottom))] focus:outline-none"
24
+ : "fixed inset-y-0 w-72 max-w-[85vw] overflow-y-auto bg-surface border-border shadow-modal p-5 focus:outline-none",
25
+ fullScreen ? "" : side === "left" ? "left-0 border-r" : "right-0 border-l",
26
+ ].join(" "), role: "dialog", "aria-modal": "true", "aria-label": title, tabIndex: -1, ref: dialogRef, children: [_jsxs("div", { className: "flex items-start justify-between gap-4 mb-5", children: [_jsx("div", { className: "text-xl font-bold tracking-tight", children: title }), _jsx("button", { type: "button", className: "bg-transparent border-none text-text-muted text-2xl leading-none cursor-pointer p-0 hover:text-text", "aria-label": "Close", onClick: onClose, children: "\u00D7" })] }), _jsx("div", { children: _jsx(OverlayDepthContext.Provider, { value: childDepth, children: children }) })] }) }), document.body);
27
+ }
@@ -0,0 +1,17 @@
1
+ import React, { ReactNode } from "react";
2
+ export interface ModalProps {
3
+ open: boolean;
4
+ onClose: () => void;
5
+ title: string;
6
+ children: ReactNode;
7
+ }
8
+ /**
9
+ * A small, dependency-free modal dialog rendered via a portal to `document.body`. Controlled by the
10
+ * caller (`open` state lives in the parent, not here) so multiple call sites can share the same simple
11
+ * contract without each needing its own open/close plumbing.
12
+ *
13
+ * Focus moves into the dialog on open, Tab/Shift+Tab stay trapped inside it, and focus returns to the
14
+ * previously focused element on close. When overlays are stacked (Modal/Drawer), only the topmost one
15
+ * handles Escape and the focus trap - see `overlayStack.ts`.
16
+ */
17
+ export default function Modal({ open, onClose, title, children }: ModalProps): React.ReactPortal | null;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ ///////////////////////////////////////////////////////////////////////////////
3
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
4
+ // SPDX-License-Identifier: MPL-2.0
5
+ ///////////////////////////////////////////////////////////////////////////////
6
+ import { useRef } from "react";
7
+ import { createPortal } from "react-dom";
8
+ import { OverlayDepthContext, useOverlayDialog } from "./overlayStack.js";
9
+ /**
10
+ * A small, dependency-free modal dialog rendered via a portal to `document.body`. Controlled by the
11
+ * caller (`open` state lives in the parent, not here) so multiple call sites can share the same simple
12
+ * contract without each needing its own open/close plumbing.
13
+ *
14
+ * Focus moves into the dialog on open, Tab/Shift+Tab stay trapped inside it, and focus returns to the
15
+ * previously focused element on close. When overlays are stacked (Modal/Drawer), only the topmost one
16
+ * handles Escape and the focus trap - see `overlayStack.ts`.
17
+ */
18
+ export default function Modal({ open, onClose, title, children }) {
19
+ const dialogRef = useRef(null);
20
+ const childDepth = useOverlayDialog(open, dialogRef, onClose);
21
+ if (!open) {
22
+ return null;
23
+ }
24
+ return createPortal(_jsx("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center p-5 z-[1000]", onMouseDown: (e) => e.target === e.currentTarget && onClose(), children: _jsxs("div", { className: "w-full max-w-[440px] max-h-[calc(100vh-2.5rem)] overflow-y-auto bg-surface border border-border rounded-md shadow-modal p-7 focus:outline-none", role: "dialog", "aria-modal": "true", "aria-label": title, tabIndex: -1, ref: dialogRef, children: [_jsxs("div", { className: "flex items-start justify-between gap-4 mb-5", children: [_jsx("div", { className: "text-xl font-bold tracking-tight", children: title }), _jsx("button", { type: "button", className: "bg-transparent border-none text-text-muted text-2xl leading-none cursor-pointer p-0 hover:text-text", "aria-label": "Close", onClick: onClose, children: "\u00D7" })] }), _jsx("div", { children: _jsx(OverlayDepthContext.Provider, { value: childDepth, children: children }) })] }) }), document.body);
25
+ }
@@ -0,0 +1,23 @@
1
+ import React, { PropsWithChildren, RefObject } from "react";
2
+ export interface PopoverPortalProps {
3
+ /** The button (or other element) this popover is anchored to — used both to position it and to
4
+ * exclude it from the outside-click-closes check (it already has its own toggle handler; without
5
+ * this exclusion, a click on the trigger while open would close-then-immediately-reopen, since
6
+ * `pointerdown` fires — and closes it — before the trigger's own `click` handler re-opens it). */
7
+ anchorRef: RefObject<HTMLElement | null>;
8
+ onClose: () => void;
9
+ width: number;
10
+ height: number;
11
+ "aria-label": string;
12
+ }
13
+ /**
14
+ * Renders its children into `document.body` (via a portal), `position: fixed` at a spot computed from
15
+ * `anchorRef`'s own rect — used by `EmojiPicker`/`GifPicker` so the popup escapes every ancestor's
16
+ * `overflow-hidden` (the Compose window's own outer frame, and `RichTextEditor`'s bordered wrapper
17
+ * both clip anything positioned merely `absolute` inside them, however high its `z-index` — clipping
18
+ * isn't a stacking-order problem `z-index` can override). Prefers opening *below* the anchor (there's
19
+ * more room in the editor area below the toolbar than above it, where the To/Cc/Subject rows are —
20
+ * confirmed directly: an earlier `absolute`+`overflow-hidden` version of this rendered the popup
21
+ * behind those rows), flipping to *above* only if there isn't enough room below.
22
+ */
23
+ export default function PopoverPortal({ anchorRef, onClose, width, height, children, ...rest }: PropsWithChildren<PopoverPortalProps>): React.ReactPortal | null;