@k2b/ui 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.
- package/dist/browser/actions/ContextMenu.js +3 -1
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +3 -1
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/actions/SpotlightSearch.js +3 -1
- package/dist/browser/actions/SpotlightSearch.js.map +1 -1
- package/dist/browser/actions/filter-messages.js +20 -0
- package/dist/browser/actions/filter-messages.js.map +1 -0
- package/dist/browser/actions/spotlight-messages.js +16 -0
- package/dist/browser/actions/spotlight-messages.js.map +1 -0
- package/dist/browser/chat/ChatComposer.js +47 -41
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/ChatPrimitives.js +25 -23
- package/dist/browser/chat/ChatPrimitives.js.map +1 -1
- package/dist/browser/chat/ChatRoot.js +3 -3
- package/dist/browser/chat/ChatRoot.js.map +1 -1
- package/dist/browser/chat/ChatTimeline.js +12 -12
- package/dist/browser/chat/ChatTimeline.js.map +1 -1
- package/dist/browser/chat/chat-messages.js +236 -0
- package/dist/browser/chat/chat-messages.js.map +1 -0
- package/dist/browser/content/Calendar.js +1096 -1060
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/CalendarDayView.js +1187 -0
- package/dist/browser/content/CalendarDayView.js.map +1 -0
- package/dist/browser/content/CalendarWeekView.js +1571 -0
- package/dist/browser/content/CalendarWeekView.js.map +1 -0
- package/dist/browser/content/Chart.js +15 -8
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/ChartExplorer.js +185 -85
- package/dist/browser/content/ChartExplorer.js.map +1 -1
- package/dist/browser/content/ChartExplorerControls.js +9 -7
- package/dist/browser/content/ChartExplorerControls.js.map +1 -1
- package/dist/browser/content/ChartFilterControls.js +93 -34
- package/dist/browser/content/ChartFilterControls.js.map +1 -1
- package/dist/browser/content/ChartSnapshotView.js +3 -3
- package/dist/browser/content/ChartSnapshotView.js.map +1 -1
- package/dist/browser/content/DataTable.js +238 -201
- package/dist/browser/content/DataTable.js.map +1 -1
- package/dist/browser/content/Docs.js +3 -1
- package/dist/browser/content/Docs.js.map +1 -1
- package/dist/browser/content/FileBrowser.js +30 -26
- package/dist/browser/content/FileBrowser.js.map +1 -1
- package/dist/browser/content/FileTree.js +9 -7
- package/dist/browser/content/FileTree.js.map +1 -1
- package/dist/browser/content/FileView.js +37 -28
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/Lightbox.js +9 -7
- package/dist/browser/content/Lightbox.js.map +1 -1
- package/dist/browser/content/LogEntriesTable.js +3 -3
- package/dist/browser/content/LogEntriesTable.js.map +1 -1
- package/dist/browser/content/MessageRow.js +24 -22
- package/dist/browser/content/MessageRow.js.map +1 -1
- package/dist/browser/content/Pagination.js +7 -7
- package/dist/browser/content/Pagination.js.map +1 -1
- package/dist/browser/content/PdfPreview.js +15 -13
- package/dist/browser/content/PdfPreview.js.map +1 -1
- package/dist/browser/content/RangePicker.js +3 -1
- package/dist/browser/content/RangePicker.js.map +1 -1
- package/dist/browser/content/StructuredDataPreview.js +3 -1
- package/dist/browser/content/StructuredDataPreview.js.map +1 -1
- package/dist/browser/content/Timeline.js +13 -11
- package/dist/browser/content/Timeline.js.map +1 -1
- package/dist/browser/content/VideoPlayer.js +5 -5
- package/dist/browser/content/VideoPlayer.js.map +1 -1
- package/dist/browser/content/VirtualFeed.js +6 -4
- package/dist/browser/content/VirtualFeed.js.map +1 -1
- package/dist/browser/content/ZoomPanViewport.js +10 -7
- package/dist/browser/content/ZoomPanViewport.js.map +1 -1
- package/dist/browser/content/calendar-day-scroll.js +98 -0
- package/dist/browser/content/calendar-day-scroll.js.map +1 -0
- package/dist/browser/content/calendar-days.js +408 -0
- package/dist/browser/content/calendar-days.js.map +1 -0
- package/dist/browser/content/calendar-dialogs.js +236 -0
- package/dist/browser/content/calendar-dialogs.js.map +1 -0
- package/dist/browser/content/calendar-messages.js +249 -3
- package/dist/browser/content/calendar-messages.js.map +1 -1
- package/dist/browser/content/calendar-pointer.js +19 -6
- package/dist/browser/content/calendar-pointer.js.map +1 -1
- package/dist/browser/content/calendar-shared.js +328 -0
- package/dist/browser/content/calendar-shared.js.map +1 -0
- package/dist/browser/content/calendar-time-view.js +1649 -0
- package/dist/browser/content/calendar-time-view.js.map +1 -0
- package/dist/browser/content/chart-messages.js +146 -0
- package/dist/browser/content/chart-messages.js.map +1 -0
- package/dist/browser/content/collection-selection.js +2 -0
- package/dist/browser/content/collection-selection.js.map +1 -1
- package/dist/browser/content/data-table-messages.js +24 -0
- package/dist/browser/content/data-table-messages.js.map +1 -0
- package/dist/browser/content/docs-messages.js +24 -0
- package/dist/browser/content/docs-messages.js.map +1 -0
- package/dist/browser/content/feed-messages.js +34 -0
- package/dist/browser/content/feed-messages.js.map +1 -0
- package/dist/browser/content/file-browser-messages.js +69 -0
- package/dist/browser/content/file-browser-messages.js.map +1 -0
- package/dist/browser/content/file-view-messages.js +64 -0
- package/dist/browser/content/file-view-messages.js.map +1 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/lightbox-messages.js +36 -0
- package/dist/browser/content/lightbox-messages.js.map +1 -0
- package/dist/browser/content/log-entries-messages.js +20 -0
- package/dist/browser/content/log-entries-messages.js.map +1 -0
- package/dist/browser/content/markdown-info-block-messages.js +24 -0
- package/dist/browser/content/markdown-info-block-messages.js.map +1 -0
- package/dist/browser/content/markdown-info-blocks.js +3 -3
- package/dist/browser/content/markdown-info-blocks.js.map +1 -1
- package/dist/browser/content/markdown-links.js +2 -2
- package/dist/browser/content/markdown-links.js.map +1 -1
- package/dist/browser/content/markdown-reference-messages.js +30 -0
- package/dist/browser/content/markdown-reference-messages.js.map +1 -0
- package/dist/browser/content/pagination-messages.js +38 -0
- package/dist/browser/content/pagination-messages.js.map +1 -0
- package/dist/browser/content/pdf-messages.js +43 -0
- package/dist/browser/content/pdf-messages.js.map +1 -0
- package/dist/browser/content/range-picker-messages.js +20 -0
- package/dist/browser/content/range-picker-messages.js.map +1 -0
- package/dist/browser/content/structured-data-messages.js +22 -0
- package/dist/browser/content/structured-data-messages.js.map +1 -0
- package/dist/browser/content/timeline-messages.js +62 -0
- package/dist/browser/content/timeline-messages.js.map +1 -0
- package/dist/browser/content/video-messages.js +24 -0
- package/dist/browser/content/video-messages.js.map +1 -0
- package/dist/browser/content/viewport-messages.js +28 -0
- package/dist/browser/content/viewport-messages.js.map +1 -0
- package/dist/browser/feedback/HoverPreview.js +34 -6
- package/dist/browser/feedback/HoverPreview.js.map +1 -1
- package/dist/browser/feedback/InstallGuide.js +18 -18
- package/dist/browser/feedback/InstallGuide.js.map +1 -1
- package/dist/browser/feedback/install-messages.js +104 -0
- package/dist/browser/feedback/install-messages.js.map +1 -0
- package/dist/browser/feedback/prompt-messages.js +65 -0
- package/dist/browser/feedback/prompt-messages.js.map +1 -0
- package/dist/browser/feedback/prompts.js +14 -11
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/feedback/toast-messages.js +18 -0
- package/dist/browser/feedback/toast-messages.js.map +1 -0
- package/dist/browser/feedback/toast.js +4 -3
- package/dist/browser/feedback/toast.js.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/inputs/AutocompleteEditor.js +6 -4
- package/dist/browser/inputs/AutocompleteEditor.js.map +1 -1
- package/dist/browser/inputs/AutocompleteSelect.js +10 -8
- package/dist/browser/inputs/AutocompleteSelect.js.map +1 -1
- package/dist/browser/inputs/ChoiceGroups.js +4 -0
- package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
- package/dist/browser/inputs/ChoiceInputs.js +5 -5
- package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
- package/dist/browser/inputs/Combobox.js +3 -2
- package/dist/browser/inputs/Combobox.js.map +1 -1
- package/dist/browser/inputs/FileDropTarget.js +6 -6
- package/dist/browser/inputs/FileDropTarget.js.map +1 -1
- package/dist/browser/inputs/FileInputs.js +30 -21
- package/dist/browser/inputs/FileInputs.js.map +1 -1
- package/dist/browser/inputs/MultiSelectInput.js +7 -5
- package/dist/browser/inputs/MultiSelectInput.js.map +1 -1
- package/dist/browser/inputs/NumberInput.js +4 -2
- package/dist/browser/inputs/NumberInput.js.map +1 -1
- package/dist/browser/inputs/QrScanner.js +5 -5
- package/dist/browser/inputs/QrScanner.js.map +1 -1
- package/dist/browser/inputs/Select.js +7 -5
- package/dist/browser/inputs/Select.js.map +1 -1
- package/dist/browser/inputs/SelectChip.js +3 -3
- package/dist/browser/inputs/SelectChip.js.map +1 -1
- package/dist/browser/inputs/SignatureInput.js +9 -3
- package/dist/browser/inputs/SignatureInput.js.map +1 -1
- package/dist/browser/inputs/SpecialInputs.js +4 -2
- package/dist/browser/inputs/SpecialInputs.js.map +1 -1
- package/dist/browser/inputs/TagEditor.js +8 -6
- package/dist/browser/inputs/TagEditor.js.map +1 -1
- package/dist/browser/inputs/TagsInput.js +5 -5
- package/dist/browser/inputs/TagsInput.js.map +1 -1
- package/dist/browser/inputs/TemplateEditor.js +5 -5
- package/dist/browser/inputs/TemplateEditor.js.map +1 -1
- package/dist/browser/inputs/TextInput.js +3 -1
- package/dist/browser/inputs/TextInput.js.map +1 -1
- package/dist/browser/inputs/completion-messages.js +24 -0
- package/dist/browser/inputs/completion-messages.js.map +1 -0
- package/dist/browser/inputs/file-drop-messages.js +63 -0
- package/dist/browser/inputs/file-drop-messages.js.map +1 -0
- package/dist/browser/inputs/file-drop.js.map +1 -1
- package/dist/browser/inputs/file-input-messages.js +60 -0
- package/dist/browser/inputs/file-input-messages.js.map +1 -0
- package/dist/browser/inputs/icon-messages.js +22 -0
- package/dist/browser/inputs/icon-messages.js.map +1 -0
- package/dist/browser/inputs/input-messages.js +38 -0
- package/dist/browser/inputs/input-messages.js.map +1 -0
- package/dist/browser/inputs/markdown/MarkdownEditor.js +10 -6
- package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/browser/inputs/markdown/Toolbar.js +13 -13
- package/dist/browser/inputs/markdown/Toolbar.js.map +1 -1
- package/dist/browser/inputs/markdown/editor-messages.js +43 -0
- package/dist/browser/inputs/markdown/editor-messages.js.map +1 -0
- package/dist/browser/inputs/markdown/toolbar-messages.js +40 -0
- package/dist/browser/inputs/markdown/toolbar-messages.js.map +1 -0
- package/dist/browser/inputs/qr-messages.js +26 -0
- package/dist/browser/inputs/qr-messages.js.map +1 -0
- package/dist/browser/inputs/select-messages.js +63 -0
- package/dist/browser/inputs/select-messages.js.map +1 -0
- package/dist/browser/inputs/tag-messages.js +44 -0
- package/dist/browser/inputs/tag-messages.js.map +1 -0
- package/dist/browser/inputs/template-messages.js +22 -0
- package/dist/browser/inputs/template-messages.js.map +1 -0
- package/dist/browser/internal/render-error-messages.js +20 -0
- package/dist/browser/internal/render-error-messages.js.map +1 -0
- package/dist/browser/internal/render-error.js +3 -1
- package/dist/browser/internal/render-error.js.map +1 -1
- package/dist/browser/internal/text-selection.js +101 -0
- package/dist/browser/internal/text-selection.js.map +1 -0
- package/dist/browser/intl/messages.js +6 -1155
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +594 -425
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/BottomSheet.js +6 -1
- package/dist/browser/layout/BottomSheet.js.map +1 -1
- package/dist/browser/layout/Discussion.js +8 -5
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/FloatingWindow.js +8 -5
- package/dist/browser/layout/FloatingWindow.js.map +1 -1
- package/dist/browser/layout/Navigation.js +7 -6
- package/dist/browser/layout/Navigation.js.map +1 -1
- package/dist/browser/layout/PageTitle.js +373 -0
- package/dist/browser/layout/PageTitle.js.map +1 -0
- package/dist/browser/layout/PanelDialog.js +8 -6
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/Panes.js +23 -15
- package/dist/browser/layout/Panes.js.map +1 -1
- package/dist/browser/layout/PullToRefresh.js +13 -4
- package/dist/browser/layout/PullToRefresh.js.map +1 -1
- package/dist/browser/layout/Settings.js +14 -12
- package/dist/browser/layout/Settings.js.map +1 -1
- package/dist/browser/layout/SettingsCollection.js +6 -5
- package/dist/browser/layout/SettingsCollection.js.map +1 -1
- package/dist/browser/layout/SettingsModal.js +3 -1
- package/dist/browser/layout/SettingsModal.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +821 -12
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/app-workspace-state.js +3 -2
- package/dist/browser/layout/app-workspace-state.js.map +1 -1
- package/dist/browser/layout/floating-window-messages.js +28 -0
- package/dist/browser/layout/floating-window-messages.js.map +1 -0
- package/dist/browser/layout/index.js +2 -0
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/navigation-model.js.map +1 -1
- package/dist/browser/layout/page-title-controller.js +169 -0
- package/dist/browser/layout/page-title-controller.js.map +1 -0
- package/dist/browser/layout/panel-dialog-messages.js +20 -0
- package/dist/browser/layout/panel-dialog-messages.js.map +1 -0
- package/dist/browser/layout/panes-messages.js +48 -0
- package/dist/browser/layout/panes-messages.js.map +1 -0
- package/dist/browser/layout/refresh-messages.js +20 -0
- package/dist/browser/layout/refresh-messages.js.map +1 -0
- package/dist/browser/layout/settings-messages.js +54 -0
- package/dist/browser/layout/settings-messages.js.map +1 -0
- package/dist/browser/layout/workspace-messages.js +56 -0
- package/dist/browser/layout/workspace-messages.js.map +1 -0
- package/dist/browser/surfaces/Avatar.js +5 -5
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/ResourceCard.js +4 -2
- package/dist/browser/surfaces/ResourceCard.js.map +1 -1
- package/dist/browser/surfaces/StatCell.js +18 -6
- package/dist/browser/surfaces/StatCell.js.map +1 -1
- package/dist/browser/surfaces/Tag.js +3 -3
- package/dist/browser/surfaces/Tag.js.map +1 -1
- package/dist/browser/surfaces/avatar-messages.js +26 -0
- package/dist/browser/surfaces/avatar-messages.js.map +1 -0
- package/dist/browser/surfaces/resource-messages.js +26 -0
- package/dist/browser/surfaces/resource-messages.js.map +1 -0
- package/dist/browser/widgets/Widget.js +6 -0
- package/dist/browser/widgets/Widget.js.map +1 -1
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +3 -1
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/actions/SpotlightSearch.js +3 -1
- package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
- package/dist/ssr/actions/filter-messages.js +20 -0
- package/dist/ssr/actions/filter-messages.js.map +1 -0
- package/dist/ssr/actions/spotlight-messages.js +16 -0
- package/dist/ssr/actions/spotlight-messages.js.map +1 -0
- package/dist/ssr/chat/ChatComposer.js +47 -41
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/ChatPrimitives.js +23 -21
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
- package/dist/ssr/chat/ChatRoot.js +3 -3
- package/dist/ssr/chat/ChatRoot.js.map +1 -1
- package/dist/ssr/chat/ChatTimeline.js +11 -11
- package/dist/ssr/chat/ChatTimeline.js.map +1 -1
- package/dist/ssr/chat/chat-messages.js +236 -0
- package/dist/ssr/chat/chat-messages.js.map +1 -0
- package/dist/ssr/content/Calendar.js +534 -346
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/CalendarDayView.js +800 -0
- package/dist/ssr/content/CalendarDayView.js.map +1 -0
- package/dist/ssr/content/CalendarWeekView.js +1069 -0
- package/dist/ssr/content/CalendarWeekView.js.map +1 -0
- package/dist/ssr/content/Chart.js +12 -5
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/ChartExplorer.js +98 -37
- package/dist/ssr/content/ChartExplorer.js.map +1 -1
- package/dist/ssr/content/ChartExplorerControls.js +9 -7
- package/dist/ssr/content/ChartExplorerControls.js.map +1 -1
- package/dist/ssr/content/ChartFilterControls.js +52 -8
- package/dist/ssr/content/ChartFilterControls.js.map +1 -1
- package/dist/ssr/content/ChartSnapshotView.js +3 -3
- package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
- package/dist/ssr/content/DataTable.js +77 -53
- package/dist/ssr/content/DataTable.js.map +1 -1
- package/dist/ssr/content/Docs.js +3 -1
- package/dist/ssr/content/Docs.js.map +1 -1
- package/dist/ssr/content/FileBrowser.js +30 -26
- package/dist/ssr/content/FileBrowser.js.map +1 -1
- package/dist/ssr/content/FileTree.js +9 -7
- package/dist/ssr/content/FileTree.js.map +1 -1
- package/dist/ssr/content/FileView.js +37 -28
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/Lightbox.js +8 -6
- package/dist/ssr/content/Lightbox.js.map +1 -1
- package/dist/ssr/content/LogEntriesTable.js +3 -3
- package/dist/ssr/content/LogEntriesTable.js.map +1 -1
- package/dist/ssr/content/MessageRow.js +24 -22
- package/dist/ssr/content/MessageRow.js.map +1 -1
- package/dist/ssr/content/Pagination.js +6 -6
- package/dist/ssr/content/Pagination.js.map +1 -1
- package/dist/ssr/content/PdfPreview.js +15 -13
- package/dist/ssr/content/PdfPreview.js.map +1 -1
- package/dist/ssr/content/RangePicker.js +3 -1
- package/dist/ssr/content/RangePicker.js.map +1 -1
- package/dist/ssr/content/StructuredDataPreview.js +3 -1
- package/dist/ssr/content/StructuredDataPreview.js.map +1 -1
- package/dist/ssr/content/Timeline.js +13 -11
- package/dist/ssr/content/Timeline.js.map +1 -1
- package/dist/ssr/content/VideoPlayer.js +5 -5
- package/dist/ssr/content/VideoPlayer.js.map +1 -1
- package/dist/ssr/content/VirtualFeed.js +6 -4
- package/dist/ssr/content/VirtualFeed.js.map +1 -1
- package/dist/ssr/content/ZoomPanViewport.js +7 -4
- package/dist/ssr/content/ZoomPanViewport.js.map +1 -1
- package/dist/ssr/content/calendar-day-scroll.js +98 -0
- package/dist/ssr/content/calendar-day-scroll.js.map +1 -0
- package/dist/ssr/content/calendar-days.js +408 -0
- package/dist/ssr/content/calendar-days.js.map +1 -0
- package/dist/ssr/content/calendar-dialogs.js +159 -0
- package/dist/ssr/content/calendar-dialogs.js.map +1 -0
- package/dist/ssr/content/calendar-messages.js +249 -3
- package/dist/ssr/content/calendar-messages.js.map +1 -1
- package/dist/ssr/content/calendar-pointer.js +19 -6
- package/dist/ssr/content/calendar-pointer.js.map +1 -1
- package/dist/ssr/content/calendar-shared.js +261 -0
- package/dist/ssr/content/calendar-shared.js.map +1 -0
- package/dist/ssr/content/calendar-time-view.js +1306 -0
- package/dist/ssr/content/calendar-time-view.js.map +1 -0
- package/dist/ssr/content/chart-messages.js +146 -0
- package/dist/ssr/content/chart-messages.js.map +1 -0
- package/dist/ssr/content/collection-selection.js +2 -0
- package/dist/ssr/content/collection-selection.js.map +1 -1
- package/dist/ssr/content/data-table-messages.js +24 -0
- package/dist/ssr/content/data-table-messages.js.map +1 -0
- package/dist/ssr/content/docs-messages.js +24 -0
- package/dist/ssr/content/docs-messages.js.map +1 -0
- package/dist/ssr/content/feed-messages.js +34 -0
- package/dist/ssr/content/feed-messages.js.map +1 -0
- package/dist/ssr/content/file-browser-messages.js +69 -0
- package/dist/ssr/content/file-browser-messages.js.map +1 -0
- package/dist/ssr/content/file-view-messages.js +64 -0
- package/dist/ssr/content/file-view-messages.js.map +1 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/lightbox-messages.js +36 -0
- package/dist/ssr/content/lightbox-messages.js.map +1 -0
- package/dist/ssr/content/log-entries-messages.js +20 -0
- package/dist/ssr/content/log-entries-messages.js.map +1 -0
- package/dist/ssr/content/markdown-info-block-messages.js +24 -0
- package/dist/ssr/content/markdown-info-block-messages.js.map +1 -0
- package/dist/ssr/content/markdown-info-blocks.js +3 -3
- package/dist/ssr/content/markdown-info-blocks.js.map +1 -1
- package/dist/ssr/content/markdown-links.js +2 -2
- package/dist/ssr/content/markdown-links.js.map +1 -1
- package/dist/ssr/content/markdown-reference-messages.js +30 -0
- package/dist/ssr/content/markdown-reference-messages.js.map +1 -0
- package/dist/ssr/content/pagination-messages.js +38 -0
- package/dist/ssr/content/pagination-messages.js.map +1 -0
- package/dist/ssr/content/pdf-messages.js +43 -0
- package/dist/ssr/content/pdf-messages.js.map +1 -0
- package/dist/ssr/content/range-picker-messages.js +20 -0
- package/dist/ssr/content/range-picker-messages.js.map +1 -0
- package/dist/ssr/content/structured-data-messages.js +22 -0
- package/dist/ssr/content/structured-data-messages.js.map +1 -0
- package/dist/ssr/content/timeline-messages.js +62 -0
- package/dist/ssr/content/timeline-messages.js.map +1 -0
- package/dist/ssr/content/video-messages.js +24 -0
- package/dist/ssr/content/video-messages.js.map +1 -0
- package/dist/ssr/content/viewport-messages.js +28 -0
- package/dist/ssr/content/viewport-messages.js.map +1 -0
- package/dist/ssr/feedback/HoverPreview.js +34 -6
- package/dist/ssr/feedback/HoverPreview.js.map +1 -1
- package/dist/ssr/feedback/InstallGuide.js +18 -18
- package/dist/ssr/feedback/InstallGuide.js.map +1 -1
- package/dist/ssr/feedback/install-messages.js +104 -0
- package/dist/ssr/feedback/install-messages.js.map +1 -0
- package/dist/ssr/feedback/prompt-messages.js +65 -0
- package/dist/ssr/feedback/prompt-messages.js.map +1 -0
- package/dist/ssr/feedback/prompts.js +14 -11
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/feedback/toast-messages.js +18 -0
- package/dist/ssr/feedback/toast-messages.js.map +1 -0
- package/dist/ssr/feedback/toast.js +4 -3
- package/dist/ssr/feedback/toast.js.map +1 -1
- package/dist/ssr/index.js +1 -1
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/inputs/AutocompleteEditor.js +5 -3
- package/dist/ssr/inputs/AutocompleteEditor.js.map +1 -1
- package/dist/ssr/inputs/AutocompleteSelect.js +10 -8
- package/dist/ssr/inputs/AutocompleteSelect.js.map +1 -1
- package/dist/ssr/inputs/ChoiceGroups.js +4 -0
- package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
- package/dist/ssr/inputs/ChoiceInputs.js +5 -5
- package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
- package/dist/ssr/inputs/Combobox.js +3 -1
- package/dist/ssr/inputs/Combobox.js.map +1 -1
- package/dist/ssr/inputs/FileDropTarget.js +6 -6
- package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
- package/dist/ssr/inputs/FileInputs.js +29 -20
- package/dist/ssr/inputs/FileInputs.js.map +1 -1
- package/dist/ssr/inputs/MultiSelectInput.js +7 -5
- package/dist/ssr/inputs/MultiSelectInput.js.map +1 -1
- package/dist/ssr/inputs/NumberInput.js +4 -2
- package/dist/ssr/inputs/NumberInput.js.map +1 -1
- package/dist/ssr/inputs/QrScanner.js +4 -4
- package/dist/ssr/inputs/QrScanner.js.map +1 -1
- package/dist/ssr/inputs/Select.js +7 -5
- package/dist/ssr/inputs/Select.js.map +1 -1
- package/dist/ssr/inputs/SelectChip.js +3 -3
- package/dist/ssr/inputs/SelectChip.js.map +1 -1
- package/dist/ssr/inputs/SignatureInput.js +9 -3
- package/dist/ssr/inputs/SignatureInput.js.map +1 -1
- package/dist/ssr/inputs/SpecialInputs.js +4 -2
- package/dist/ssr/inputs/SpecialInputs.js.map +1 -1
- package/dist/ssr/inputs/TagEditor.js +8 -6
- package/dist/ssr/inputs/TagEditor.js.map +1 -1
- package/dist/ssr/inputs/TagsInput.js +5 -5
- package/dist/ssr/inputs/TagsInput.js.map +1 -1
- package/dist/ssr/inputs/TemplateEditor.js +5 -5
- package/dist/ssr/inputs/TemplateEditor.js.map +1 -1
- package/dist/ssr/inputs/TextInput.js +3 -1
- package/dist/ssr/inputs/TextInput.js.map +1 -1
- package/dist/ssr/inputs/completion-messages.js +24 -0
- package/dist/ssr/inputs/completion-messages.js.map +1 -0
- package/dist/ssr/inputs/file-drop-messages.js +63 -0
- package/dist/ssr/inputs/file-drop-messages.js.map +1 -0
- package/dist/ssr/inputs/file-drop.js.map +1 -1
- package/dist/ssr/inputs/file-input-messages.js +60 -0
- package/dist/ssr/inputs/file-input-messages.js.map +1 -0
- package/dist/ssr/inputs/icon-messages.js +22 -0
- package/dist/ssr/inputs/icon-messages.js.map +1 -0
- package/dist/ssr/inputs/input-messages.js +38 -0
- package/dist/ssr/inputs/input-messages.js.map +1 -0
- package/dist/ssr/inputs/markdown/MarkdownEditor.js +9 -5
- package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/ssr/inputs/markdown/Toolbar.js +13 -13
- package/dist/ssr/inputs/markdown/Toolbar.js.map +1 -1
- package/dist/ssr/inputs/markdown/editor-messages.js +43 -0
- package/dist/ssr/inputs/markdown/editor-messages.js.map +1 -0
- package/dist/ssr/inputs/markdown/toolbar-messages.js +40 -0
- package/dist/ssr/inputs/markdown/toolbar-messages.js.map +1 -0
- package/dist/ssr/inputs/qr-messages.js +26 -0
- package/dist/ssr/inputs/qr-messages.js.map +1 -0
- package/dist/ssr/inputs/select-messages.js +63 -0
- package/dist/ssr/inputs/select-messages.js.map +1 -0
- package/dist/ssr/inputs/tag-messages.js +44 -0
- package/dist/ssr/inputs/tag-messages.js.map +1 -0
- package/dist/ssr/inputs/template-messages.js +22 -0
- package/dist/ssr/inputs/template-messages.js.map +1 -0
- package/dist/ssr/internal/render-error-messages.js +20 -0
- package/dist/ssr/internal/render-error-messages.js.map +1 -0
- package/dist/ssr/internal/render-error.js +3 -1
- package/dist/ssr/internal/render-error.js.map +1 -1
- package/dist/ssr/internal/text-selection.js +101 -0
- package/dist/ssr/internal/text-selection.js.map +1 -0
- package/dist/ssr/intl/messages.js +6 -1155
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +219 -103
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/BottomSheet.js +1 -0
- package/dist/ssr/layout/BottomSheet.js.map +1 -1
- package/dist/ssr/layout/Discussion.js +8 -5
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/FloatingWindow.js +8 -5
- package/dist/ssr/layout/FloatingWindow.js.map +1 -1
- package/dist/ssr/layout/Navigation.js +6 -5
- package/dist/ssr/layout/Navigation.js.map +1 -1
- package/dist/ssr/layout/PageTitle.js +256 -0
- package/dist/ssr/layout/PageTitle.js.map +1 -0
- package/dist/ssr/layout/PanelDialog.js +8 -6
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/Panes.js +22 -14
- package/dist/ssr/layout/Panes.js.map +1 -1
- package/dist/ssr/layout/PullToRefresh.js +13 -4
- package/dist/ssr/layout/PullToRefresh.js.map +1 -1
- package/dist/ssr/layout/Settings.js +14 -12
- package/dist/ssr/layout/Settings.js.map +1 -1
- package/dist/ssr/layout/SettingsCollection.js +6 -5
- package/dist/ssr/layout/SettingsCollection.js.map +1 -1
- package/dist/ssr/layout/SettingsModal.js +3 -1
- package/dist/ssr/layout/SettingsModal.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +821 -12
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/app-workspace-state.js +3 -2
- package/dist/ssr/layout/app-workspace-state.js.map +1 -1
- package/dist/ssr/layout/floating-window-messages.js +28 -0
- package/dist/ssr/layout/floating-window-messages.js.map +1 -0
- package/dist/ssr/layout/index.js +2 -0
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/navigation-model.js.map +1 -1
- package/dist/ssr/layout/page-title-controller.js +169 -0
- package/dist/ssr/layout/page-title-controller.js.map +1 -0
- package/dist/ssr/layout/panel-dialog-messages.js +20 -0
- package/dist/ssr/layout/panel-dialog-messages.js.map +1 -0
- package/dist/ssr/layout/panes-messages.js +48 -0
- package/dist/ssr/layout/panes-messages.js.map +1 -0
- package/dist/ssr/layout/refresh-messages.js +20 -0
- package/dist/ssr/layout/refresh-messages.js.map +1 -0
- package/dist/ssr/layout/settings-messages.js +54 -0
- package/dist/ssr/layout/settings-messages.js.map +1 -0
- package/dist/ssr/layout/workspace-messages.js +56 -0
- package/dist/ssr/layout/workspace-messages.js.map +1 -0
- package/dist/ssr/surfaces/Avatar.js +5 -5
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/ResourceCard.js +4 -2
- package/dist/ssr/surfaces/ResourceCard.js.map +1 -1
- package/dist/ssr/surfaces/StatCell.js +2 -2
- package/dist/ssr/surfaces/StatCell.js.map +1 -1
- package/dist/ssr/surfaces/Tag.js +3 -3
- package/dist/ssr/surfaces/Tag.js.map +1 -1
- package/dist/ssr/surfaces/avatar-messages.js +26 -0
- package/dist/ssr/surfaces/avatar-messages.js.map +1 -0
- package/dist/ssr/surfaces/resource-messages.js +26 -0
- package/dist/ssr/surfaces/resource-messages.js.map +1 -0
- package/dist/ssr/widgets/Widget.js +6 -0
- package/dist/ssr/widgets/Widget.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/filter-messages.d.ts +8 -0
- package/dist/types/actions/spotlight-messages.d.ts +8 -0
- package/dist/types/chat/chat-messages.d.ts +116 -0
- package/dist/types/content/Calendar.d.ts +91 -0
- package/dist/types/content/CalendarDayView.d.ts +7 -0
- package/dist/types/content/CalendarWeekView.d.ts +7 -0
- package/dist/types/content/ChartExplorer.d.ts +36 -1
- package/dist/types/content/ChartFilterControls.d.ts +6 -1
- package/dist/types/content/DataTable.d.ts +7 -0
- package/dist/types/content/FileView.d.ts +0 -10
- package/dist/types/content/calendar-day-scroll.d.ts +42 -0
- package/dist/types/content/calendar-days.d.ts +192 -0
- package/dist/types/content/calendar-dialogs.d.ts +22 -0
- package/dist/types/content/calendar-messages.d.ts +119 -1
- package/dist/types/content/calendar-pointer.d.ts +9 -0
- package/dist/types/content/calendar-shared.d.ts +69 -0
- package/dist/types/content/calendar-time-view.d.ts +252 -0
- package/dist/types/content/chart-messages.d.ts +37 -0
- package/dist/types/content/data-table-messages.d.ts +10 -0
- package/dist/types/content/docs-messages.d.ts +10 -0
- package/dist/types/content/feed-messages.d.ts +15 -0
- package/dist/types/content/file-browser-messages.d.ts +33 -0
- package/dist/types/content/file-view-messages.d.ts +30 -0
- package/dist/types/content/index.d.ts +2 -2
- package/dist/types/content/lightbox-messages.d.ts +16 -0
- package/dist/types/content/log-entries-messages.d.ts +8 -0
- package/dist/types/content/markdown-info-block-messages.d.ts +12 -0
- package/dist/types/content/markdown-reference-messages.d.ts +15 -0
- package/dist/types/content/pagination-messages.d.ts +17 -0
- package/dist/types/content/pdf-messages.d.ts +20 -0
- package/dist/types/content/range-picker-messages.d.ts +8 -0
- package/dist/types/content/structured-data-messages.d.ts +9 -0
- package/dist/types/content/timeline-messages.d.ts +29 -0
- package/dist/types/content/video-messages.d.ts +10 -0
- package/dist/types/content/viewport-messages.d.ts +12 -0
- package/dist/types/feedback/install-messages.d.ts +50 -0
- package/dist/types/feedback/prompt-messages.d.ts +31 -0
- package/dist/types/feedback/toast-messages.d.ts +9 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/inputs/completion-messages.d.ts +10 -0
- package/dist/types/inputs/file-drop-messages.d.ts +30 -0
- package/dist/types/inputs/file-drop.d.ts +3 -3
- package/dist/types/inputs/file-input-messages.d.ts +28 -0
- package/dist/types/inputs/icon-messages.d.ts +9 -0
- package/dist/types/inputs/input-messages.d.ts +17 -0
- package/dist/types/inputs/markdown/editor-messages.d.ts +20 -0
- package/dist/types/inputs/markdown/toolbar-messages.d.ts +18 -0
- package/dist/types/inputs/qr-messages.d.ts +11 -0
- package/dist/types/inputs/select-messages.d.ts +30 -0
- package/dist/types/inputs/tag-messages.d.ts +20 -0
- package/dist/types/inputs/template-messages.d.ts +9 -0
- package/dist/types/internal/render-error-messages.d.ts +8 -0
- package/dist/types/internal/text-selection.d.ts +18 -0
- package/dist/types/intl/messages.d.ts +3 -544
- package/dist/types/layout/AppWorkspace.d.ts +42 -5
- package/dist/types/layout/PageTitle.d.ts +65 -0
- package/dist/types/layout/app-workspace-controller.d.ts +12 -0
- package/dist/types/layout/app-workspace-state.d.ts +3 -2
- package/dist/types/layout/floating-window-messages.d.ts +12 -0
- package/dist/types/layout/index.d.ts +3 -0
- package/dist/types/layout/navigation-model.d.ts +7 -0
- package/dist/types/layout/page-title-controller.d.ts +13 -0
- package/dist/types/layout/panel-dialog-messages.d.ts +8 -0
- package/dist/types/layout/panes-messages.d.ts +22 -0
- package/dist/types/layout/refresh-messages.d.ts +8 -0
- package/dist/types/layout/settings-messages.d.ts +25 -0
- package/dist/types/layout/workspace-messages.d.ts +26 -0
- package/dist/types/surfaces/StatCell.d.ts +5 -0
- package/dist/types/surfaces/avatar-messages.d.ts +11 -0
- package/dist/types/surfaces/resource-messages.d.ts +11 -0
- package/dist/types/widgets/Widget.d.ts +5 -1
- package/package.json +1 -1
|
@@ -65,6 +65,7 @@ import { fileIcons } from "@k2b/stdlib";
|
|
|
65
65
|
import { createMemo, createSignal, createUniqueId, For, onCleanup, Show } from "solid-js";
|
|
66
66
|
import { Button, IconButton } from "../actions/Button";
|
|
67
67
|
import { copyText } from "../actions/CopyButton";
|
|
68
|
+
import { useChatMessages } from "../chat/chat-messages";
|
|
68
69
|
import { announce } from "../feedback/announce";
|
|
69
70
|
import { useLocale } from "../intl/locale";
|
|
70
71
|
import { useUiMessages } from "../intl/messages";
|
|
@@ -239,7 +240,7 @@ function AttachmentTarget(props) {
|
|
|
239
240
|
* Renders the safe Markdown of `MarkdownView` with line breaks kept, absolute links only, and a copy control above
|
|
240
241
|
* every code block, and counts the fewest lines it takes. An edited message that does not collapse ends with the marker.
|
|
241
242
|
*/
|
|
242
|
-
const renderMessage = (text, locale, messages, edited) => {
|
|
243
|
+
const renderMessage = (text, locale, messages, chatMessages, edited) => {
|
|
243
244
|
const renderer = createSafeRenderer({
|
|
244
245
|
allowImages: false,
|
|
245
246
|
linkProtocols: LINK_PROTOCOLS,
|
|
@@ -267,7 +268,7 @@ const renderMessage = (text, locale, messages, edited) => {
|
|
|
267
268
|
lines
|
|
268
269
|
};
|
|
269
270
|
// The marker ends the last paragraph, so it takes no line of its own there.
|
|
270
|
-
const marker = `<span class="k2b-message-row__edited">${escapeHtml(
|
|
271
|
+
const marker = `<span class="k2b-message-row__edited">${escapeHtml(chatMessages.messageEdited)}</span>`;
|
|
271
272
|
const end = html.trimEnd();
|
|
272
273
|
return {
|
|
273
274
|
html: end.endsWith("</p>") ? `${end.slice(0, -4)} ${marker}</p>` : `${html}<p>${marker}</p>`,
|
|
@@ -282,10 +283,11 @@ const renderMessage = (text, locale, messages, edited) => {
|
|
|
282
283
|
*/
|
|
283
284
|
export function MessageRow(props) {
|
|
284
285
|
const messages = useUiMessages();
|
|
286
|
+
const chatMessages = useChatMessages();
|
|
285
287
|
const locale = useLocale();
|
|
286
288
|
const textId = `k2b-message-${createUniqueId()}`;
|
|
287
289
|
const [expanded, setExpanded] = createSignal(false);
|
|
288
|
-
const rendered = createMemo(() => renderMessage(props.text, locale(), messages(), Boolean(props.edited)));
|
|
290
|
+
const rendered = createMemo(() => renderMessage(props.text, locale(), messages(), chatMessages(), Boolean(props.edited)));
|
|
289
291
|
const collapsible = () => rendered().lines > COLLAPSE_LINES;
|
|
290
292
|
const collapsed = () => collapsible() && !expanded();
|
|
291
293
|
const groupStart = () => props.groupStart ?? true;
|
|
@@ -333,16 +335,16 @@ export function MessageRow(props) {
|
|
|
333
335
|
return _$ssr(_tmpl$6, _$escape(props.badge));
|
|
334
336
|
}
|
|
335
337
|
}), _$ssr(_tmpl$7, _$ssrAttribute("datetime", _$escape(dateTimeOf(props.dateTime), true), false), _$escape(props.time))];
|
|
336
|
-
const quote = value => [_$ssr(_tmpl$8), _$ssr(_tmpl$9, _$escape(
|
|
338
|
+
const quote = value => [_$ssr(_tmpl$8), _$ssr(_tmpl$9, _$escape(chatMessages().messageReplyTo), _$escape(value.author), _$escape(value.text))];
|
|
337
339
|
|
|
338
340
|
/** The picture's description, then that it is a video and how long, then how many more the grid hides. */
|
|
339
|
-
const mediaLabel = (item, more) => [item.alt, item.kind === "video" ? [
|
|
341
|
+
const mediaLabel = (item, more) => [item.alt, item.kind === "video" ? [chatMessages().messageVideo, item.duration].filter(Boolean).join(" ") : "", more > 0 ? chatMessages().messageMoreAttachments({
|
|
340
342
|
count: more
|
|
341
343
|
}) : ""].filter(Boolean).join(", ");
|
|
342
344
|
|
|
343
345
|
/** A toggle button, or with no `onToggleReaction` a labelled image that also says whether the reader reacted. */
|
|
344
346
|
const reactionChip = (key, reaction) => {
|
|
345
|
-
const label = own =>
|
|
347
|
+
const label = own => chatMessages().messageReaction({
|
|
346
348
|
emoji: reaction().emoji,
|
|
347
349
|
count: reaction().count,
|
|
348
350
|
names: reaction().label,
|
|
@@ -452,7 +454,7 @@ export function MessageRow(props) {
|
|
|
452
454
|
return _$memo(() => !!content())() && props.forwarded;
|
|
453
455
|
},
|
|
454
456
|
get children() {
|
|
455
|
-
return _$ssr(_tmpl$17, _$escape(
|
|
457
|
+
return _$ssr(_tmpl$17, _$escape(chatMessages().messageForwarded));
|
|
456
458
|
}
|
|
457
459
|
})), _$escape(_$createComponent(Show, {
|
|
458
460
|
get when() {
|
|
@@ -477,7 +479,7 @@ export function MessageRow(props) {
|
|
|
477
479
|
return !props.deleted;
|
|
478
480
|
},
|
|
479
481
|
get fallback() {
|
|
480
|
-
return _$ssr(_tmpl$34, _$escape(
|
|
482
|
+
return _$ssr(_tmpl$34, _$escape(chatMessages().messageDeleted));
|
|
481
483
|
},
|
|
482
484
|
get children() {
|
|
483
485
|
return _$createComponent(Show, {
|
|
@@ -503,14 +505,14 @@ export function MessageRow(props) {
|
|
|
503
505
|
"aria-controls": textId,
|
|
504
506
|
onClick: () => setExpanded(value => !value),
|
|
505
507
|
get children() {
|
|
506
|
-
return expanded() ?
|
|
508
|
+
return expanded() ? chatMessages().messageShowLess : chatMessages().messageShowMore;
|
|
507
509
|
}
|
|
508
510
|
})), _$escape(_$createComponent(Show, {
|
|
509
511
|
get when() {
|
|
510
512
|
return props.edited;
|
|
511
513
|
},
|
|
512
514
|
get children() {
|
|
513
|
-
return _$ssr(_tmpl$19, _$escape(
|
|
515
|
+
return _$ssr(_tmpl$19, _$escape(chatMessages().messageEdited));
|
|
514
516
|
}
|
|
515
517
|
})));
|
|
516
518
|
}
|
|
@@ -525,14 +527,14 @@ export function MessageRow(props) {
|
|
|
525
527
|
return _$memo(() => !!(content() && props.edited))() && !hasBubble();
|
|
526
528
|
},
|
|
527
529
|
get children() {
|
|
528
|
-
return _$ssr(_tmpl$22, _$escape(
|
|
530
|
+
return _$ssr(_tmpl$22, _$escape(chatMessages().messageEdited));
|
|
529
531
|
}
|
|
530
532
|
})), _$escape(_$createComponent(Show, {
|
|
531
533
|
get when() {
|
|
532
534
|
return media().length > 0;
|
|
533
535
|
},
|
|
534
536
|
get children() {
|
|
535
|
-
return _$ssr(_tmpl$23, _$ssrAttribute("aria-label", _$escape(
|
|
537
|
+
return _$ssr(_tmpl$23, _$ssrAttribute("aria-label", _$escape(chatMessages().attachments, true), false) + _$ssrAttribute("data-count", _$escape(Math.min(media().length, MEDIA_SHOWN), true), false), _$ssrStyle(media().length === 1 ? {
|
|
536
538
|
width: mediaWidth(media()[0])
|
|
537
539
|
} : undefined), _$escape(_$createComponent(For, {
|
|
538
540
|
get each() {
|
|
@@ -612,13 +614,13 @@ export function MessageRow(props) {
|
|
|
612
614
|
})
|
|
613
615
|
})));
|
|
614
616
|
}
|
|
615
|
-
})), _$escape(
|
|
617
|
+
})), _$escape(chatMessages().messageReplies({
|
|
616
618
|
count: thread().count
|
|
617
619
|
})), _$escape(_$createComponent(Show, {
|
|
618
620
|
get when() {
|
|
619
621
|
return thread().lastReply;
|
|
620
622
|
},
|
|
621
|
-
children: time => _$ssr(_tmpl$41, _$ssrAttribute("datetime", _$escape(dateTimeOf(thread().lastReplyDateTime), true), false), _$escape(
|
|
623
|
+
children: time => _$ssr(_tmpl$41, _$ssrAttribute("datetime", _$escape(dateTimeOf(thread().lastReplyDateTime), true), false), _$escape(chatMessages().messageLastReply({
|
|
622
624
|
time: time()
|
|
623
625
|
})))
|
|
624
626
|
})))
|
|
@@ -631,7 +633,7 @@ export function MessageRow(props) {
|
|
|
631
633
|
get when() {
|
|
632
634
|
return reactions();
|
|
633
635
|
},
|
|
634
|
-
children: list => _$ssr(_tmpl$42, _$ssrAttribute("aria-label", _$escape(
|
|
636
|
+
children: list => _$ssr(_tmpl$42, _$ssrAttribute("aria-label", _$escape(chatMessages().messageReactions, true), false) + _$ssrAttribute("data-empty", list().length === 0 ? "" : _$escape(undefined, true), false), _$escape(_$createComponent(Show, {
|
|
635
637
|
get when() {
|
|
636
638
|
return list().length > 0;
|
|
637
639
|
},
|
|
@@ -663,7 +665,7 @@ export function MessageRow(props) {
|
|
|
663
665
|
},
|
|
664
666
|
children: add => _$createComponent(IconButton, {
|
|
665
667
|
get label() {
|
|
666
|
-
return
|
|
668
|
+
return chatMessages().messageAddReaction;
|
|
667
669
|
},
|
|
668
670
|
size: "xs",
|
|
669
671
|
"class": "k2b-message-row__react",
|
|
@@ -688,14 +690,14 @@ export function MessageRow(props) {
|
|
|
688
690
|
return props.status === "pending";
|
|
689
691
|
},
|
|
690
692
|
get children() {
|
|
691
|
-
return [_$ssr(_tmpl$44), _$ssr(_tmpl$45, _$escape(
|
|
693
|
+
return [_$ssr(_tmpl$44), _$ssr(_tmpl$45, _$escape(chatMessages().sending))];
|
|
692
694
|
}
|
|
693
695
|
}), _$createComponent(Show, {
|
|
694
696
|
get when() {
|
|
695
697
|
return props.status === "failed";
|
|
696
698
|
},
|
|
697
699
|
get children() {
|
|
698
|
-
return [_$ssr(_tmpl$46), _$ssr(_tmpl$45, _$escape(
|
|
700
|
+
return [_$ssr(_tmpl$46), _$ssr(_tmpl$45, _$escape(chatMessages().messageNotSent)), _$createComponent(Show, {
|
|
699
701
|
get when() {
|
|
700
702
|
return props.onRetry;
|
|
701
703
|
},
|
|
@@ -704,7 +706,7 @@ export function MessageRow(props) {
|
|
|
704
706
|
size: "xs",
|
|
705
707
|
onClick: () => retry()(),
|
|
706
708
|
get children() {
|
|
707
|
-
return
|
|
709
|
+
return chatMessages().messageRetry;
|
|
708
710
|
}
|
|
709
711
|
})
|
|
710
712
|
})];
|
|
@@ -724,7 +726,7 @@ export function MessageRow(props) {
|
|
|
724
726
|
return props.status === "sent";
|
|
725
727
|
},
|
|
726
728
|
get children() {
|
|
727
|
-
return [_$ssr(_tmpl$47), _$ssr(_tmpl$48, _$escape(
|
|
729
|
+
return [_$ssr(_tmpl$47), _$ssr(_tmpl$48, _$escape(chatMessages().messageSent))];
|
|
728
730
|
}
|
|
729
731
|
});
|
|
730
732
|
},
|
|
@@ -742,7 +744,7 @@ export function MessageRow(props) {
|
|
|
742
744
|
size: "xs",
|
|
743
745
|
onClick: () => stop()(),
|
|
744
746
|
get children() {
|
|
745
|
-
return
|
|
747
|
+
return chatMessages().messageStop;
|
|
746
748
|
}
|
|
747
749
|
})
|
|
748
750
|
})]
|
|
@@ -755,7 +757,7 @@ export function MessageRow(props) {
|
|
|
755
757
|
return (props.actions?.length ?? 0) > 0;
|
|
756
758
|
},
|
|
757
759
|
get children() {
|
|
758
|
-
return _$ssr(_tmpl$28, _$ssrAttribute("aria-label", _$escape(
|
|
760
|
+
return _$ssr(_tmpl$28, _$ssrAttribute("aria-label", _$escape(chatMessages().messageActions, true), false), _$escape(_$createComponent(For, {
|
|
759
761
|
get each() {
|
|
760
762
|
return props.actions;
|
|
761
763
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/MessageRow.tsx"],"sourcesContent":["import { fileIcons } from \"@k2b/stdlib\";\nimport type { Token, Tokens } from \"marked\";\nimport { type Accessor, createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { copyText } from \"../actions/CopyButton\";\nimport { announce } from \"../feedback/announce\";\nimport { useLocale } from \"../intl/locale\";\nimport { type UiMessages, useUiMessages } from \"../intl/messages\";\nimport { ScrollArea } from \"../layout/ScrollArea\";\nimport { Avatar } from \"../surfaces/Avatar\";\nimport { createSafeMarked, createSafeRenderer, escapeHtml } from \"./MarkdownView\";\n\n/** Messages by the same author within this time continue a group. */\nconst GROUP_WINDOW_MS = 5 * 60_000;\n/**\n * A message collapses to ten lines (`.k2b-message-row__text[data-collapsed]`) when its rendered text takes more lines\n * than this. `renderedLines` counts the fewest lines the text takes at any width, so a collapsed message always hides\n * some of it.\n */\nconst COLLAPSE_LINES = 14;\n/** Visible characters that take at least one line of a message, even at its widest. */\nconst LINE_CHARS = 100;\n/** Lines at the bottom of a collapsed message that fade out, as `.k2b-message-row__text[data-collapsed]` draws them. */\nconst FADE_LINES = 2;\nconst COPIED_MS = 2_000;\n/** Links in messages may only use these schemes; other links show as their text. */\nconst LINK_PROTOCOLS = [\"https:\", \"http:\", \"mailto:\"] as const;\n/** Attachments open and load only from these schemes or from a relative URL. */\nconst ATTACHMENT_PROTOCOLS = new Set([\"https:\", \"http:\"]);\n/**\n * A picture may also show a file that is still uploading. A `blob:` URL runs in the page's origin when it is opened,\n * so links never use one.\n */\nconst PICTURE_PROTOCOLS = new Set([...ATTACHMENT_PROTOCOLS, \"blob:\"]);\n/** A grid shows this many images or videos; the last one tells how many more there are. */\nconst MEDIA_SHOWN = 4;\n/** A single image keeps its own aspect ratio within these bounds; beyond them it is cropped to fit. */\nconst MEDIA_RATIO_MIN = 0.5;\nconst MEDIA_RATIO_MAX = 3;\n\nexport type MessageRowAuthor = {\n /** Display name, shown at the start of a group and read before every message. */\n name: string;\n /** Picture URL. Without one, the avatar shows initials on the author's tint. */\n avatar?: string | null;\n /** Icon class shown instead of initials, for example for an automated author. */\n icon?: string;\n};\n\nexport type MessageRowStatus = \"pending\" | \"sent\" | \"failed\";\n\nexport type MessageRowAction = {\n id: string;\n /** Accessible name and tooltip. */\n label: string;\n /** Icon class, for example `ti ti-arrow-back-up`. */\n icon: string;\n onSelect: () => void;\n disabled?: boolean;\n};\n\nexport type MessageRowQuote = {\n /** Name of the quoted message's author. */\n author: string;\n /** Plain text of the quoted message. It shows at most two lines. */\n text: string;\n /** Opens the quoted message, for example by scrolling to it. Without it, the quote is not a control. */\n onSelect?: () => void;\n};\n\nexport type MessageRowReaction = {\n /** Stable identity of the reaction, passed to `onToggleReaction`. */\n key: string;\n emoji: string;\n count: number;\n /** The reader reacted this way; the chip shows pressed. */\n own?: boolean;\n /** Who reacted, for example \"Nora, Tobias\". Read by screen readers and shown as a tooltip. */\n label?: string;\n};\n\nexport type MessageRowThread = {\n /** Number of replies. */\n count: number;\n /** People who replied, most recent first; the bar shows up to three. */\n participants?: readonly MessageRowAuthor[];\n /** Visible time of the last reply, formatted by the caller. */\n lastReply?: string;\n lastReplyDateTime?: string | Date;\n onOpen: () => void;\n};\n\ntype MessageRowAttachmentTarget = {\n /** Opens the attachment, for example in a lightbox. Takes precedence over `href`. */\n onOpen?: () => void;\n /** Opens the attachment in a new tab. Absolute `https` or `http`, or relative. */\n href?: string;\n};\n\nexport type MessageRowMedia = MessageRowAttachmentTarget & {\n kind: \"image\" | \"video\";\n /** The image, or the poster frame of a video. Absolute `https` or `http`, relative, `blob`, or `data:image/`. */\n src: string;\n /** Describes the image or video for people who cannot see it. */\n alt: string;\n /** Stored pixel size. The row reserves the area from it, so nothing moves when the image loads. */\n width: number;\n height: number;\n /** Visible length of a video, for example \"0:42\". */\n duration?: string;\n};\n\nexport type MessageRowFile = MessageRowAttachmentTarget & {\n kind: \"file\";\n name: string;\n /** Second line, for example \"PDF · 412 KB\". */\n detail?: string;\n /** Media type, used with the name to choose the icon. */\n mediaType?: string;\n /** Icon class instead of the one chosen from the name. */\n icon?: string;\n};\n\nexport type MessageRowAttachment = MessageRowMedia | MessageRowFile;\n\nexport type MessageRowProgress = {\n /** What is happening, for example \"Writing\" or \"Searching the files\". */\n status: string;\n /** Called by \"Stop\". */\n onStop?: () => void;\n};\n\nexport type MessageRowProps = {\n author: MessageRowAuthor;\n /** Message text as Markdown. Raw HTML shows as text; links must be absolute and use `https`, `http`, or `mailto`. */\n text: string;\n /** Visible time, formatted by the caller, so server and browser render the same text. */\n time: string;\n /** Machine-readable time for the `<time>` element. */\n dateTime?: string | Date;\n /** The reader's own message: on the right in the accent tint, without avatar or name. */\n own?: boolean;\n /**\n * Starts a group with avatar, name, badge, and time. A continuation shows only its text; screen readers still hear\n * the author and time. Defaults to true; `startsMessageGroup` decides it from the previous message.\n */\n groupStart?: boolean;\n /** Shown next to the name at the start of a group, for example the kind of account. */\n badge?: JSX.Element;\n /** Send state. Sets a line of fixed height below the message: a clock, a check, or \"Not sent\" with \"Retry\". */\n status?: MessageRowStatus;\n /** Text shown in that line instead of the check once someone has read the message, for example \"Read by Nora\". */\n receipt?: string;\n /** Called by \"Retry\" while `status` is `\"failed\"`. */\n onRetry?: () => void;\n /** Shown as a toolbar over the message while it is hovered or focused. It never moves the layout. */\n actions?: readonly MessageRowAction[];\n /** The message this one answers, shown above it. */\n quote?: MessageRowQuote;\n /** Marks the message as forwarded from somewhere else. */\n forwarded?: boolean;\n /** Marks the message as edited after it was sent. */\n edited?: boolean;\n /** Shows \"This message was deleted\" instead of the text, quote, attachments, previews, and reactions. */\n deleted?: boolean;\n /** Images and videos in a grid with areas reserved from their stored size, then files as chips. */\n attachments?: readonly MessageRowAttachment[];\n /** A preview of a link in the text, supplied with its final height. */\n linkPreview?: JSX.Element;\n /** A card for an element the message refers to, such as a task or a document, supplied with its final height. */\n card?: JSX.Element;\n /**\n * Reactions in a bar of fixed height. The bar shows whenever this is set, even to an empty list, so chips that come\n * and go never change the row. Only setting it where it was unset adds a line, so pass it on own messages and on\n * messages that have or had reactions, and leave it out on others' messages that never had one.\n */\n reactions?: readonly MessageRowReaction[];\n /** Called with a reaction's `key` when the reader presses its chip. Without it, the chips are not controls. */\n onToggleReaction?: (key: string) => void;\n /** Called by \"Add reaction\" in the reaction bar, with the button to anchor a picker to. */\n onAddReaction?: (anchor: HTMLElement) => void;\n /** A bar of fixed height that opens the replies to this message. */\n thread?: MessageRowThread;\n /** The message is still being written, by a person or an automated author alike: a status line with \"Stop\". */\n progress?: MessageRowProgress;\n class?: string;\n};\n\nexport type MessageSystemRowProps = {\n /** What happened, for example \"Nora added Tobias\". */\n children: JSX.Element;\n /** Visible time, formatted by the caller. */\n time?: string;\n dateTime?: string | Date;\n /** Icon class shown before the text. */\n icon?: string;\n class?: string;\n};\n\nexport type MessageGroupEntry = {\n /** Stable identity of the author. */\n author: string;\n at: Date | number | string;\n /** System rows never belong to a group. */\n system?: boolean;\n};\n\nconst timestamp = (value: Date | number | string) => (value instanceof Date ? value.getTime() : new Date(value).getTime());\n\n/**\n * Whether a message starts a new group: there is no previous message, either is a system row, the author changes, or\n * more than five minutes passed. Also start a group where you show a separator such as a new day.\n */\nexport const startsMessageGroup = (entry: MessageGroupEntry, previous?: MessageGroupEntry | null): boolean => {\n if (!previous || entry.system || previous.system || entry.author !== previous.author) return true;\n const gap = timestamp(entry.at) - timestamp(previous.at);\n return !(gap >= 0 && gap <= GROUP_WINDOW_MS);\n};\n\n/** Text that wraps: every `LINE_CHARS` visible characters of a line take at least one line. */\nconst wrappedLines = (text: string): number =>\n text.split(\"\\n\").reduce((lines, line) => lines + Math.ceil(line.trim().length / LINE_CHARS), 0);\n\n/** What inline tokens show: a link its label, never its destination. */\nconst inlineText = (tokens: readonly Token[]): string => {\n let text = \"\";\n for (const token of tokens) {\n if (token.type === \"br\") text += \"\\n\";\n else if (\"tokens\" in token && token.tokens) text += inlineText(token.tokens);\n else if (\"text\" in token) text += token.text;\n }\n return text;\n};\n\n/**\n * The fewest lines the rendered tokens take at any width. Code never wraps, so each of its lines is one line, blank\n * ones too, and its bar one more. Link destinations and reference definitions show nothing. Decided from the text\n * alone, so the row has its final height when it mounts.\n */\nconst renderedLines = (tokens: readonly Token[]): number => {\n let lines = 0;\n for (const token of tokens) {\n switch (token.type) {\n case \"code\":\n lines += token.text.split(\"\\n\").length + 1;\n break;\n case \"list\":\n for (const item of token.items) lines += Math.max(1, renderedLines(item.tokens));\n break;\n case \"table\":\n lines += token.rows.length + (token.header.some((cell: Tokens.TableCell) => cell.text.trim()) ? 1 : 0);\n break;\n case \"paragraph\":\n case \"heading\":\n case \"text\":\n lines += wrappedLines(token.tokens ? inlineText(token.tokens) : token.text);\n break;\n case \"hr\":\n lines += 1;\n break;\n case \"space\":\n case \"def\":\n break;\n default:\n if (\"tokens\" in token && token.tokens) lines += renderedLines(token.tokens);\n else if (\"text\" in token) lines += wrappedLines(token.text);\n }\n }\n return lines;\n};\n\n/** Messages link only to absolute URLs; a relative one would lead somewhere else on every page that shows it. */\nconst isAbsoluteUrl = (href: string): boolean => {\n try {\n return new URL(href).protocol !== \"\";\n } catch {\n return false;\n }\n};\n\nconst dateTimeOf = (value: string | Date | undefined): string | undefined => {\n if (value === undefined) return undefined;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isFinite(date.getTime()) ? date.toISOString() : undefined;\n};\n\n/**\n * An attachment URL the row may load or open: absolute with an allowed scheme, or relative to the page. A picture may\n * also be a `blob:` URL or a `data:image/` URL, which an image element shows without running anything.\n */\nconst attachmentUrl = (url: string | undefined, picture = false): string | undefined => {\n if (!url) return undefined;\n if (picture && /^data:image\\//i.test(url)) return url;\n try {\n return (picture ? PICTURE_PROTOCOLS : ATTACHMENT_PROTOCOLS).has(new URL(url, \"https://relative.invalid/\").protocol) ? url : undefined;\n } catch {\n return undefined;\n }\n};\n\n/** The aspect ratio a single image or video reserves, from its stored size. */\nconst mediaRatio = (media: MessageRowMedia): number => {\n const ratio = media.width > 0 && media.height > 0 ? media.width / media.height : 4 / 3;\n return Math.min(MEDIA_RATIO_MAX, Math.max(MEDIA_RATIO_MIN, ratio));\n};\n\n/** The width of a single image or video: its stored width, at most the row's media height tall, never wider than the row. */\nconst mediaWidth = (media: MessageRowMedia): string => {\n const natural = Number.isFinite(media.width) && media.width > 0 ? `${media.width}px, ` : \"\";\n return `min(100%, ${natural}calc(var(--k2b-message-media-height) * ${mediaRatio(media)}))`;\n};\n\n/** Only the `ti-*` glyph of `fileIcons`, which may add colour utilities that `@k2b/ui` does not ship. */\nconst fileIcon = (file: MessageRowFile): string =>\n file.icon ??\n `ti ${fileIcons\n .getFileIcon({ name: file.name, type: \"file\", mimeType: file.mediaType })\n .split(/\\s+/)\n .filter((token) => token.startsWith(\"ti-\"))\n .join(\" \")}`;\n\n/** A link, a button, or neither, depending on what the caller passes. */\nfunction AttachmentTarget(\n props: MessageRowAttachmentTarget & {\n class: string;\n style?: JSX.CSSProperties;\n /** Names a picture; without a link or button around it, the element becomes the image. */\n label?: string;\n children: JSX.Element;\n },\n): JSX.Element {\n return (\n <Show\n when={props.onOpen}\n fallback={\n <Show\n when={attachmentUrl(props.href)}\n fallback={\n <Show\n when={props.label}\n fallback={\n <span class={props.class} style={props.style}>\n {props.children}\n </span>\n }\n >\n {(label) => (\n <span class={props.class} style={props.style} role=\"img\" aria-label={label()}>\n {props.children}\n </span>\n )}\n </Show>\n }\n >\n {(href) => (\n <a class={props.class} style={props.style} href={href()} target=\"_blank\" rel=\"noopener noreferrer\" aria-label={props.label}>\n {props.children}\n </a>\n )}\n </Show>\n }\n >\n {(open) => (\n <button type=\"button\" class={props.class} style={props.style} aria-label={props.label} onClick={() => open()()}>\n {props.children}\n </button>\n )}\n </Show>\n );\n}\n\n/**\n * Renders the safe Markdown of `MarkdownView` with line breaks kept, absolute links only, and a copy control above\n * every code block, and counts the fewest lines it takes. An edited message that does not collapse ends with the marker.\n */\nconst renderMessage = (text: string, locale: string, messages: UiMessages, edited: boolean): { html: string; lines: number } => {\n const renderer = createSafeRenderer({ allowImages: false, linkProtocols: LINK_PROTOCOLS, linkTarget: \"_blank\", locale });\n const renderLink = renderer.link.bind(renderer);\n renderer.link = (token: Tokens.Link) => (isAbsoluteUrl(token.href) ? renderLink(token) : renderer.parser.parseInline(token.tokens));\n const renderCode = renderer.code.bind(renderer);\n renderer.code = (token: Tokens.Code) => {\n const language = token.lang?.match(/^\\S{1,24}/)?.[0];\n const block = renderCode(token).replace(/^<pre>/, '<pre tabindex=\"0\">');\n return (\n '<div class=\"k2b-message-row__code\" data-gesture-ignore><div class=\"k2b-message-row__code-bar\">' +\n `<span class=\"k2b-message-row__code-label\">${escapeHtml(language ?? messages.code)}</span>` +\n '<button type=\"button\" class=\"k2b-message-row__copy\">' +\n `<span class=\"k2b-message-row__copy-idle\"><i class=\"ti ti-copy\" aria-hidden=\"true\"></i>${escapeHtml(messages.copy)}</span>` +\n `<span class=\"k2b-message-row__copy-done\"><i class=\"ti ti-check\" aria-hidden=\"true\"></i>${escapeHtml(messages.copied)}</span>` +\n `</button></div>${block}</div>`\n );\n };\n const marked = createSafeMarked(locale).setOptions({ breaks: true, renderer });\n const tokens = marked.lexer(text);\n const html = marked.parser(tokens);\n const lines = renderedLines(tokens);\n // A collapsed message would hide the end of its text, so its marker sits next to \"Show more\" instead.\n if (!edited || lines > COLLAPSE_LINES) return { html, lines };\n // The marker ends the last paragraph, so it takes no line of its own there.\n const marker = `<span class=\"k2b-message-row__edited\">${escapeHtml(messages.messageEdited)}</span>`;\n const end = html.trimEnd();\n return { html: end.endsWith(\"</p>\") ? `${end.slice(0, -4)} ${marker}</p>` : `${html}<p>${marker}</p>`, lines };\n};\n\n/**\n * One message in a conversation with many people: own messages on the right, others on the left with avatar, name,\n * and time at the start of a group. Every part has its final height when the row mounts, so a virtualized list such\n * as `VirtualFeed` keeps its positions.\n */\nexport function MessageRow(props: MessageRowProps): JSX.Element {\n const messages = useUiMessages();\n const locale = useLocale();\n const textId = `k2b-message-${createUniqueId()}`;\n const [expanded, setExpanded] = createSignal(false);\n const rendered = createMemo(() => renderMessage(props.text, locale(), messages(), Boolean(props.edited)));\n const collapsible = () => rendered().lines > COLLAPSE_LINES;\n const collapsed = () => collapsible() && !expanded();\n const groupStart = () => props.groupStart ?? true;\n const hasLine = () => props.progress !== undefined || props.status !== undefined || props.receipt !== undefined;\n const reactions = () => (props.deleted ? undefined : props.reactions);\n // Chips follow their keys, so a chip keeps its element, and focus, when the caller passes new objects for it.\n const reactionKeys = createMemo(() => reactions()?.map((reaction) => reaction.key) ?? []);\n const reactionByKey = createMemo(() => new Map(reactions()?.map((reaction) => [reaction.key, reaction])));\n const hasFooter = () => hasLine() || reactions() !== undefined;\n const writing = () => props.progress !== undefined && !props.deleted && props.text.trim() === \"\";\n const hasBubble = () => props.deleted || writing() || props.text.trim() !== \"\";\n const content = () => !props.deleted;\n const media = createMemo(() =>\n content() ? (props.attachments ?? []).filter((attachment): attachment is MessageRowMedia => attachment.kind !== \"file\") : [],\n );\n const files = createMemo(() =>\n content() ? (props.attachments ?? []).filter((attachment): attachment is MessageRowFile => attachment.kind === \"file\") : [],\n );\n const shownMedia = () => media().slice(0, MEDIA_SHOWN);\n const hiddenMedia = () => media().length - shownMedia().length;\n let text: HTMLDivElement | undefined;\n let copiedTimer: ReturnType<typeof setTimeout> | undefined;\n\n onCleanup(() => clearTimeout(copiedTimer));\n\n const copyCode = (event: MouseEvent) => {\n const button = (event.target as Element | null)?.closest?.<HTMLButtonElement>(\".k2b-message-row__copy\");\n if (!button || !text?.contains(button)) return;\n const code = button.closest(\".k2b-message-row__code\")?.querySelector(\"pre\")?.textContent ?? \"\";\n copyText(code).then(\n () => {\n for (const other of text?.querySelectorAll<HTMLElement>(\".k2b-message-row__copy[data-copied]\") ?? []) delete other.dataset.copied;\n button.dataset.copied = \"\";\n announce(messages().copied);\n clearTimeout(copiedTimer);\n copiedTimer = setTimeout(() => delete button.dataset.copied, COPIED_MS);\n },\n () => {},\n );\n };\n\n // A keyboard user who reaches a link or code block in the hidden or faded part of a collapsed message gets the whole\n // message. The collapsed text clips instead of scrolling, so the browser cannot scroll it to the target instead.\n const revealFocus = (event: FocusEvent) => {\n if (!text || !collapsed() || !(event.target instanceof Element)) return;\n const fade = text.getBoundingClientRect().bottom - FADE_LINES * Number.parseFloat(getComputedStyle(text).lineHeight);\n if (event.target.getBoundingClientRect().bottom > fade) setExpanded(true);\n };\n\n const header = () => (\n <>\n <span class=\"k2b-message-row__name\">{props.author.name}</span>\n <Show when={props.badge}>\n <span class=\"k2b-message-row__badge\">{props.badge}</span>\n </Show>\n <time class=\"k2b-message-row__time\" datetime={dateTimeOf(props.dateTime)}>\n {props.time}\n </time>\n </>\n );\n\n const quote = (value: MessageRowQuote) => (\n <>\n <i class=\"ti ti-arrow-back-up\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__quote-text\">\n <span class=\"k2b-sr-only\">{messages().messageReplyTo} </span>\n <span class=\"k2b-message-row__quote-author\">{value.author}</span> {value.text}\n </span>\n </>\n );\n\n /** The picture's description, then that it is a video and how long, then how many more the grid hides. */\n const mediaLabel = (item: MessageRowMedia, more: number) =>\n [\n item.alt,\n item.kind === \"video\" ? [messages().messageVideo, item.duration].filter(Boolean).join(\" \") : \"\",\n more > 0 ? messages().messageMoreAttachments({ count: more }) : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n\n /** A toggle button, or with no `onToggleReaction` a labelled image that also says whether the reader reacted. */\n const reactionChip = (key: string, reaction: Accessor<MessageRowReaction>) => {\n const label = (own: boolean) =>\n messages().messageReaction({ emoji: reaction().emoji, count: reaction().count, names: reaction().label, own });\n return (\n <Show\n when={props.onToggleReaction}\n fallback={\n <span\n class=\"k2b-message-row__reaction\"\n role=\"img\"\n aria-label={label(Boolean(reaction().own))}\n title={reaction().label}\n data-own={reaction().own ? \"\" : undefined}\n >\n <span aria-hidden=\"true\">{reaction().emoji}</span>\n <span aria-hidden=\"true\">{reaction().count}</span>\n </span>\n }\n >\n {(toggle) => (\n <button\n type=\"button\"\n class=\"k2b-message-row__reaction\"\n aria-pressed={reaction().own ? \"true\" : \"false\"}\n aria-label={label(false)}\n title={reaction().label}\n data-own={reaction().own ? \"\" : undefined}\n onClick={() => toggle()(key)}\n >\n <span aria-hidden=\"true\">{reaction().emoji}</span>\n <span aria-hidden=\"true\">{reaction().count}</span>\n </button>\n )}\n </Show>\n );\n };\n\n const mediaItem = (item: MessageRowMedia, index: () => number) => {\n const more = () => (index() === shownMedia().length - 1 ? hiddenMedia() : 0);\n return (\n <AttachmentTarget\n class=\"k2b-message-row__media-item\"\n style={media().length === 1 ? { \"aspect-ratio\": String(mediaRatio(item)) } : undefined}\n label={mediaLabel(item, more())}\n onOpen={item.onOpen}\n href={item.href}\n >\n <img\n src={attachmentUrl(item.src, true)}\n alt=\"\"\n width={item.width > 0 ? item.width : undefined}\n height={item.height > 0 ? item.height : undefined}\n loading=\"lazy\"\n decoding=\"async\"\n />\n <Show when={item.kind === \"video\"}>\n <span class=\"k2b-message-row__media-play\" aria-hidden=\"true\">\n <i class=\"ti ti-player-play\" />\n </span>\n <Show when={item.duration}>\n <span class=\"k2b-message-row__media-duration\" aria-hidden=\"true\">\n {item.duration}\n </span>\n </Show>\n </Show>\n <Show when={more() > 0}>\n <span class=\"k2b-message-row__media-more\" aria-hidden=\"true\">\n +{more()}\n </span>\n </Show>\n </AttachmentTarget>\n );\n };\n\n return (\n <div\n class={props.class ? `k2b-message-row ${props.class}` : \"k2b-message-row\"}\n data-own={props.own ? \"\" : undefined}\n data-group-start={groupStart() ? \"\" : undefined}\n data-status={props.status}\n data-media={media().length > 0 ? \"\" : undefined}\n >\n <Show when={!props.own}>\n <div class=\"k2b-message-row__gutter\">\n <Show when={groupStart()}>\n <span class=\"k2b-message-row__avatar\" aria-hidden=\"true\">\n <Avatar name={props.author.name} src={props.author.avatar} icon={props.author.icon} size=\"sm\" />\n </span>\n </Show>\n </div>\n </Show>\n <div class=\"k2b-message-row__body\">\n <Show\n when={groupStart()}\n fallback={\n <span class=\"k2b-sr-only\">\n {props.author.name}, {props.time}:{\" \"}\n </span>\n }\n >\n <Show\n when={!props.own}\n fallback={\n <div class=\"k2b-message-row__meta\">\n <span class=\"k2b-sr-only\">{props.author.name}, </span>\n <time class=\"k2b-message-row__time\" datetime={dateTimeOf(props.dateTime)}>\n {props.time}\n </time>\n </div>\n }\n >\n <div class=\"k2b-message-row__meta\">{header()}</div>\n </Show>\n </Show>\n <Show when={content() && props.forwarded}>\n <div class=\"k2b-message-row__marker\">\n <i class=\"ti ti-arrow-forward-up\" aria-hidden=\"true\" />\n <span>{messages().messageForwarded}</span>\n </div>\n </Show>\n <Show when={content() && props.quote}>\n {(value) => (\n <Show when={value().onSelect} fallback={<div class=\"k2b-message-row__quote\">{quote(value())}</div>}>\n {(select) => (\n <button type=\"button\" class=\"k2b-message-row__quote\" onClick={() => select()()}>\n {quote(value())}\n </button>\n )}\n </Show>\n )}\n </Show>\n <Show when={hasBubble()}>\n <div\n class=\"k2b-message-row__bubble\"\n data-deleted={props.deleted ? \"\" : undefined}\n aria-busy={props.progress && !props.deleted ? \"true\" : undefined}\n >\n <Show\n when={!props.deleted}\n fallback={\n <span class=\"k2b-message-row__deleted\">\n <i class=\"ti ti-message-off\" aria-hidden=\"true\" />\n {messages().messageDeleted}\n </span>\n }\n >\n <Show\n when={!writing()}\n fallback={\n <span class=\"k2b-message-row__writing\">\n <span class=\"k2b-chat-progress-dots\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n </span>\n }\n >\n {/* biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: the native copy buttons inside the rendered Markdown are the targets; their clicks, including from the keyboard, bubble here. */}\n <div\n ref={text}\n id={textId}\n class=\"k2b-content-markdown k2b-message-row__text\"\n data-heading-scale=\"compact\"\n data-collapsed={collapsed() ? \"\" : undefined}\n onClick={copyCode}\n onFocusIn={revealFocus}\n innerHTML={rendered().html}\n />\n <Show when={collapsible()}>\n <div class=\"k2b-message-row__more-line\">\n <Button\n variant=\"text\"\n size=\"xs\"\n class=\"k2b-message-row__more\"\n aria-expanded={expanded() ? \"true\" : \"false\"}\n aria-controls={textId}\n onClick={() => setExpanded((value) => !value)}\n >\n {expanded() ? messages().messageShowLess : messages().messageShowMore}\n </Button>\n <Show when={props.edited}>\n <span class=\"k2b-message-row__edited\">{messages().messageEdited}</span>\n </Show>\n </div>\n </Show>\n </Show>\n </Show>\n </div>\n </Show>\n {/* Without a bubble to end, the edit marker takes the bubble's place. */}\n <Show when={content() && props.edited && !hasBubble()}>\n <div class=\"k2b-message-row__marker\">\n <i class=\"ti ti-pencil\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__edited\">{messages().messageEdited}</span>\n </div>\n </Show>\n <Show when={media().length > 0}>\n <div\n class=\"k2b-message-row__media\"\n role=\"group\"\n aria-label={messages().attachments}\n data-count={Math.min(media().length, MEDIA_SHOWN)}\n style={media().length === 1 ? { width: mediaWidth(media()[0]!) } : undefined}\n >\n <For each={shownMedia()}>{(item, index) => mediaItem(item, index)}</For>\n </div>\n </Show>\n <Show when={files().length > 0}>\n <div class=\"k2b-message-row__files\">\n <For each={files()}>\n {(file) => (\n <AttachmentTarget class=\"k2b-message-row__file\" onOpen={file.onOpen} href={file.href}>\n <span class=\"k2b-message-row__file-icon\" aria-hidden=\"true\">\n <i class={fileIcon(file)} />\n </span>\n <span class=\"k2b-message-row__file-copy\">\n <span class=\"k2b-message-row__file-name\">{file.name}</span>\n <Show when={file.detail}>\n <span class=\"k2b-message-row__file-detail\">{file.detail}</span>\n </Show>\n </span>\n </AttachmentTarget>\n )}\n </For>\n </div>\n </Show>\n <Show when={content() && props.linkPreview}>\n <div class=\"k2b-message-row__slot\" data-gesture-ignore>\n {props.linkPreview}\n </div>\n </Show>\n <Show when={content() && props.card}>\n <div class=\"k2b-message-row__slot\" data-gesture-ignore>\n {props.card}\n </div>\n </Show>\n <Show when={props.thread}>\n {(thread) => (\n <button type=\"button\" class=\"k2b-message-row__thread\" onClick={() => thread().onOpen()}>\n <Show when={(thread().participants?.length ?? 0) > 0}>\n <span class=\"k2b-message-row__thread-people\" aria-hidden=\"true\">\n <For each={thread().participants?.slice(0, 3)}>\n {(person) => <Avatar name={person.name} src={person.avatar} icon={person.icon} size=\"xs\" />}\n </For>\n </span>\n </Show>\n <span class=\"k2b-message-row__thread-count\">{messages().messageReplies({ count: thread().count })}</span>\n <Show when={thread().lastReply}>\n {(time) => (\n <time class=\"k2b-message-row__thread-time\" datetime={dateTimeOf(thread().lastReplyDateTime)}>\n {messages().messageLastReply({ time: time() })}\n </time>\n )}\n </Show>\n </button>\n )}\n </Show>\n <Show when={hasFooter()}>\n <div class=\"k2b-message-row__footer\">\n <Show when={reactions()}>\n {(list) => (\n <div\n class=\"k2b-message-row__reactions\"\n role=\"group\"\n aria-label={messages().messageReactions}\n data-empty={list().length === 0 ? \"\" : undefined}\n >\n <Show when={list().length > 0}>\n {/* Chips that do not fit scroll sideways behind a fade. Read-only chips are no tab stops, so the list\n is one: a keyboard can scroll it. */}\n <ScrollArea\n orientation=\"horizontal\"\n class=\"k2b-message-row__reaction-list\"\n tabindex={props.onToggleReaction ? undefined : 0}\n >\n <For each={reactionKeys()}>\n {(key) => <Show when={reactionByKey().get(key)}>{(reaction) => reactionChip(key, reaction)}</Show>}\n </For>\n </ScrollArea>\n </Show>\n <Show when={props.onAddReaction}>\n {(add) => (\n <IconButton\n label={messages().messageAddReaction}\n size=\"xs\"\n class=\"k2b-message-row__react\"\n onClick={(event) => add()(event.currentTarget)}\n >\n <i class=\"ti ti-mood-plus\" aria-hidden=\"true\" />\n </IconButton>\n )}\n </Show>\n </div>\n )}\n </Show>\n <Show when={hasLine()}>\n <div class=\"k2b-message-row__line\">\n <Show\n when={props.progress}\n fallback={\n <>\n <Show when={props.status === \"pending\"}>\n <i class=\"ti ti-clock\" aria-hidden=\"true\" />\n <span>{messages().sending}</span>\n </Show>\n <Show when={props.status === \"failed\"}>\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n <span>{messages().messageNotSent}</span>\n <Show when={props.onRetry}>\n {(retry) => (\n <Button variant=\"text\" size=\"xs\" onClick={() => retry()()}>\n {messages().messageRetry}\n </Button>\n )}\n </Show>\n </Show>\n <Show when={props.status !== \"pending\" && props.status !== \"failed\"}>\n <Show\n when={props.receipt}\n fallback={\n <Show when={props.status === \"sent\"}>\n <i class=\"ti ti-check\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{messages().messageSent}</span>\n </Show>\n }\n >\n {(receipt) => (\n <>\n <i class=\"ti ti-checks\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__receipt\">{receipt()}</span>\n </>\n )}\n </Show>\n </Show>\n </>\n }\n >\n {(progress) => (\n <>\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__line-text\">{progress().status}</span>\n <Show when={progress().onStop}>\n {(stop) => (\n <Button variant=\"text\" size=\"xs\" onClick={() => stop()()}>\n {messages().messageStop}\n </Button>\n )}\n </Show>\n </>\n )}\n </Show>\n </div>\n </Show>\n </div>\n </Show>\n </div>\n <Show when={(props.actions?.length ?? 0) > 0}>\n <div class=\"k2b-message-row__actions\" role=\"group\" aria-label={messages().messageActions}>\n <For each={props.actions}>\n {(action) => (\n <IconButton label={action.label} size=\"sm\" disabled={action.disabled} onClick={() => action.onSelect()}>\n <i class={action.icon} aria-hidden=\"true\" />\n </IconButton>\n )}\n </For>\n </div>\n </Show>\n </div>\n );\n}\n\n/** A quiet, centered line for something that happened in the conversation, such as a person joining. */\nexport function MessageSystemRow(props: MessageSystemRowProps): JSX.Element {\n return (\n <div class={props.class ? `k2b-message-system-row ${props.class}` : \"k2b-message-system-row\"}>\n <Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span>{props.children}</span>\n <Show when={props.time}>\n <time datetime={dateTimeOf(props.dateTime)}>{props.time}</time>\n </Show>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/MessageRow.tsx"],"sourcesContent":["import { fileIcons } from \"@k2b/stdlib\";\nimport type { Token, Tokens } from \"marked\";\nimport { type Accessor, createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { copyText } from \"../actions/CopyButton\";\nimport { type ChatMessages, useChatMessages } from \"../chat/chat-messages\";\nimport { announce } from \"../feedback/announce\";\nimport { useLocale } from \"../intl/locale\";\nimport { type UiMessages, useUiMessages } from \"../intl/messages\";\nimport { ScrollArea } from \"../layout/ScrollArea\";\nimport { Avatar } from \"../surfaces/Avatar\";\nimport { createSafeMarked, createSafeRenderer, escapeHtml } from \"./MarkdownView\";\n\n/** Messages by the same author within this time continue a group. */\nconst GROUP_WINDOW_MS = 5 * 60_000;\n/**\n * A message collapses to ten lines (`.k2b-message-row__text[data-collapsed]`) when its rendered text takes more lines\n * than this. `renderedLines` counts the fewest lines the text takes at any width, so a collapsed message always hides\n * some of it.\n */\nconst COLLAPSE_LINES = 14;\n/** Visible characters that take at least one line of a message, even at its widest. */\nconst LINE_CHARS = 100;\n/** Lines at the bottom of a collapsed message that fade out, as `.k2b-message-row__text[data-collapsed]` draws them. */\nconst FADE_LINES = 2;\nconst COPIED_MS = 2_000;\n/** Links in messages may only use these schemes; other links show as their text. */\nconst LINK_PROTOCOLS = [\"https:\", \"http:\", \"mailto:\"] as const;\n/** Attachments open and load only from these schemes or from a relative URL. */\nconst ATTACHMENT_PROTOCOLS = new Set([\"https:\", \"http:\"]);\n/**\n * A picture may also show a file that is still uploading. A `blob:` URL runs in the page's origin when it is opened,\n * so links never use one.\n */\nconst PICTURE_PROTOCOLS = new Set([...ATTACHMENT_PROTOCOLS, \"blob:\"]);\n/** A grid shows this many images or videos; the last one tells how many more there are. */\nconst MEDIA_SHOWN = 4;\n/** A single image keeps its own aspect ratio within these bounds; beyond them it is cropped to fit. */\nconst MEDIA_RATIO_MIN = 0.5;\nconst MEDIA_RATIO_MAX = 3;\n\nexport type MessageRowAuthor = {\n /** Display name, shown at the start of a group and read before every message. */\n name: string;\n /** Picture URL. Without one, the avatar shows initials on the author's tint. */\n avatar?: string | null;\n /** Icon class shown instead of initials, for example for an automated author. */\n icon?: string;\n};\n\nexport type MessageRowStatus = \"pending\" | \"sent\" | \"failed\";\n\nexport type MessageRowAction = {\n id: string;\n /** Accessible name and tooltip. */\n label: string;\n /** Icon class, for example `ti ti-arrow-back-up`. */\n icon: string;\n onSelect: () => void;\n disabled?: boolean;\n};\n\nexport type MessageRowQuote = {\n /** Name of the quoted message's author. */\n author: string;\n /** Plain text of the quoted message. It shows at most two lines. */\n text: string;\n /** Opens the quoted message, for example by scrolling to it. Without it, the quote is not a control. */\n onSelect?: () => void;\n};\n\nexport type MessageRowReaction = {\n /** Stable identity of the reaction, passed to `onToggleReaction`. */\n key: string;\n emoji: string;\n count: number;\n /** The reader reacted this way; the chip shows pressed. */\n own?: boolean;\n /** Who reacted, for example \"Nora, Tobias\". Read by screen readers and shown as a tooltip. */\n label?: string;\n};\n\nexport type MessageRowThread = {\n /** Number of replies. */\n count: number;\n /** People who replied, most recent first; the bar shows up to three. */\n participants?: readonly MessageRowAuthor[];\n /** Visible time of the last reply, formatted by the caller. */\n lastReply?: string;\n lastReplyDateTime?: string | Date;\n onOpen: () => void;\n};\n\ntype MessageRowAttachmentTarget = {\n /** Opens the attachment, for example in a lightbox. Takes precedence over `href`. */\n onOpen?: () => void;\n /** Opens the attachment in a new tab. Absolute `https` or `http`, or relative. */\n href?: string;\n};\n\nexport type MessageRowMedia = MessageRowAttachmentTarget & {\n kind: \"image\" | \"video\";\n /** The image, or the poster frame of a video. Absolute `https` or `http`, relative, `blob`, or `data:image/`. */\n src: string;\n /** Describes the image or video for people who cannot see it. */\n alt: string;\n /** Stored pixel size. The row reserves the area from it, so nothing moves when the image loads. */\n width: number;\n height: number;\n /** Visible length of a video, for example \"0:42\". */\n duration?: string;\n};\n\nexport type MessageRowFile = MessageRowAttachmentTarget & {\n kind: \"file\";\n name: string;\n /** Second line, for example \"PDF · 412 KB\". */\n detail?: string;\n /** Media type, used with the name to choose the icon. */\n mediaType?: string;\n /** Icon class instead of the one chosen from the name. */\n icon?: string;\n};\n\nexport type MessageRowAttachment = MessageRowMedia | MessageRowFile;\n\nexport type MessageRowProgress = {\n /** What is happening, for example \"Writing\" or \"Searching the files\". */\n status: string;\n /** Called by \"Stop\". */\n onStop?: () => void;\n};\n\nexport type MessageRowProps = {\n author: MessageRowAuthor;\n /** Message text as Markdown. Raw HTML shows as text; links must be absolute and use `https`, `http`, or `mailto`. */\n text: string;\n /** Visible time, formatted by the caller, so server and browser render the same text. */\n time: string;\n /** Machine-readable time for the `<time>` element. */\n dateTime?: string | Date;\n /** The reader's own message: on the right in the accent tint, without avatar or name. */\n own?: boolean;\n /**\n * Starts a group with avatar, name, badge, and time. A continuation shows only its text; screen readers still hear\n * the author and time. Defaults to true; `startsMessageGroup` decides it from the previous message.\n */\n groupStart?: boolean;\n /** Shown next to the name at the start of a group, for example the kind of account. */\n badge?: JSX.Element;\n /** Send state. Sets a line of fixed height below the message: a clock, a check, or \"Not sent\" with \"Retry\". */\n status?: MessageRowStatus;\n /** Text shown in that line instead of the check once someone has read the message, for example \"Read by Nora\". */\n receipt?: string;\n /** Called by \"Retry\" while `status` is `\"failed\"`. */\n onRetry?: () => void;\n /** Shown as a toolbar over the message while it is hovered or focused. It never moves the layout. */\n actions?: readonly MessageRowAction[];\n /** The message this one answers, shown above it. */\n quote?: MessageRowQuote;\n /** Marks the message as forwarded from somewhere else. */\n forwarded?: boolean;\n /** Marks the message as edited after it was sent. */\n edited?: boolean;\n /** Shows \"This message was deleted\" instead of the text, quote, attachments, previews, and reactions. */\n deleted?: boolean;\n /** Images and videos in a grid with areas reserved from their stored size, then files as chips. */\n attachments?: readonly MessageRowAttachment[];\n /** A preview of a link in the text, supplied with its final height. */\n linkPreview?: JSX.Element;\n /** A card for an element the message refers to, such as a task or a document, supplied with its final height. */\n card?: JSX.Element;\n /**\n * Reactions in a bar of fixed height. The bar shows whenever this is set, even to an empty list, so chips that come\n * and go never change the row. Only setting it where it was unset adds a line, so pass it on own messages and on\n * messages that have or had reactions, and leave it out on others' messages that never had one.\n */\n reactions?: readonly MessageRowReaction[];\n /** Called with a reaction's `key` when the reader presses its chip. Without it, the chips are not controls. */\n onToggleReaction?: (key: string) => void;\n /** Called by \"Add reaction\" in the reaction bar, with the button to anchor a picker to. */\n onAddReaction?: (anchor: HTMLElement) => void;\n /** A bar of fixed height that opens the replies to this message. */\n thread?: MessageRowThread;\n /** The message is still being written, by a person or an automated author alike: a status line with \"Stop\". */\n progress?: MessageRowProgress;\n class?: string;\n};\n\nexport type MessageSystemRowProps = {\n /** What happened, for example \"Nora added Tobias\". */\n children: JSX.Element;\n /** Visible time, formatted by the caller. */\n time?: string;\n dateTime?: string | Date;\n /** Icon class shown before the text. */\n icon?: string;\n class?: string;\n};\n\nexport type MessageGroupEntry = {\n /** Stable identity of the author. */\n author: string;\n at: Date | number | string;\n /** System rows never belong to a group. */\n system?: boolean;\n};\n\nconst timestamp = (value: Date | number | string) => (value instanceof Date ? value.getTime() : new Date(value).getTime());\n\n/**\n * Whether a message starts a new group: there is no previous message, either is a system row, the author changes, or\n * more than five minutes passed. Also start a group where you show a separator such as a new day.\n */\nexport const startsMessageGroup = (entry: MessageGroupEntry, previous?: MessageGroupEntry | null): boolean => {\n if (!previous || entry.system || previous.system || entry.author !== previous.author) return true;\n const gap = timestamp(entry.at) - timestamp(previous.at);\n return !(gap >= 0 && gap <= GROUP_WINDOW_MS);\n};\n\n/** Text that wraps: every `LINE_CHARS` visible characters of a line take at least one line. */\nconst wrappedLines = (text: string): number =>\n text.split(\"\\n\").reduce((lines, line) => lines + Math.ceil(line.trim().length / LINE_CHARS), 0);\n\n/** What inline tokens show: a link its label, never its destination. */\nconst inlineText = (tokens: readonly Token[]): string => {\n let text = \"\";\n for (const token of tokens) {\n if (token.type === \"br\") text += \"\\n\";\n else if (\"tokens\" in token && token.tokens) text += inlineText(token.tokens);\n else if (\"text\" in token) text += token.text;\n }\n return text;\n};\n\n/**\n * The fewest lines the rendered tokens take at any width. Code never wraps, so each of its lines is one line, blank\n * ones too, and its bar one more. Link destinations and reference definitions show nothing. Decided from the text\n * alone, so the row has its final height when it mounts.\n */\nconst renderedLines = (tokens: readonly Token[]): number => {\n let lines = 0;\n for (const token of tokens) {\n switch (token.type) {\n case \"code\":\n lines += token.text.split(\"\\n\").length + 1;\n break;\n case \"list\":\n for (const item of token.items) lines += Math.max(1, renderedLines(item.tokens));\n break;\n case \"table\":\n lines += token.rows.length + (token.header.some((cell: Tokens.TableCell) => cell.text.trim()) ? 1 : 0);\n break;\n case \"paragraph\":\n case \"heading\":\n case \"text\":\n lines += wrappedLines(token.tokens ? inlineText(token.tokens) : token.text);\n break;\n case \"hr\":\n lines += 1;\n break;\n case \"space\":\n case \"def\":\n break;\n default:\n if (\"tokens\" in token && token.tokens) lines += renderedLines(token.tokens);\n else if (\"text\" in token) lines += wrappedLines(token.text);\n }\n }\n return lines;\n};\n\n/** Messages link only to absolute URLs; a relative one would lead somewhere else on every page that shows it. */\nconst isAbsoluteUrl = (href: string): boolean => {\n try {\n return new URL(href).protocol !== \"\";\n } catch {\n return false;\n }\n};\n\nconst dateTimeOf = (value: string | Date | undefined): string | undefined => {\n if (value === undefined) return undefined;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isFinite(date.getTime()) ? date.toISOString() : undefined;\n};\n\n/**\n * An attachment URL the row may load or open: absolute with an allowed scheme, or relative to the page. A picture may\n * also be a `blob:` URL or a `data:image/` URL, which an image element shows without running anything.\n */\nconst attachmentUrl = (url: string | undefined, picture = false): string | undefined => {\n if (!url) return undefined;\n if (picture && /^data:image\\//i.test(url)) return url;\n try {\n return (picture ? PICTURE_PROTOCOLS : ATTACHMENT_PROTOCOLS).has(new URL(url, \"https://relative.invalid/\").protocol) ? url : undefined;\n } catch {\n return undefined;\n }\n};\n\n/** The aspect ratio a single image or video reserves, from its stored size. */\nconst mediaRatio = (media: MessageRowMedia): number => {\n const ratio = media.width > 0 && media.height > 0 ? media.width / media.height : 4 / 3;\n return Math.min(MEDIA_RATIO_MAX, Math.max(MEDIA_RATIO_MIN, ratio));\n};\n\n/** The width of a single image or video: its stored width, at most the row's media height tall, never wider than the row. */\nconst mediaWidth = (media: MessageRowMedia): string => {\n const natural = Number.isFinite(media.width) && media.width > 0 ? `${media.width}px, ` : \"\";\n return `min(100%, ${natural}calc(var(--k2b-message-media-height) * ${mediaRatio(media)}))`;\n};\n\n/** Only the `ti-*` glyph of `fileIcons`, which may add colour utilities that `@k2b/ui` does not ship. */\nconst fileIcon = (file: MessageRowFile): string =>\n file.icon ??\n `ti ${fileIcons\n .getFileIcon({ name: file.name, type: \"file\", mimeType: file.mediaType })\n .split(/\\s+/)\n .filter((token) => token.startsWith(\"ti-\"))\n .join(\" \")}`;\n\n/** A link, a button, or neither, depending on what the caller passes. */\nfunction AttachmentTarget(\n props: MessageRowAttachmentTarget & {\n class: string;\n style?: JSX.CSSProperties;\n /** Names a picture; without a link or button around it, the element becomes the image. */\n label?: string;\n children: JSX.Element;\n },\n): JSX.Element {\n return (\n <Show\n when={props.onOpen}\n fallback={\n <Show\n when={attachmentUrl(props.href)}\n fallback={\n <Show\n when={props.label}\n fallback={\n <span class={props.class} style={props.style}>\n {props.children}\n </span>\n }\n >\n {(label) => (\n <span class={props.class} style={props.style} role=\"img\" aria-label={label()}>\n {props.children}\n </span>\n )}\n </Show>\n }\n >\n {(href) => (\n <a class={props.class} style={props.style} href={href()} target=\"_blank\" rel=\"noopener noreferrer\" aria-label={props.label}>\n {props.children}\n </a>\n )}\n </Show>\n }\n >\n {(open) => (\n <button type=\"button\" class={props.class} style={props.style} aria-label={props.label} onClick={() => open()()}>\n {props.children}\n </button>\n )}\n </Show>\n );\n}\n\n/**\n * Renders the safe Markdown of `MarkdownView` with line breaks kept, absolute links only, and a copy control above\n * every code block, and counts the fewest lines it takes. An edited message that does not collapse ends with the marker.\n */\nconst renderMessage = (\n text: string,\n locale: string,\n messages: UiMessages,\n chatMessages: ChatMessages,\n edited: boolean,\n): { html: string; lines: number } => {\n const renderer = createSafeRenderer({ allowImages: false, linkProtocols: LINK_PROTOCOLS, linkTarget: \"_blank\", locale });\n const renderLink = renderer.link.bind(renderer);\n renderer.link = (token: Tokens.Link) => (isAbsoluteUrl(token.href) ? renderLink(token) : renderer.parser.parseInline(token.tokens));\n const renderCode = renderer.code.bind(renderer);\n renderer.code = (token: Tokens.Code) => {\n const language = token.lang?.match(/^\\S{1,24}/)?.[0];\n const block = renderCode(token).replace(/^<pre>/, '<pre tabindex=\"0\">');\n return (\n '<div class=\"k2b-message-row__code\" data-gesture-ignore><div class=\"k2b-message-row__code-bar\">' +\n `<span class=\"k2b-message-row__code-label\">${escapeHtml(language ?? messages.code)}</span>` +\n '<button type=\"button\" class=\"k2b-message-row__copy\">' +\n `<span class=\"k2b-message-row__copy-idle\"><i class=\"ti ti-copy\" aria-hidden=\"true\"></i>${escapeHtml(messages.copy)}</span>` +\n `<span class=\"k2b-message-row__copy-done\"><i class=\"ti ti-check\" aria-hidden=\"true\"></i>${escapeHtml(messages.copied)}</span>` +\n `</button></div>${block}</div>`\n );\n };\n const marked = createSafeMarked(locale).setOptions({ breaks: true, renderer });\n const tokens = marked.lexer(text);\n const html = marked.parser(tokens);\n const lines = renderedLines(tokens);\n // A collapsed message would hide the end of its text, so its marker sits next to \"Show more\" instead.\n if (!edited || lines > COLLAPSE_LINES) return { html, lines };\n // The marker ends the last paragraph, so it takes no line of its own there.\n const marker = `<span class=\"k2b-message-row__edited\">${escapeHtml(chatMessages.messageEdited)}</span>`;\n const end = html.trimEnd();\n return { html: end.endsWith(\"</p>\") ? `${end.slice(0, -4)} ${marker}</p>` : `${html}<p>${marker}</p>`, lines };\n};\n\n/**\n * One message in a conversation with many people: own messages on the right, others on the left with avatar, name,\n * and time at the start of a group. Every part has its final height when the row mounts, so a virtualized list such\n * as `VirtualFeed` keeps its positions.\n */\nexport function MessageRow(props: MessageRowProps): JSX.Element {\n const messages = useUiMessages();\n const chatMessages = useChatMessages();\n const locale = useLocale();\n const textId = `k2b-message-${createUniqueId()}`;\n const [expanded, setExpanded] = createSignal(false);\n const rendered = createMemo(() => renderMessage(props.text, locale(), messages(), chatMessages(), Boolean(props.edited)));\n const collapsible = () => rendered().lines > COLLAPSE_LINES;\n const collapsed = () => collapsible() && !expanded();\n const groupStart = () => props.groupStart ?? true;\n const hasLine = () => props.progress !== undefined || props.status !== undefined || props.receipt !== undefined;\n const reactions = () => (props.deleted ? undefined : props.reactions);\n // Chips follow their keys, so a chip keeps its element, and focus, when the caller passes new objects for it.\n const reactionKeys = createMemo(() => reactions()?.map((reaction) => reaction.key) ?? []);\n const reactionByKey = createMemo(() => new Map(reactions()?.map((reaction) => [reaction.key, reaction])));\n const hasFooter = () => hasLine() || reactions() !== undefined;\n const writing = () => props.progress !== undefined && !props.deleted && props.text.trim() === \"\";\n const hasBubble = () => props.deleted || writing() || props.text.trim() !== \"\";\n const content = () => !props.deleted;\n const media = createMemo(() =>\n content() ? (props.attachments ?? []).filter((attachment): attachment is MessageRowMedia => attachment.kind !== \"file\") : [],\n );\n const files = createMemo(() =>\n content() ? (props.attachments ?? []).filter((attachment): attachment is MessageRowFile => attachment.kind === \"file\") : [],\n );\n const shownMedia = () => media().slice(0, MEDIA_SHOWN);\n const hiddenMedia = () => media().length - shownMedia().length;\n let text: HTMLDivElement | undefined;\n let copiedTimer: ReturnType<typeof setTimeout> | undefined;\n\n onCleanup(() => clearTimeout(copiedTimer));\n\n const copyCode = (event: MouseEvent) => {\n const button = (event.target as Element | null)?.closest?.<HTMLButtonElement>(\".k2b-message-row__copy\");\n if (!button || !text?.contains(button)) return;\n const code = button.closest(\".k2b-message-row__code\")?.querySelector(\"pre\")?.textContent ?? \"\";\n copyText(code).then(\n () => {\n for (const other of text?.querySelectorAll<HTMLElement>(\".k2b-message-row__copy[data-copied]\") ?? []) delete other.dataset.copied;\n button.dataset.copied = \"\";\n announce(messages().copied);\n clearTimeout(copiedTimer);\n copiedTimer = setTimeout(() => delete button.dataset.copied, COPIED_MS);\n },\n () => {},\n );\n };\n\n // A keyboard user who reaches a link or code block in the hidden or faded part of a collapsed message gets the whole\n // message. The collapsed text clips instead of scrolling, so the browser cannot scroll it to the target instead.\n const revealFocus = (event: FocusEvent) => {\n if (!text || !collapsed() || !(event.target instanceof Element)) return;\n const fade = text.getBoundingClientRect().bottom - FADE_LINES * Number.parseFloat(getComputedStyle(text).lineHeight);\n if (event.target.getBoundingClientRect().bottom > fade) setExpanded(true);\n };\n\n const header = () => (\n <>\n <span class=\"k2b-message-row__name\">{props.author.name}</span>\n <Show when={props.badge}>\n <span class=\"k2b-message-row__badge\">{props.badge}</span>\n </Show>\n <time class=\"k2b-message-row__time\" datetime={dateTimeOf(props.dateTime)}>\n {props.time}\n </time>\n </>\n );\n\n const quote = (value: MessageRowQuote) => (\n <>\n <i class=\"ti ti-arrow-back-up\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__quote-text\">\n <span class=\"k2b-sr-only\">{chatMessages().messageReplyTo} </span>\n <span class=\"k2b-message-row__quote-author\">{value.author}</span> {value.text}\n </span>\n </>\n );\n\n /** The picture's description, then that it is a video and how long, then how many more the grid hides. */\n const mediaLabel = (item: MessageRowMedia, more: number) =>\n [\n item.alt,\n item.kind === \"video\" ? [chatMessages().messageVideo, item.duration].filter(Boolean).join(\" \") : \"\",\n more > 0 ? chatMessages().messageMoreAttachments({ count: more }) : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n\n /** A toggle button, or with no `onToggleReaction` a labelled image that also says whether the reader reacted. */\n const reactionChip = (key: string, reaction: Accessor<MessageRowReaction>) => {\n const label = (own: boolean) =>\n chatMessages().messageReaction({ emoji: reaction().emoji, count: reaction().count, names: reaction().label, own });\n return (\n <Show\n when={props.onToggleReaction}\n fallback={\n <span\n class=\"k2b-message-row__reaction\"\n role=\"img\"\n aria-label={label(Boolean(reaction().own))}\n title={reaction().label}\n data-own={reaction().own ? \"\" : undefined}\n >\n <span aria-hidden=\"true\">{reaction().emoji}</span>\n <span aria-hidden=\"true\">{reaction().count}</span>\n </span>\n }\n >\n {(toggle) => (\n <button\n type=\"button\"\n class=\"k2b-message-row__reaction\"\n aria-pressed={reaction().own ? \"true\" : \"false\"}\n aria-label={label(false)}\n title={reaction().label}\n data-own={reaction().own ? \"\" : undefined}\n onClick={() => toggle()(key)}\n >\n <span aria-hidden=\"true\">{reaction().emoji}</span>\n <span aria-hidden=\"true\">{reaction().count}</span>\n </button>\n )}\n </Show>\n );\n };\n\n const mediaItem = (item: MessageRowMedia, index: () => number) => {\n const more = () => (index() === shownMedia().length - 1 ? hiddenMedia() : 0);\n return (\n <AttachmentTarget\n class=\"k2b-message-row__media-item\"\n style={media().length === 1 ? { \"aspect-ratio\": String(mediaRatio(item)) } : undefined}\n label={mediaLabel(item, more())}\n onOpen={item.onOpen}\n href={item.href}\n >\n <img\n src={attachmentUrl(item.src, true)}\n alt=\"\"\n width={item.width > 0 ? item.width : undefined}\n height={item.height > 0 ? item.height : undefined}\n loading=\"lazy\"\n decoding=\"async\"\n />\n <Show when={item.kind === \"video\"}>\n <span class=\"k2b-message-row__media-play\" aria-hidden=\"true\">\n <i class=\"ti ti-player-play\" />\n </span>\n <Show when={item.duration}>\n <span class=\"k2b-message-row__media-duration\" aria-hidden=\"true\">\n {item.duration}\n </span>\n </Show>\n </Show>\n <Show when={more() > 0}>\n <span class=\"k2b-message-row__media-more\" aria-hidden=\"true\">\n +{more()}\n </span>\n </Show>\n </AttachmentTarget>\n );\n };\n\n return (\n <div\n class={props.class ? `k2b-message-row ${props.class}` : \"k2b-message-row\"}\n data-own={props.own ? \"\" : undefined}\n data-group-start={groupStart() ? \"\" : undefined}\n data-status={props.status}\n data-media={media().length > 0 ? \"\" : undefined}\n >\n <Show when={!props.own}>\n <div class=\"k2b-message-row__gutter\">\n <Show when={groupStart()}>\n <span class=\"k2b-message-row__avatar\" aria-hidden=\"true\">\n <Avatar name={props.author.name} src={props.author.avatar} icon={props.author.icon} size=\"sm\" />\n </span>\n </Show>\n </div>\n </Show>\n <div class=\"k2b-message-row__body\">\n <Show\n when={groupStart()}\n fallback={\n <span class=\"k2b-sr-only\">\n {props.author.name}, {props.time}:{\" \"}\n </span>\n }\n >\n <Show\n when={!props.own}\n fallback={\n <div class=\"k2b-message-row__meta\">\n <span class=\"k2b-sr-only\">{props.author.name}, </span>\n <time class=\"k2b-message-row__time\" datetime={dateTimeOf(props.dateTime)}>\n {props.time}\n </time>\n </div>\n }\n >\n <div class=\"k2b-message-row__meta\">{header()}</div>\n </Show>\n </Show>\n <Show when={content() && props.forwarded}>\n <div class=\"k2b-message-row__marker\">\n <i class=\"ti ti-arrow-forward-up\" aria-hidden=\"true\" />\n <span>{chatMessages().messageForwarded}</span>\n </div>\n </Show>\n <Show when={content() && props.quote}>\n {(value) => (\n <Show when={value().onSelect} fallback={<div class=\"k2b-message-row__quote\">{quote(value())}</div>}>\n {(select) => (\n <button type=\"button\" class=\"k2b-message-row__quote\" onClick={() => select()()}>\n {quote(value())}\n </button>\n )}\n </Show>\n )}\n </Show>\n <Show when={hasBubble()}>\n <div\n class=\"k2b-message-row__bubble\"\n data-deleted={props.deleted ? \"\" : undefined}\n aria-busy={props.progress && !props.deleted ? \"true\" : undefined}\n >\n <Show\n when={!props.deleted}\n fallback={\n <span class=\"k2b-message-row__deleted\">\n <i class=\"ti ti-message-off\" aria-hidden=\"true\" />\n {chatMessages().messageDeleted}\n </span>\n }\n >\n <Show\n when={!writing()}\n fallback={\n <span class=\"k2b-message-row__writing\">\n <span class=\"k2b-chat-progress-dots\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n </span>\n }\n >\n {/* biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: the native copy buttons inside the rendered Markdown are the targets; their clicks, including from the keyboard, bubble here. */}\n <div\n ref={text}\n id={textId}\n class=\"k2b-content-markdown k2b-message-row__text\"\n data-heading-scale=\"compact\"\n data-collapsed={collapsed() ? \"\" : undefined}\n onClick={copyCode}\n onFocusIn={revealFocus}\n innerHTML={rendered().html}\n />\n <Show when={collapsible()}>\n <div class=\"k2b-message-row__more-line\">\n <Button\n variant=\"text\"\n size=\"xs\"\n class=\"k2b-message-row__more\"\n aria-expanded={expanded() ? \"true\" : \"false\"}\n aria-controls={textId}\n onClick={() => setExpanded((value) => !value)}\n >\n {expanded() ? chatMessages().messageShowLess : chatMessages().messageShowMore}\n </Button>\n <Show when={props.edited}>\n <span class=\"k2b-message-row__edited\">{chatMessages().messageEdited}</span>\n </Show>\n </div>\n </Show>\n </Show>\n </Show>\n </div>\n </Show>\n {/* Without a bubble to end, the edit marker takes the bubble's place. */}\n <Show when={content() && props.edited && !hasBubble()}>\n <div class=\"k2b-message-row__marker\">\n <i class=\"ti ti-pencil\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__edited\">{chatMessages().messageEdited}</span>\n </div>\n </Show>\n <Show when={media().length > 0}>\n <div\n class=\"k2b-message-row__media\"\n role=\"group\"\n aria-label={chatMessages().attachments}\n data-count={Math.min(media().length, MEDIA_SHOWN)}\n style={media().length === 1 ? { width: mediaWidth(media()[0]!) } : undefined}\n >\n <For each={shownMedia()}>{(item, index) => mediaItem(item, index)}</For>\n </div>\n </Show>\n <Show when={files().length > 0}>\n <div class=\"k2b-message-row__files\">\n <For each={files()}>\n {(file) => (\n <AttachmentTarget class=\"k2b-message-row__file\" onOpen={file.onOpen} href={file.href}>\n <span class=\"k2b-message-row__file-icon\" aria-hidden=\"true\">\n <i class={fileIcon(file)} />\n </span>\n <span class=\"k2b-message-row__file-copy\">\n <span class=\"k2b-message-row__file-name\">{file.name}</span>\n <Show when={file.detail}>\n <span class=\"k2b-message-row__file-detail\">{file.detail}</span>\n </Show>\n </span>\n </AttachmentTarget>\n )}\n </For>\n </div>\n </Show>\n <Show when={content() && props.linkPreview}>\n <div class=\"k2b-message-row__slot\" data-gesture-ignore>\n {props.linkPreview}\n </div>\n </Show>\n <Show when={content() && props.card}>\n <div class=\"k2b-message-row__slot\" data-gesture-ignore>\n {props.card}\n </div>\n </Show>\n <Show when={props.thread}>\n {(thread) => (\n <button type=\"button\" class=\"k2b-message-row__thread\" onClick={() => thread().onOpen()}>\n <Show when={(thread().participants?.length ?? 0) > 0}>\n <span class=\"k2b-message-row__thread-people\" aria-hidden=\"true\">\n <For each={thread().participants?.slice(0, 3)}>\n {(person) => <Avatar name={person.name} src={person.avatar} icon={person.icon} size=\"xs\" />}\n </For>\n </span>\n </Show>\n <span class=\"k2b-message-row__thread-count\">{chatMessages().messageReplies({ count: thread().count })}</span>\n <Show when={thread().lastReply}>\n {(time) => (\n <time class=\"k2b-message-row__thread-time\" datetime={dateTimeOf(thread().lastReplyDateTime)}>\n {chatMessages().messageLastReply({ time: time() })}\n </time>\n )}\n </Show>\n </button>\n )}\n </Show>\n <Show when={hasFooter()}>\n <div class=\"k2b-message-row__footer\">\n <Show when={reactions()}>\n {(list) => (\n <div\n class=\"k2b-message-row__reactions\"\n role=\"group\"\n aria-label={chatMessages().messageReactions}\n data-empty={list().length === 0 ? \"\" : undefined}\n >\n <Show when={list().length > 0}>\n {/* Chips that do not fit scroll sideways behind a fade. Read-only chips are no tab stops, so the list\n is one: a keyboard can scroll it. */}\n <ScrollArea\n orientation=\"horizontal\"\n class=\"k2b-message-row__reaction-list\"\n tabindex={props.onToggleReaction ? undefined : 0}\n >\n <For each={reactionKeys()}>\n {(key) => <Show when={reactionByKey().get(key)}>{(reaction) => reactionChip(key, reaction)}</Show>}\n </For>\n </ScrollArea>\n </Show>\n <Show when={props.onAddReaction}>\n {(add) => (\n <IconButton\n label={chatMessages().messageAddReaction}\n size=\"xs\"\n class=\"k2b-message-row__react\"\n onClick={(event) => add()(event.currentTarget)}\n >\n <i class=\"ti ti-mood-plus\" aria-hidden=\"true\" />\n </IconButton>\n )}\n </Show>\n </div>\n )}\n </Show>\n <Show when={hasLine()}>\n <div class=\"k2b-message-row__line\">\n <Show\n when={props.progress}\n fallback={\n <>\n <Show when={props.status === \"pending\"}>\n <i class=\"ti ti-clock\" aria-hidden=\"true\" />\n <span>{chatMessages().sending}</span>\n </Show>\n <Show when={props.status === \"failed\"}>\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n <span>{chatMessages().messageNotSent}</span>\n <Show when={props.onRetry}>\n {(retry) => (\n <Button variant=\"text\" size=\"xs\" onClick={() => retry()()}>\n {chatMessages().messageRetry}\n </Button>\n )}\n </Show>\n </Show>\n <Show when={props.status !== \"pending\" && props.status !== \"failed\"}>\n <Show\n when={props.receipt}\n fallback={\n <Show when={props.status === \"sent\"}>\n <i class=\"ti ti-check\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{chatMessages().messageSent}</span>\n </Show>\n }\n >\n {(receipt) => (\n <>\n <i class=\"ti ti-checks\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__receipt\">{receipt()}</span>\n </>\n )}\n </Show>\n </Show>\n </>\n }\n >\n {(progress) => (\n <>\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n <span class=\"k2b-message-row__line-text\">{progress().status}</span>\n <Show when={progress().onStop}>\n {(stop) => (\n <Button variant=\"text\" size=\"xs\" onClick={() => stop()()}>\n {chatMessages().messageStop}\n </Button>\n )}\n </Show>\n </>\n )}\n </Show>\n </div>\n </Show>\n </div>\n </Show>\n </div>\n <Show when={(props.actions?.length ?? 0) > 0}>\n <div class=\"k2b-message-row__actions\" role=\"group\" aria-label={chatMessages().messageActions}>\n <For each={props.actions}>\n {(action) => (\n <IconButton label={action.label} size=\"sm\" disabled={action.disabled} onClick={() => action.onSelect()}>\n <i class={action.icon} aria-hidden=\"true\" />\n </IconButton>\n )}\n </For>\n </div>\n </Show>\n </div>\n );\n}\n\n/** A quiet, centered line for something that happened in the conversation, such as a person joining. */\nexport function MessageSystemRow(props: MessageSystemRowProps): JSX.Element {\n return (\n <div class={props.class ? `k2b-message-system-row ${props.class}` : \"k2b-message-system-row\"}>\n <Show when={props.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span>{props.children}</span>\n <Show when={props.time}>\n <time datetime={dateTimeOf(props.dateTime)}>{props.time}</time>\n </Show>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -11,7 +11,7 @@ var _tmpl$ = ["<a", " class=\"", "\"", ">", "</a>"],
|
|
|
11
11
|
_tmpl$6 = ["<span class=\"k2b-pagination__page is-current\" aria-current=\"page\">", "</span>"];
|
|
12
12
|
import { Link } from "@k2b/ssr/nav";
|
|
13
13
|
import { createMemo, For, Show } from "solid-js";
|
|
14
|
-
import {
|
|
14
|
+
import { usePaginationMessages } from "./pagination-messages";
|
|
15
15
|
const PaginationLink = props => props.onNavigate ? _$createComponent(Link, {
|
|
16
16
|
get href() {
|
|
17
17
|
return props.href;
|
|
@@ -36,7 +36,7 @@ const PaginationLink = props => props.onNavigate ? _$createComponent(Link, {
|
|
|
36
36
|
|
|
37
37
|
/** Link-based pagination with directional navigation and compact mobile disclosure. */
|
|
38
38
|
export const Pagination = props => {
|
|
39
|
-
const
|
|
39
|
+
const paginationMessages = usePaginationMessages();
|
|
40
40
|
const totalPages = createMemo(() => Math.max(1, Math.floor(Number.isFinite(props.totalPages) ? props.totalPages : 1)));
|
|
41
41
|
const currentPage = createMemo(() => Math.min(totalPages(), Math.max(1, Math.floor(Number.isFinite(props.currentPage) ? props.currentPage : 1))));
|
|
42
42
|
const href = page => `${props.baseUrl}${page}`;
|
|
@@ -46,7 +46,7 @@ export const Pagination = props => {
|
|
|
46
46
|
return totalPages() > 1;
|
|
47
47
|
},
|
|
48
48
|
get children() {
|
|
49
|
-
return _$ssr(_tmpl$4, _$ssrAttribute("aria-label", _$escape(
|
|
49
|
+
return _$ssr(_tmpl$4, _$ssrAttribute("aria-label", _$escape(paginationMessages().pagination, true), false), _$escape(paginationMessages().pageOf({
|
|
50
50
|
page: currentPage(),
|
|
51
51
|
total: totalPages()
|
|
52
52
|
})), _$escape(_$createComponent(Show, {
|
|
@@ -60,7 +60,7 @@ export const Pagination = props => {
|
|
|
60
60
|
},
|
|
61
61
|
rel: "prev",
|
|
62
62
|
get label() {
|
|
63
|
-
return
|
|
63
|
+
return paginationMessages().previousPage;
|
|
64
64
|
},
|
|
65
65
|
get onNavigate() {
|
|
66
66
|
return props.onNavigate;
|
|
@@ -96,7 +96,7 @@ export const Pagination = props => {
|
|
|
96
96
|
return href(page);
|
|
97
97
|
},
|
|
98
98
|
get label() {
|
|
99
|
-
return
|
|
99
|
+
return paginationMessages().goToPage({
|
|
100
100
|
page
|
|
101
101
|
});
|
|
102
102
|
},
|
|
@@ -125,7 +125,7 @@ export const Pagination = props => {
|
|
|
125
125
|
},
|
|
126
126
|
rel: "next",
|
|
127
127
|
get label() {
|
|
128
|
-
return
|
|
128
|
+
return paginationMessages().nextPage;
|
|
129
129
|
},
|
|
130
130
|
get onNavigate() {
|
|
131
131
|
return props.onNavigate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/Pagination.tsx"],"sourcesContent":["import { Link, type LinkNavigateEvent } from \"@k2b/ssr/nav\";\nimport { createMemo, For, type JSX, Show } from \"solid-js\";\nimport {
|
|
1
|
+
{"version":3,"names":[],"sources":["content/Pagination.tsx"],"sourcesContent":["import { Link, type LinkNavigateEvent } from \"@k2b/ssr/nav\";\nimport { createMemo, For, type JSX, Show } from \"solid-js\";\nimport { usePaginationMessages } from \"./pagination-messages\";\n\nexport type PaginationProps = {\n currentPage: number;\n totalPages: number;\n baseUrl: string;\n onNavigate?: (event: LinkNavigateEvent) => void | Promise<void>;\n};\n\ntype PaginationLinkProps = {\n href: string;\n label: string;\n rel?: \"prev\" | \"next\";\n class?: string;\n onNavigate?: PaginationProps[\"onNavigate\"];\n children: JSX.Element;\n};\n\nconst PaginationLink = (props: PaginationLinkProps) =>\n props.onNavigate ? (\n <Link\n href={props.href}\n rel={props.rel}\n scroll=\"top\"\n onNavigate={props.onNavigate}\n class={`k2b-pagination__page ${props.class ?? \"\"}`}\n aria-label={props.label}\n >\n {props.children}\n </Link>\n ) : (\n <a href={props.href} rel={props.rel} class={`k2b-pagination__page ${props.class ?? \"\"}`} aria-label={props.label}>\n {props.children}\n </a>\n );\n\n/** Link-based pagination with directional navigation and compact mobile disclosure. */\nexport const Pagination = (props: PaginationProps): JSX.Element => {\n const paginationMessages = usePaginationMessages();\n const totalPages = createMemo(() => Math.max(1, Math.floor(Number.isFinite(props.totalPages) ? props.totalPages : 1)));\n const currentPage = createMemo(() =>\n Math.min(totalPages(), Math.max(1, Math.floor(Number.isFinite(props.currentPage) ? props.currentPage : 1))),\n );\n const href = (page: number) => `${props.baseUrl}${page}`;\n const visiblePages = createMemo(() =>\n [...new Set([1, currentPage() - 1, currentPage(), currentPage() + 1, totalPages()])]\n .filter((page) => page >= 1 && page <= totalPages())\n .sort((left, right) => left - right),\n );\n\n return (\n <Show when={totalPages() > 1}>\n <nav class=\"k2b-pagination\" aria-label={paginationMessages().pagination}>\n <span class=\"k2b-sr-only\">{paginationMessages().pageOf({ page: currentPage(), total: totalPages() })}</span>\n <div class=\"k2b-pagination__pages\">\n <Show when={currentPage() > 1}>\n <PaginationLink\n href={href(currentPage() - 1)}\n rel=\"prev\"\n label={paginationMessages().previousPage}\n onNavigate={props.onNavigate}\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </PaginationLink>\n </Show>\n\n <For each={visiblePages()}>\n {(page, index) => {\n const previousPage = () => visiblePages()[index() - 1];\n const hasGap = () => previousPage() !== undefined && page - previousPage()! > 1;\n const isCurrent = () => page === currentPage();\n const mobileVisible = () => page === 1 || page === totalPages() || isCurrent();\n\n return (\n <>\n <Show when={hasGap()}>\n <span class=\"k2b-pagination__ellipsis\" aria-hidden=\"true\">\n …\n </span>\n </Show>\n <Show\n when={isCurrent()}\n fallback={\n <PaginationLink\n href={href(page)}\n label={paginationMessages().goToPage({ page })}\n class={mobileVisible() ? \"\" : \"k2b-pagination__page--wide-only\"}\n onNavigate={props.onNavigate}\n >\n {page}\n </PaginationLink>\n }\n >\n <span class=\"k2b-pagination__page is-current\" aria-current=\"page\">\n {page}\n </span>\n </Show>\n </>\n );\n }}\n </For>\n\n <Show when={currentPage() < totalPages()}>\n <PaginationLink href={href(currentPage() + 1)} rel=\"next\" label={paginationMessages().nextPage} onNavigate={props.onNavigate}>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n </PaginationLink>\n </Show>\n </div>\n </nav>\n </Show>\n );\n};\n"],"mappings":"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","ignoreList":[]}
|