@k2b/ui 0.20.0 → 0.22.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/Button.js +20 -31
- package/dist/browser/actions/Button.js.map +1 -1
- package/dist/browser/actions/ContextMenu.js +10 -4
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/CopyButton.js +10 -8
- package/dist/browser/actions/CopyButton.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/GestureMenu.js +4 -0
- package/dist/browser/actions/GestureMenu.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 +1960 -575
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/Chart.js +15 -8
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/ChartExplorer.js +20 -12
- 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 +4 -2
- 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 +68 -59
- 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-messages.js +121 -0
- package/dist/browser/content/calendar-messages.js.map +1 -0
- package/dist/browser/content/calendar-month-layout.js +108 -0
- package/dist/browser/content/calendar-month-layout.js.map +1 -0
- package/dist/browser/content/calendar-pointer.js +4 -3
- package/dist/browser/content/calendar-pointer.js.map +1 -1
- package/dist/browser/content/chart-messages.js +136 -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 -1
- package/dist/browser/inputs/Combobox.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +46 -10
- package/dist/browser/inputs/DatePicker.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/date-picker.js +24 -0
- package/dist/browser/inputs/date-picker.js.map +1 -1
- 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 +12 -1155
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +561 -418
- 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 +370 -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 +743 -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/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/Button.js +21 -32
- package/dist/ssr/actions/Button.js.map +1 -1
- package/dist/ssr/actions/ContextMenu.js +7 -3
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/CopyButton.js +9 -7
- package/dist/ssr/actions/CopyButton.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/GestureMenu.js +4 -0
- package/dist/ssr/actions/GestureMenu.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 +1232 -115
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/Chart.js +12 -5
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/ChartExplorer.js +10 -8
- 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 +4 -2
- 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 +10 -4
- 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-messages.js +121 -0
- package/dist/ssr/content/calendar-messages.js.map +1 -0
- package/dist/ssr/content/calendar-month-layout.js +108 -0
- package/dist/ssr/content/calendar-month-layout.js.map +1 -0
- package/dist/ssr/content/calendar-pointer.js +4 -3
- package/dist/ssr/content/calendar-pointer.js.map +1 -1
- package/dist/ssr/content/chart-messages.js +136 -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/DatePicker.js +34 -4
- package/dist/ssr/inputs/DatePicker.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/date-picker.js +24 -0
- package/dist/ssr/inputs/date-picker.js.map +1 -1
- 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 +12 -1155
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +203 -96
- 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 +253 -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 +743 -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/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/GestureMenu.d.ts +2 -0
- 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 +32 -0
- package/dist/types/content/DataTable.d.ts +2 -0
- package/dist/types/content/FileView.d.ts +0 -10
- package/dist/types/content/calendar-messages.d.ts +60 -0
- package/dist/types/content/calendar-month-layout.d.ts +52 -0
- package/dist/types/content/chart-messages.d.ts +32 -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 +1 -1
- 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/date-picker.d.ts +7 -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 +6 -544
- package/dist/types/layout/AppWorkspace.d.ts +19 -4
- package/dist/types/layout/PageTitle.d.ts +64 -0
- package/dist/types/layout/app-workspace-controller.d.ts +4 -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/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
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { suppressTextSelection } from "../internal/text-selection";
|
|
2
|
+
import { APP_WORKSPACE_DETAIL_DEFAULT, APP_WORKSPACE_DETAIL_MAX, APP_WORKSPACE_DETAIL_MIN, APP_WORKSPACE_DRAWER_MAX, APP_WORKSPACE_DRAWER_MIN, APP_WORKSPACE_MAIN_MIN, APP_WORKSPACE_PANE_MAX, APP_WORKSPACE_PANE_MIN, APP_WORKSPACE_SIDEBAR_COLLAPSED, APP_WORKSPACE_SIDEBAR_MAX, APP_WORKSPACE_SIDEBAR_MIN, appWorkspacePanelVariable, appWorkspaceResizeLimits, fitAppWorkspacePaneSizes, normalizeAppWorkspaceLayoutState, resolveAppWorkspaceSidebarWidth, safeAppWorkspacePanelId, shouldCollapseAppWorkspaceSidebar } from "./app-workspace-state";
|
|
2
3
|
import { installScrollFades } from "./scroll-fade";
|
|
3
4
|
const HANDLE_SELECTOR = "[data-app-workspace-resize]";
|
|
4
5
|
const ROOT_SELECTOR = "[data-k2b-app-workspace]";
|
|
5
6
|
const LAYOUT_REGION_SELECTOR = [ROOT_SELECTOR, ".k2b-app-workspace__sidebar", ".k2b-app-workspace__main-pane", ".k2b-app-workspace__detail", ".k2b-app-workspace__drawer", HANDLE_SELECTOR].join(",");
|
|
7
|
+
const TOGGLE_SELECTOR = "[data-app-workspace-sidebar-toggle]";
|
|
8
|
+
/** The width range in which the sidebar is an overlay; it matches the compact media query in the stylesheet. */
|
|
9
|
+
const COMPACT_QUERY = "(min-width: 48rem) and (max-width: 63.999rem)";
|
|
10
|
+
const FOCUSABLE_SELECTOR = ["a[href]", "button:not([disabled])", "input:not([disabled]):not([type='hidden'])", "select:not([disabled])", "textarea:not([disabled])", "[tabindex]:not([tabindex='-1'])"].join(",");
|
|
11
|
+
/** Text entry, menus, dialogs, and open popups keep their own keys. */
|
|
12
|
+
const KEY_OWNER_SELECTOR = "input, textarea, select, [contenteditable]:not([contenteditable='false']), [role='textbox'], [role='combobox'], [role='searchbox'], [role='spinbutton'], [role='menu'], [role='listbox'], [role='dialog'], dialog, [aria-haspopup]:not([aria-haspopup='false'])[aria-expanded='true']";
|
|
6
13
|
const LABEL_SELECTOR = ".k2b-app-workspace__sidebar-item-label[data-marquee='true']";
|
|
7
14
|
const LABEL_TEXT_SELECTOR = ".k2b-app-workspace__sidebar-item-label-text";
|
|
8
15
|
const ITEM_SELECTOR = ".k2b-app-workspace__sidebar-item";
|
|
@@ -26,6 +33,10 @@ const sidebarHideable = root => sidebarElement(root)?.dataset.workspaceHideable
|
|
|
26
33
|
* stays application state, so the controller only requests the change.
|
|
27
34
|
*/
|
|
28
35
|
export const APP_WORKSPACE_SIDEBAR_HIDE_EVENT = "k2b-app-workspace-sidebar-hide";
|
|
36
|
+
/** Asks the owning `AppWorkspace.Detail` to close; its `onClose` decides. */
|
|
37
|
+
export const APP_WORKSPACE_DETAIL_CLOSE_EVENT = "k2b-app-workspace-detail-close";
|
|
38
|
+
/** Asks the owning `AppWorkspace.Detail` for the previous or next item, as `detail.direction` of `-1` or `1`. */
|
|
39
|
+
export const APP_WORKSPACE_DETAIL_STEP_EVENT = "k2b-app-workspace-detail-step";
|
|
29
40
|
const previewSidebarHidden = (root, hidden) => {
|
|
30
41
|
const sidebar = sidebarElement(root);
|
|
31
42
|
if (!sidebar) return;
|
|
@@ -53,15 +64,16 @@ const sizeLimits = (root, handle, kind) => {
|
|
|
53
64
|
const controlled = controlledPanel(root, handle);
|
|
54
65
|
const main = kind === "pane" ? handle.closest(".k2b-app-workspace__main") : mainElement(root);
|
|
55
66
|
const panes = main ? Array.from(main.querySelectorAll(".k2b-app-workspace__main-pane")).filter(pane => pane.closest(".k2b-app-workspace__main") === main && !pane.classList.contains("is-primary") && isVisible(pane)) : [];
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
// A detail shares the content area with the main region, as the stylesheet
|
|
68
|
+
// fits it. The area already leaves out a sidebar in its own column; as the
|
|
69
|
+
// compact overlay or stacked above the content, the sidebar takes none of it.
|
|
70
|
+
const content = kind === "detail" ? controlled?.closest(".k2b-app-workspace__content") : null;
|
|
59
71
|
const defaultMin = kind === "sidebar" ? APP_WORKSPACE_SIDEBAR_MIN : kind === "pane" ? APP_WORKSPACE_PANE_MIN : kind === "detail" ? APP_WORKSPACE_DETAIL_MIN : APP_WORKSPACE_DRAWER_MIN;
|
|
60
72
|
const defaultMax = kind === "sidebar" ? APP_WORKSPACE_SIDEBAR_MAX : kind === "pane" ? APP_WORKSPACE_PANE_MAX : kind === "detail" ? APP_WORKSPACE_DETAIL_MAX : APP_WORKSPACE_DRAWER_MAX;
|
|
61
73
|
return appWorkspaceResizeLimits({
|
|
62
74
|
kind,
|
|
63
|
-
workspaceSize: kind === "drawer" ? root.getBoundingClientRect().height : kind === "pane" && main ? main.getBoundingClientRect().width : root.getBoundingClientRect().width,
|
|
64
|
-
reservedSize: kind === "
|
|
75
|
+
workspaceSize: kind === "drawer" ? root.getBoundingClientRect().height : kind === "pane" && main ? main.getBoundingClientRect().width : (content ?? root).getBoundingClientRect().width,
|
|
76
|
+
reservedSize: kind === "detail" ? 16 : kind === "pane" ? panes.reduce((total, pane) => total + (pane === controlled ? 0 : elementSize(pane, "pane")), 0) : 0,
|
|
65
77
|
min: numberData(handle, "workspaceMinSize", defaultMin),
|
|
66
78
|
max: numberData(handle, "workspaceMaxSize", defaultMax),
|
|
67
79
|
sidebarCollapsible: kind === "sidebar" && sidebarCollapsible(root)
|
|
@@ -165,8 +177,613 @@ const measureLabel = label => {
|
|
|
165
177
|
label.style.setProperty("--k2b-sidebar-label-overflow", `${overflow}px`);
|
|
166
178
|
if (overflow > 2) label.dataset.overflow = "true";else delete label.dataset.overflow;
|
|
167
179
|
};
|
|
180
|
+
|
|
181
|
+
/** An open overlay remembers the regions it made inert, so it leaves the application's own `inert` alone. */
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The elements Tab stops at, in order. A roving tab index, as in a tree, keeps
|
|
185
|
+
* links and buttons at `tabindex="-1"`; they take focus but are no stops.
|
|
186
|
+
*/
|
|
187
|
+
const tabStopsIn = container => Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter(element => element.tabIndex >= 0 && element.getClientRects().length > 0 && !element.closest("[inert]") && getComputedStyle(element).visibility !== "hidden");
|
|
188
|
+
/** Several controllers can see one click on a nested workspace's button; the innermost one, which sees it first, owns it. */
|
|
189
|
+
const claimedToggleClicks = new WeakSet();
|
|
190
|
+
const claimedDetailGestures = new WeakSet();
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The compact overlay: from 48 to 64 rem the sidebar opens over the work area
|
|
194
|
+
* from the button in the workspace's head. While it is open the rest of
|
|
195
|
+
* the workspace is inert, Tab stays in the sidebar, and Escape, the scrim,
|
|
196
|
+
* choosing an item, hiding the sidebar, or leaving the width range close it
|
|
197
|
+
* again. The state is one attribute on the workspace root, so server-rendered
|
|
198
|
+
* and hydrated workspaces behave the same.
|
|
199
|
+
*/
|
|
200
|
+
const overlayTarget = toggle => {
|
|
201
|
+
const root = workspaceRoot(toggle);
|
|
202
|
+
// The button belongs to its workspace's own sidebar. A sidebar rendered apart
|
|
203
|
+
// from the head, for example in an island, can carry another id than the one
|
|
204
|
+
// the head named, so the button learns the real one here.
|
|
205
|
+
const sidebar = root ? sidebarElement(root) : null;
|
|
206
|
+
if (!root || !sidebar || sidebar.hidden || sidebar.dataset.mobile === "stacked") return null;
|
|
207
|
+
if (sidebar.id) toggle.setAttribute("aria-controls", sidebar.id);
|
|
208
|
+
return {
|
|
209
|
+
root,
|
|
210
|
+
sidebar,
|
|
211
|
+
toggle
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
const overlayRegions = (root, sidebar) => Array.from(root.children).flatMap(child => child instanceof HTMLElement && (child.localName === "solid-island" || child.localName === "solid-client") ? Array.from(child.children) : [child]).filter(child => child instanceof HTMLElement && child !== sidebar && !child.contains(sidebar));
|
|
168
215
|
export const installAppWorkspaceController = (options = {}) => {
|
|
169
216
|
const eventRoot = options.root ?? document;
|
|
217
|
+
// A document has no owner document; an element root listens on its own.
|
|
218
|
+
const ownerDocument = eventRoot.ownerDocument ?? document;
|
|
219
|
+
const ownerWindow = ownerDocument.defaultView ?? window;
|
|
220
|
+
let overlay = null;
|
|
221
|
+
const compact = typeof window.matchMedia === "function" ? window.matchMedia(COMPACT_QUERY) : null;
|
|
222
|
+
// A server-rendered head names the sidebar before the sidebar renders; the button learns its real id now.
|
|
223
|
+
for (const toggle of eventRoot.querySelectorAll(TOGGLE_SELECTOR)) overlayTarget(toggle);
|
|
224
|
+
const openOverlay = target => {
|
|
225
|
+
if (overlay) closeOverlay("none");
|
|
226
|
+
const inerted = overlayRegions(target.root, target.sidebar).filter(region => !region.hasAttribute("inert"));
|
|
227
|
+
overlay = {
|
|
228
|
+
...target,
|
|
229
|
+
inerted
|
|
230
|
+
};
|
|
231
|
+
target.root.dataset.sidebarOverlay = "open";
|
|
232
|
+
target.toggle.setAttribute("aria-expanded", "true");
|
|
233
|
+
inerted.forEach(region => region.setAttribute("inert", ""));
|
|
234
|
+
// Focus starts on the current destination, so the reader knows where they
|
|
235
|
+
// are: on its own tab stop, or on the tree item around it.
|
|
236
|
+
const current = target.sidebar.querySelector("[aria-current='page'], .is-active");
|
|
237
|
+
const stops = tabStopsIn(target.sidebar);
|
|
238
|
+
const first = (current && (stops.find(element => current.contains(element)) ?? stops.findLast(element => element.contains(current)))) ?? stops[0];
|
|
239
|
+
if (first) first.focus();else {
|
|
240
|
+
target.sidebar.tabIndex = -1;
|
|
241
|
+
target.sidebar.focus();
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* `"button"` returns focus to the button. `"kept"` leaves it where it moved,
|
|
246
|
+
* for example into a dialog an item opened, and only rescues focus that the
|
|
247
|
+
* closing sidebar would hide. `"none"` moves nothing, for cleanup.
|
|
248
|
+
*/
|
|
249
|
+
const closeOverlay = focus => {
|
|
250
|
+
const closing = overlay;
|
|
251
|
+
if (!closing) return;
|
|
252
|
+
overlay = null;
|
|
253
|
+
delete closing.root.dataset.sidebarOverlay;
|
|
254
|
+
closing.toggle.setAttribute("aria-expanded", "false");
|
|
255
|
+
closing.inerted.forEach(region => region.removeAttribute("inert"));
|
|
256
|
+
if (focus === "none") return;
|
|
257
|
+
const active = document.activeElement;
|
|
258
|
+
if (focus === "button" || !active || active === document.body || closing.sidebar.contains(active)) closing.toggle.focus();
|
|
259
|
+
};
|
|
260
|
+
const onClick = event => {
|
|
261
|
+
const target = eventElement(event);
|
|
262
|
+
const toggle = target?.closest(TOGGLE_SELECTOR);
|
|
263
|
+
if (toggle) {
|
|
264
|
+
const next = overlayTarget(toggle);
|
|
265
|
+
if (!next || claimedToggleClicks.has(event)) return;
|
|
266
|
+
claimedToggleClicks.add(event);
|
|
267
|
+
if (overlay?.sidebar === next.sidebar) closeOverlay("button");else if (compact?.matches) openOverlay(next);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (!overlay || !target) return;
|
|
271
|
+
// The scrim is the workspace root's own pseudo-element.
|
|
272
|
+
if (target === overlay.root) {
|
|
273
|
+
closeOverlay("button");
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
// Choosing a destination closes the overlay: a link, or the button of a
|
|
277
|
+
// row. A tree folder that only expands, a control that opens a popup or
|
|
278
|
+
// expands something, such as a row's preview, and an item's own actions
|
|
279
|
+
// keep it open.
|
|
280
|
+
const control = target.closest("a[href], button");
|
|
281
|
+
if (!control || !overlay.sidebar.contains(control)) return;
|
|
282
|
+
if (target.closest("[data-k2b-nav-tree-toggle]") || control.closest("[data-k2b-nav-tree-disclosure], .k2b-app-workspace__sidebar-item-action, .k2b-app-workspace__sidebar-item-actions") || control.matches("[aria-haspopup], [aria-expanded]")) return;
|
|
283
|
+
if (control.matches("a[href]") || control.closest(ITEM_SELECTOR)) closeOverlay("kept");
|
|
284
|
+
};
|
|
285
|
+
const onOverlayKeyDown = event => {
|
|
286
|
+
if (!overlay || event.defaultPrevented) return;
|
|
287
|
+
const target = eventElement(event);
|
|
288
|
+
if (!target) return;
|
|
289
|
+
// Escape also closes it when a click left focus on nothing, so on the body.
|
|
290
|
+
if (event.key === "Escape" && (overlay.sidebar.contains(target) || target === ownerDocument.body)) {
|
|
291
|
+
event.preventDefault();
|
|
292
|
+
closeOverlay("button");
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (event.key !== "Tab" || !overlay.sidebar.contains(target)) return;
|
|
296
|
+
const stops = tabStopsIn(overlay.sidebar);
|
|
297
|
+
const first = stops[0];
|
|
298
|
+
const last = stops.at(-1);
|
|
299
|
+
if (!first || !last) {
|
|
300
|
+
event.preventDefault();
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (event.shiftKey && (document.activeElement === first || document.activeElement === overlay.sidebar)) {
|
|
304
|
+
event.preventDefault();
|
|
305
|
+
last.focus();
|
|
306
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
first.focus();
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
const onCompactChange = () => {
|
|
312
|
+
if (!compact?.matches) closeOverlay("none");
|
|
313
|
+
};
|
|
314
|
+
const phone = typeof window.matchMedia === "function" ? window.matchMedia("(max-width: 47.999rem)") : null;
|
|
315
|
+
const wide = typeof window.matchMedia === "function" ? window.matchMedia("(min-width: 48rem)") : null;
|
|
316
|
+
const touchDrawer = typeof window.matchMedia === "function" ? window.matchMedia(`${COMPACT_QUERY} and (pointer: coarse)`) : null;
|
|
317
|
+
const reducedMotion = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
318
|
+
const detailSelector = ".k2b-app-workspace__detail";
|
|
319
|
+
const grabberSelector = ".k2b-app-workspace__detail-grabber";
|
|
320
|
+
const trailSelector = ".k2b-detail-trail";
|
|
321
|
+
const detailHidden = new WeakMap();
|
|
322
|
+
const remembered = new WeakMap();
|
|
323
|
+
const lastFocus = new WeakMap();
|
|
324
|
+
const trailPadding = new WeakMap();
|
|
325
|
+
const heldTrails = new Set();
|
|
326
|
+
const touchedDetails = new Set();
|
|
327
|
+
// Only a panel blocks scrolling for its touch gestures; a document-wide
|
|
328
|
+
// non-passive listener would make every scroll on the page wait for script.
|
|
329
|
+
const touchMoveAsides = new Set();
|
|
330
|
+
const titleTabIndices = new Set();
|
|
331
|
+
const motionFrames = new Map();
|
|
332
|
+
const motionRoots = new Set();
|
|
333
|
+
const revealFrames = new Map();
|
|
334
|
+
const openDetails = root => rootElements(root, detailSelector).filter(aside => !aside.hidden);
|
|
335
|
+
const closeControl = aside => Array.from(aside.querySelectorAll("[data-workspace-detail-close]")).find(control => control.closest(detailSelector) === aside);
|
|
336
|
+
const closable = aside => aside.hasAttribute("data-workspace-detail-closable") || Boolean(closeControl(aside));
|
|
337
|
+
const requestClose = aside => {
|
|
338
|
+
if (aside.hasAttribute("data-workspace-detail-closable")) aside.dispatchEvent(new CustomEvent(APP_WORKSPACE_DETAIL_CLOSE_EVENT));else closeControl(aside)?.click();
|
|
339
|
+
};
|
|
340
|
+
const verticalScroller = (target, boundary) => {
|
|
341
|
+
for (let element = target; element && boundary.contains(element); element = element.parentElement) {
|
|
342
|
+
if (element instanceof HTMLElement && /^(auto|scroll)$/.test(getComputedStyle(element).overflowY) && element.scrollHeight > element.clientHeight) return element;
|
|
343
|
+
if (element === boundary) break;
|
|
344
|
+
}
|
|
345
|
+
return null;
|
|
346
|
+
};
|
|
347
|
+
const refreshItem = snapshot => {
|
|
348
|
+
snapshot.top = snapshot.item.getBoundingClientRect().top;
|
|
349
|
+
snapshot.scrollTop = snapshot.scroller?.scrollTop ?? 0;
|
|
350
|
+
};
|
|
351
|
+
const rememberInteraction = event => {
|
|
352
|
+
const target = eventElement(event);
|
|
353
|
+
const root = target?.closest(ROOT_SELECTOR);
|
|
354
|
+
if (!target || !root || !observedRoots.has(root)) return;
|
|
355
|
+
const previous = remembered.get(root);
|
|
356
|
+
if (previous && openDetails(root).length) refreshItem(previous);
|
|
357
|
+
const main = mainElement(root);
|
|
358
|
+
const item = target.closest(FOCUSABLE_SELECTOR);
|
|
359
|
+
if (!main || !item || !main.contains(item) || item.closest(ROOT_SELECTOR) !== root) return;
|
|
360
|
+
if (event instanceof KeyboardEvent && event.key !== "Enter" && event.key !== " ") return;
|
|
361
|
+
const snapshot = {
|
|
362
|
+
item,
|
|
363
|
+
interaction: event instanceof KeyboardEvent ? "keyboard" : "pointer",
|
|
364
|
+
scroller: verticalScroller(item, main),
|
|
365
|
+
scrollTop: 0,
|
|
366
|
+
top: 0,
|
|
367
|
+
fresh: true
|
|
368
|
+
};
|
|
369
|
+
refreshItem(snapshot);
|
|
370
|
+
remembered.set(root, snapshot);
|
|
371
|
+
// Enter in an editor or a field types; only an item that chooses something moves on to its title.
|
|
372
|
+
if (event instanceof KeyboardEvent && !target.closest(KEY_OWNER_SELECTOR)) {
|
|
373
|
+
const aside = openDetails(root).find(isVisible);
|
|
374
|
+
if (aside) requestTitle(aside, true);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
const onDetailFocusIn = event => {
|
|
378
|
+
const target = eventElement(event);
|
|
379
|
+
const root = target?.closest(ROOT_SELECTOR);
|
|
380
|
+
if (!target || !root || !observedRoots.has(root)) return;
|
|
381
|
+
lastFocus.set(root, target);
|
|
382
|
+
const previous = remembered.get(root);
|
|
383
|
+
// Pointer focus follows pointerdown; keeping that snapshot also keeps the
|
|
384
|
+
// interaction that opened the panel rather than treating focus as a new one.
|
|
385
|
+
if (previous?.item.contains(target)) {
|
|
386
|
+
const main = mainElement(root);
|
|
387
|
+
if (target !== previous.item && target instanceof HTMLElement && main) {
|
|
388
|
+
previous.item = target;
|
|
389
|
+
previous.scroller = verticalScroller(target, main);
|
|
390
|
+
refreshItem(previous);
|
|
391
|
+
}
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
rememberInteraction(event);
|
|
395
|
+
};
|
|
396
|
+
const titleIn = aside => aside.querySelector("h1, h2, h3, [role='heading']");
|
|
397
|
+
let focusingTitle = null;
|
|
398
|
+
const focusTitle = aside => {
|
|
399
|
+
const title = titleIn(aside);
|
|
400
|
+
if (!title) return false;
|
|
401
|
+
if (!title.matches(FOCUSABLE_SELECTOR) && !title.hasAttribute("tabindex")) {
|
|
402
|
+
title.tabIndex = -1;
|
|
403
|
+
titleTabIndices.add(title);
|
|
404
|
+
}
|
|
405
|
+
focusingTitle = title;
|
|
406
|
+
try {
|
|
407
|
+
title.focus({
|
|
408
|
+
preventScroll: true
|
|
409
|
+
});
|
|
410
|
+
} finally {
|
|
411
|
+
focusingTitle = null;
|
|
412
|
+
}
|
|
413
|
+
return true;
|
|
414
|
+
};
|
|
415
|
+
let pendingTitle = null;
|
|
416
|
+
const cancelTitle = () => {
|
|
417
|
+
pendingTitle?.observer.disconnect();
|
|
418
|
+
pendingTitle = null;
|
|
419
|
+
};
|
|
420
|
+
const cancelTitleOnInteraction = event => {
|
|
421
|
+
if (event.type !== "focusin" || event.target !== focusingTitle) cancelTitle();
|
|
422
|
+
};
|
|
423
|
+
const requestTitle = (aside, waitForChange = false) => {
|
|
424
|
+
cancelTitle();
|
|
425
|
+
if (aside.hidden || !aside.isConnected) return;
|
|
426
|
+
if (!waitForChange && focusTitle(aside)) return;
|
|
427
|
+
const previousTitle = titleIn(aside);
|
|
428
|
+
const previousText = previousTitle?.textContent;
|
|
429
|
+
// Loading fallbacks and selection changes can produce their heading after
|
|
430
|
+
// the opening interaction. A later user action always takes precedence.
|
|
431
|
+
const observer = new MutationObserver(() => {
|
|
432
|
+
if (aside.hidden || !aside.isConnected) {
|
|
433
|
+
cancelTitle();
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const title = titleIn(aside);
|
|
437
|
+
if (!title || waitForChange && title === previousTitle && title.textContent === previousText) return;
|
|
438
|
+
cancelTitle();
|
|
439
|
+
focusTitle(aside);
|
|
440
|
+
});
|
|
441
|
+
pendingTitle = {
|
|
442
|
+
aside,
|
|
443
|
+
observer
|
|
444
|
+
};
|
|
445
|
+
observer.observe(aside, {
|
|
446
|
+
childList: true,
|
|
447
|
+
subtree: true,
|
|
448
|
+
characterData: true
|
|
449
|
+
});
|
|
450
|
+
// An element-scoped controller cannot see its own root leave the document.
|
|
451
|
+
observer.observe(ownerDocument, {
|
|
452
|
+
childList: true,
|
|
453
|
+
subtree: true
|
|
454
|
+
});
|
|
455
|
+
};
|
|
456
|
+
const setDetent = (aside, full) => {
|
|
457
|
+
touchedDetails.add(aside);
|
|
458
|
+
if (full) aside.dataset.workspaceDetailSheet = "full";else delete aside.dataset.workspaceDetailSheet;
|
|
459
|
+
aside.querySelector(grabberSelector)?.setAttribute("aria-pressed", String(full));
|
|
460
|
+
};
|
|
461
|
+
const clearDrag = aside => {
|
|
462
|
+
aside.style.removeProperty("--k2b-workspace-detail-sheet-height");
|
|
463
|
+
aside.style.removeProperty("transform");
|
|
464
|
+
delete aside.dataset.workspaceDetailDragging;
|
|
465
|
+
};
|
|
466
|
+
const trailsIn = root => {
|
|
467
|
+
const main = mainElement(root);
|
|
468
|
+
return main ? rootElements(root, trailSelector).filter(trail => main.contains(trail)) : [];
|
|
469
|
+
};
|
|
470
|
+
const clearHolds = root => {
|
|
471
|
+
for (const trail of trailsIn(root)) {
|
|
472
|
+
trail.style.removeProperty("--k2b-detail-trail-hold");
|
|
473
|
+
heldTrails.delete(trail);
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
const rememberTrailPadding = root => {
|
|
477
|
+
if (!openDetails(root).some(isVisible)) return;
|
|
478
|
+
for (const trail of trailsIn(root)) trailPadding.set(trail, Number.parseFloat(getComputedStyle(trail).paddingInlineEnd) || 0);
|
|
479
|
+
};
|
|
480
|
+
const shrinkHold = trail => {
|
|
481
|
+
const hold = Number.parseFloat(trail.style.getPropertyValue("--k2b-detail-trail-hold")) || 0;
|
|
482
|
+
const visible = trail.scrollWidth <= trail.clientWidth || trail.scrollLeft < 1 ? 0 : Math.min(hold, Math.max(0, Math.ceil(trail.scrollLeft + trail.clientWidth - (trail.scrollWidth - hold))));
|
|
483
|
+
if (visible > 0) trail.style.setProperty("--k2b-detail-trail-hold", `${visible}px`);else {
|
|
484
|
+
trail.style.removeProperty("--k2b-detail-trail-hold");
|
|
485
|
+
heldTrails.delete(trail);
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
const onTrailScroll = event => {
|
|
489
|
+
const target = eventElement(event);
|
|
490
|
+
if (target instanceof HTMLElement && heldTrails.has(target)) shrinkHold(target);
|
|
491
|
+
};
|
|
492
|
+
const anchorItem = (root, aside, snapshot) => {
|
|
493
|
+
if (!wide?.matches || touchDrawer?.matches && closable(aside) || trailsIn(root).length || !snapshot?.item.isConnected) return;
|
|
494
|
+
if (!mainElement(root)?.contains(snapshot.item) || snapshot.item.closest(ROOT_SELECTOR) !== root) return;
|
|
495
|
+
const scroller = snapshot.scroller;
|
|
496
|
+
if (scroller?.isConnected && scroller.scrollTop === snapshot.scrollTop) scroller.scrollTop += snapshot.item.getBoundingClientRect().top - snapshot.top;
|
|
497
|
+
};
|
|
498
|
+
const detailTransition = (aside, wasHidden) => {
|
|
499
|
+
const root = aside.closest(ROOT_SELECTOR);
|
|
500
|
+
detailHidden.set(aside, Boolean(aside.hidden));
|
|
501
|
+
if (!root || !observedRoots.has(root) || Boolean(aside.hidden) === wasHidden) return;
|
|
502
|
+
touchedDetails.add(aside);
|
|
503
|
+
const pending = revealFrames.get(root);
|
|
504
|
+
if (pending !== undefined) cancelAnimationFrame(pending);
|
|
505
|
+
revealFrames.delete(root);
|
|
506
|
+
const snapshot = remembered.get(root);
|
|
507
|
+
const followedInteraction = snapshot?.fresh ?? false;
|
|
508
|
+
if (snapshot) snapshot.fresh = false;
|
|
509
|
+
if (aside.hidden) {
|
|
510
|
+
if (pendingTitle?.aside === aside) cancelTitle();
|
|
511
|
+
const trails = trailsIn(root);
|
|
512
|
+
// Restore all padding before the first layout read, or the browser can
|
|
513
|
+
// clamp scrollLeft as soon as the open panel's trailing space disappears.
|
|
514
|
+
for (const trail of trails) {
|
|
515
|
+
const hold = trailPadding.get(trail) ?? 0;
|
|
516
|
+
if (hold > 0) {
|
|
517
|
+
trail.style.setProperty("--k2b-detail-trail-hold", `${hold}px`);
|
|
518
|
+
heldTrails.add(trail);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
trails.forEach(shrinkHold);
|
|
522
|
+
anchorItem(root, aside, snapshot);
|
|
523
|
+
const focused = ownerDocument.activeElement;
|
|
524
|
+
if (snapshot?.item.isConnected && (aside.contains(lastFocus.get(root) ?? null) || aside.contains(focused) || focused === ownerDocument.body)) snapshot.item.focus({
|
|
525
|
+
preventScroll: true
|
|
526
|
+
});
|
|
527
|
+
clearDrag(aside);
|
|
528
|
+
if (detailDrag?.aside === aside) finishDetailDrag(true);
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
clearHolds(root);
|
|
532
|
+
anchorItem(root, aside, snapshot);
|
|
533
|
+
if (phone?.matches) setDetent(aside, false);
|
|
534
|
+
rememberTrailPadding(root);
|
|
535
|
+
if (followedInteraction && snapshot) {
|
|
536
|
+
revealFrames.set(root, requestAnimationFrame(() => {
|
|
537
|
+
revealFrames.delete(root);
|
|
538
|
+
if (!aside.hidden && aside.isConnected && snapshot.item.isConnected && mainElement(root)?.contains(snapshot.item) && snapshot.item.closest(ROOT_SELECTOR) === root) {
|
|
539
|
+
const behavior = reducedMotion?.matches ? "auto" : "smooth";
|
|
540
|
+
if (phone?.matches) {
|
|
541
|
+
const sheetTop = ownerWindow.innerHeight - aside.offsetHeight;
|
|
542
|
+
const overlap = snapshot.item.getBoundingClientRect().bottom - sheetTop + 8;
|
|
543
|
+
const main = mainElement(root);
|
|
544
|
+
if (overlap > 0 && main) (verticalScroller(snapshot.item, main) ?? ownerDocument.scrollingElement)?.scrollBy({
|
|
545
|
+
top: overlap,
|
|
546
|
+
behavior
|
|
547
|
+
});
|
|
548
|
+
} else snapshot.item.scrollIntoView({
|
|
549
|
+
block: "nearest",
|
|
550
|
+
inline: "nearest",
|
|
551
|
+
behavior
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
}));
|
|
555
|
+
if (snapshot.interaction === "keyboard" || phone?.matches) requestTitle(aside);
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
const onDetailKeyDown = event => {
|
|
559
|
+
if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey) return;
|
|
560
|
+
const target = eventElement(event);
|
|
561
|
+
if (!target || target.closest(KEY_OWNER_SELECTOR)) return;
|
|
562
|
+
if (ownerDocument.querySelector("dialog[open], [aria-modal='true']")) return;
|
|
563
|
+
try {
|
|
564
|
+
if (ownerDocument.querySelector(":popover-open")) return;
|
|
565
|
+
} catch {
|
|
566
|
+
// Older engines have no popover selector; the other popup guards still apply.
|
|
567
|
+
}
|
|
568
|
+
const root = target.closest(ROOT_SELECTOR);
|
|
569
|
+
let aside = target.closest(detailSelector);
|
|
570
|
+
if (aside?.hidden || aside && (!eventRoot.contains(aside) || aside.closest(ROOT_SELECTOR) !== root)) aside = null;
|
|
571
|
+
if (!aside && root && observedRoots.has(root) && mainElement(root)?.contains(target)) aside = openDetails(root)[0] ?? null;
|
|
572
|
+
if (!aside && target === ownerDocument.body) {
|
|
573
|
+
const open = allRoots().flatMap(openDetails);
|
|
574
|
+
if (open.length === 1) aside = open[0];
|
|
575
|
+
}
|
|
576
|
+
const owningRoot = aside?.closest(ROOT_SELECTOR);
|
|
577
|
+
if (!aside || !owningRoot) return;
|
|
578
|
+
if (event.key === "Escape" && closable(aside)) requestClose(aside);else if ((event.key.toLowerCase() === "j" || event.key.toLowerCase() === "k") && aside.hasAttribute("data-workspace-detail-steppable")) aside.dispatchEvent(new CustomEvent(APP_WORKSPACE_DETAIL_STEP_EVENT, {
|
|
579
|
+
detail: {
|
|
580
|
+
direction: event.key.toLowerCase() === "j" ? 1 : -1
|
|
581
|
+
}
|
|
582
|
+
}));else if (event.key === "F6") {
|
|
583
|
+
if (aside.contains(target)) {
|
|
584
|
+
const item = remembered.get(owningRoot)?.item;
|
|
585
|
+
const main = mainElement(owningRoot);
|
|
586
|
+
(item?.isConnected ? item : main ? tabStopsIn(main)[0] : null)?.focus({
|
|
587
|
+
preventScroll: true
|
|
588
|
+
});
|
|
589
|
+
} else focusTitle(aside);
|
|
590
|
+
} else return;
|
|
591
|
+
event.preventDefault();
|
|
592
|
+
};
|
|
593
|
+
let detailDrag = null;
|
|
594
|
+
let detailDragFrame = null;
|
|
595
|
+
let suppressedClick = null;
|
|
596
|
+
let suppressedClickTimer = null;
|
|
597
|
+
const paintDetailDrag = () => {
|
|
598
|
+
detailDragFrame = null;
|
|
599
|
+
const drag = detailDrag;
|
|
600
|
+
if (!drag?.moved) return;
|
|
601
|
+
drag.aside.dataset.workspaceDetailDragging = "true";
|
|
602
|
+
touchedDetails.add(drag.aside);
|
|
603
|
+
if (drag.source === "drawer") drag.aside.style.transform = `translateX(${Math.max(0, drag.dx)}px)`;else {
|
|
604
|
+
const height = ownerWindow.innerHeight;
|
|
605
|
+
drag.aside.style.setProperty("--k2b-workspace-detail-sheet-height", `${clamp(drag.startHeight - drag.dy, 0, Math.max(0, height - 8))}px`);
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
const scheduleDetailDrag = () => {
|
|
609
|
+
if (detailDragFrame === null) detailDragFrame = requestAnimationFrame(paintDetailDrag);
|
|
610
|
+
};
|
|
611
|
+
const finishDetailDrag = cancelled => {
|
|
612
|
+
const drag = detailDrag;
|
|
613
|
+
if (!drag) return;
|
|
614
|
+
detailDrag = null;
|
|
615
|
+
if (detailDragFrame !== null) cancelAnimationFrame(detailDragFrame);
|
|
616
|
+
detailDragFrame = null;
|
|
617
|
+
drag.releaseTextSelection?.();
|
|
618
|
+
if (drag.source === "pointer") {
|
|
619
|
+
if (drag.target instanceof HTMLElement && drag.target.hasPointerCapture?.(drag.pointerId)) drag.target.releasePointerCapture(drag.pointerId);
|
|
620
|
+
if (drag.moved) {
|
|
621
|
+
suppressedClick = drag.aside;
|
|
622
|
+
if (suppressedClickTimer !== null) clearTimeout(suppressedClickTimer);
|
|
623
|
+
suppressedClickTimer = setTimeout(() => {
|
|
624
|
+
suppressedClick = null;
|
|
625
|
+
suppressedClickTimer = null;
|
|
626
|
+
}, 0);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
clearDrag(drag.aside);
|
|
630
|
+
if (cancelled || !drag.moved) return;
|
|
631
|
+
if (drag.source === "drawer") {
|
|
632
|
+
if (drag.dx > 80 || drag.dx > 30 && drag.velocity > 0.5) requestClose(drag.aside);
|
|
633
|
+
} else if (drag.dy > 60) {
|
|
634
|
+
setDetent(drag.aside, false);
|
|
635
|
+
if (!drag.full && closable(drag.aside)) requestClose(drag.aside);
|
|
636
|
+
} else if (drag.dy < -60) setDetent(drag.aside, true);
|
|
637
|
+
};
|
|
638
|
+
const beginDetailDrag = (aside, target, source, x, y, pointerId) => {
|
|
639
|
+
detailDrag = {
|
|
640
|
+
aside,
|
|
641
|
+
target,
|
|
642
|
+
source,
|
|
643
|
+
pointerId,
|
|
644
|
+
startX: x,
|
|
645
|
+
startY: y,
|
|
646
|
+
startHeight: aside.getBoundingClientRect().height,
|
|
647
|
+
full: aside.dataset.workspaceDetailSheet === "full",
|
|
648
|
+
dx: 0,
|
|
649
|
+
dy: 0,
|
|
650
|
+
time: performance.now(),
|
|
651
|
+
velocity: 0,
|
|
652
|
+
moved: false
|
|
653
|
+
};
|
|
654
|
+
return detailDrag;
|
|
655
|
+
};
|
|
656
|
+
const onSheetPointerDown = event => {
|
|
657
|
+
if (!(event instanceof PointerEvent) || !phone?.matches || event.button !== 0 || !event.isPrimary || claimedDetailGestures.has(event)) return;
|
|
658
|
+
const target = eventElement(event);
|
|
659
|
+
const aside = target?.closest(detailSelector);
|
|
660
|
+
const root = aside?.closest(ROOT_SELECTOR);
|
|
661
|
+
if (!target || !aside || !root || aside.hidden || !observedRoots.has(root) || target.closest(ROOT_SELECTOR) !== root) return;
|
|
662
|
+
const grabber = target.closest(grabberSelector);
|
|
663
|
+
if (!grabber && (!target.closest(".k2b-detail-panel__header") || target.closest("a, button, input, select, textarea, [role='button'], [contenteditable]:not([contenteditable='false'])"))) return;
|
|
664
|
+
claimedDetailGestures.add(event);
|
|
665
|
+
if (detailDrag) finishDetailDrag(true);
|
|
666
|
+
const drag = beginDetailDrag(aside, grabber ?? target, "pointer", event.clientX, event.clientY, event.pointerId);
|
|
667
|
+
drag.releaseTextSelection = suppressTextSelection(event.pointerId);
|
|
668
|
+
if (drag.target instanceof HTMLElement) drag.target.setPointerCapture?.(event.pointerId);
|
|
669
|
+
aside.dataset.workspaceDetailDragging = "true";
|
|
670
|
+
touchedDetails.add(aside);
|
|
671
|
+
};
|
|
672
|
+
const onSheetPointerMove = event => {
|
|
673
|
+
const drag = detailDrag;
|
|
674
|
+
if (!drag || drag.source !== "pointer" || drag.pointerId !== event.pointerId) return;
|
|
675
|
+
drag.dy = event.clientY - drag.startY;
|
|
676
|
+
drag.moved ||= Math.abs(drag.dy) > 4;
|
|
677
|
+
if (drag.moved) scheduleDetailDrag();
|
|
678
|
+
};
|
|
679
|
+
const onSheetPointerEnd = event => {
|
|
680
|
+
if (!(event instanceof PointerEvent)) return;
|
|
681
|
+
if (detailDrag?.source === "pointer" && detailDrag.pointerId === event.pointerId) finishDetailDrag(event.type !== "pointerup");
|
|
682
|
+
};
|
|
683
|
+
const onGrabberClick = event => {
|
|
684
|
+
const target = eventElement(event);
|
|
685
|
+
const grabber = target?.closest(grabberSelector);
|
|
686
|
+
const aside = grabber?.closest(detailSelector);
|
|
687
|
+
if (!aside || aside.hidden || !phone?.matches || claimedToggleClicks.has(event)) return;
|
|
688
|
+
claimedToggleClicks.add(event);
|
|
689
|
+
if (suppressedClick === aside && event instanceof MouseEvent && event.detail !== 0) {
|
|
690
|
+
event.preventDefault();
|
|
691
|
+
suppressedClick = null;
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
setDetent(aside, aside.dataset.workspaceDetailSheet !== "full");
|
|
695
|
+
};
|
|
696
|
+
const ownsTouchGesture = (target, aside, source) => {
|
|
697
|
+
for (let element = target; element && element !== aside; element = element.parentElement) {
|
|
698
|
+
if (element.matches("input, textarea, select, [contenteditable]:not([contenteditable='false']), [role='slider'], [draggable='true'], canvas")) return true;
|
|
699
|
+
const action = getComputedStyle(element).getPropertyValue("touch-action");
|
|
700
|
+
const horizontal = /\bpan-(x|left|right)\b/.test(action);
|
|
701
|
+
const vertical = /\bpan-(y|up|down)\b/.test(action);
|
|
702
|
+
if (action.trim() === "none" || (source === "drawer" ? vertical && !horizontal : horizontal && !vertical)) return true;
|
|
703
|
+
}
|
|
704
|
+
return false;
|
|
705
|
+
};
|
|
706
|
+
const onDetailTouchStart = event => {
|
|
707
|
+
if (!(event instanceof TouchEvent) || event.touches.length !== 1) {
|
|
708
|
+
if (detailDrag && detailDrag.source !== "pointer") finishDetailDrag(true);
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
if (detailDrag || claimedDetailGestures.has(event)) return;
|
|
712
|
+
const target = eventElement(event);
|
|
713
|
+
const aside = target?.closest(detailSelector);
|
|
714
|
+
const touch = event.touches[0];
|
|
715
|
+
const root = aside?.closest(ROOT_SELECTOR);
|
|
716
|
+
if (!target || !aside || !root || aside.hidden || !touch || !observedRoots.has(root) || target.closest(ROOT_SELECTOR) !== root) return;
|
|
717
|
+
if (phone?.matches && (verticalScroller(target, aside) ?? aside).scrollTop <= 0) {
|
|
718
|
+
if (!ownsTouchGesture(target, aside, "sheet")) beginDetailDrag(aside, target, "sheet", touch.clientX, touch.clientY, touch.identifier);
|
|
719
|
+
} else if (touchDrawer?.matches && closable(aside)) {
|
|
720
|
+
if (!ownsTouchGesture(target, aside, "drawer")) beginDetailDrag(aside, target, "drawer", touch.clientX, touch.clientY, touch.identifier);
|
|
721
|
+
}
|
|
722
|
+
if (detailDrag) claimedDetailGestures.add(event);
|
|
723
|
+
};
|
|
724
|
+
const onDetailTouchMove = event => {
|
|
725
|
+
const drag = detailDrag;
|
|
726
|
+
if (!(event instanceof TouchEvent) || !drag || drag.source === "pointer") return;
|
|
727
|
+
const touch = Array.from(event.touches).find(touch => touch.identifier === drag.pointerId);
|
|
728
|
+
if (!touch || event.touches.length !== 1) {
|
|
729
|
+
finishDetailDrag(true);
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const dx = touch.clientX - drag.startX;
|
|
733
|
+
const dy = touch.clientY - drag.startY;
|
|
734
|
+
const now = performance.now();
|
|
735
|
+
drag.velocity = (dx - drag.dx) / Math.max(1, now - drag.time);
|
|
736
|
+
drag.time = now;
|
|
737
|
+
drag.dx = dx;
|
|
738
|
+
drag.dy = dy;
|
|
739
|
+
if (!drag.moved) {
|
|
740
|
+
if (drag.source === "sheet") {
|
|
741
|
+
if (dy < 0 || (verticalScroller(drag.target, drag.aside) ?? drag.aside).scrollTop > 0) {
|
|
742
|
+
finishDetailDrag(true);
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
if (dy <= 4) return;
|
|
746
|
+
} else {
|
|
747
|
+
if (Math.max(Math.abs(dx), Math.abs(dy)) <= 8) return;
|
|
748
|
+
if (dx <= Math.abs(dy)) {
|
|
749
|
+
finishDetailDrag(true);
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
for (let element = drag.target; element && drag.aside.contains(element); element = element.parentElement) {
|
|
753
|
+
if (element instanceof HTMLElement && /^(auto|scroll)$/.test(getComputedStyle(element).overflowX) && element.scrollWidth > element.clientWidth && element.scrollLeft > 0) {
|
|
754
|
+
finishDetailDrag(true);
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
if (element === drag.aside) break;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
drag.moved = true;
|
|
761
|
+
}
|
|
762
|
+
event.preventDefault();
|
|
763
|
+
scheduleDetailDrag();
|
|
764
|
+
};
|
|
765
|
+
const onDetailTouchEnd = event => {
|
|
766
|
+
if (detailDrag && detailDrag.source !== "pointer") finishDetailDrag(event.type === "touchcancel");
|
|
767
|
+
};
|
|
768
|
+
const onDetailDoubleClick = event => {
|
|
769
|
+
const handle = resizeHandle(event);
|
|
770
|
+
const root = handle?.closest(ROOT_SELECTOR);
|
|
771
|
+
if (!handle || !root || resizeKind(handle) !== "detail" || !workspaceResizable(root) || !controlsResizableRegion(root, handle, "detail")) return;
|
|
772
|
+
const widths = {
|
|
773
|
+
...layoutState.detailWidths
|
|
774
|
+
};
|
|
775
|
+
delete widths[panelId(handle)];
|
|
776
|
+
layoutState = {
|
|
777
|
+
...layoutState,
|
|
778
|
+
detailWidths: widths
|
|
779
|
+
};
|
|
780
|
+
const variable = appWorkspacePanelVariable("detail", panelId(handle));
|
|
781
|
+
root.style.removeProperty(variable);
|
|
782
|
+
if (getComputedStyle(root).getPropertyValue(variable).trim()) root.style.setProperty(variable, `${numberData(handle, "workspaceDefaultSize", APP_WORKSPACE_DETAIL_DEFAULT)}px`);
|
|
783
|
+
updateHandleValue(root, handle, "detail", currentSize(root, handle, "detail"));
|
|
784
|
+
rememberTrailPadding(root);
|
|
785
|
+
options.writeState?.(layoutState);
|
|
786
|
+
};
|
|
170
787
|
const stopScrollFades = installScrollFades(eventRoot);
|
|
171
788
|
let layoutState = normalizeAppWorkspaceLayoutState(options.readState?.()) ?? {
|
|
172
789
|
version: 2
|
|
@@ -246,9 +863,10 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
246
863
|
const size = finished.kind === "pane" ? finished.liveSize : applySize(finished.root, finished.handle, finished.kind, finished.liveSize);
|
|
247
864
|
persistSize(finished.handle, finished.kind, size);
|
|
248
865
|
if (finished.kind !== "drawer") reconcilePanes(finished.root, layoutState);
|
|
866
|
+
if (finished.kind === "detail") rememberTrailPadding(finished.root);
|
|
249
867
|
}
|
|
250
868
|
if (finished.handle.hasPointerCapture?.(finished.pointerId)) finished.handle.releasePointerCapture(finished.pointerId);
|
|
251
|
-
|
|
869
|
+
finished.releaseTextSelection();
|
|
252
870
|
window.removeEventListener("pointermove", onPointerMove);
|
|
253
871
|
window.removeEventListener("pointerup", stopResize);
|
|
254
872
|
window.removeEventListener("pointercancel", stopResize);
|
|
@@ -274,11 +892,10 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
274
892
|
moved: false,
|
|
275
893
|
hiding: false,
|
|
276
894
|
direction: resizeDirection(handle, kind),
|
|
277
|
-
|
|
895
|
+
releaseTextSelection: suppressTextSelection(event.pointerId)
|
|
278
896
|
};
|
|
279
897
|
root.dataset.workspaceResizeActive = kind;
|
|
280
898
|
handle.dataset.workspaceResizeActive = "true";
|
|
281
|
-
document.body.style.userSelect = "none";
|
|
282
899
|
handle.setPointerCapture?.(event.pointerId);
|
|
283
900
|
window.addEventListener("pointermove", onPointerMove);
|
|
284
901
|
window.addEventListener("pointerup", stopResize);
|
|
@@ -312,6 +929,7 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
312
929
|
event.preventDefault();
|
|
313
930
|
persistSize(handle, kind, applySize(root, handle, kind, requested));
|
|
314
931
|
if (kind === "sidebar" || kind === "detail") reconcilePanes(root, layoutState);
|
|
932
|
+
if (kind === "detail") rememberTrailPadding(root);
|
|
315
933
|
};
|
|
316
934
|
const allRoots = () => {
|
|
317
935
|
const nested = Array.from(eventRoot.querySelectorAll(ROOT_SELECTOR));
|
|
@@ -324,6 +942,15 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
324
942
|
return allRoots().filter(root => getComputedStyle(root).display !== "none" && root.getBoundingClientRect().width > 0);
|
|
325
943
|
};
|
|
326
944
|
const reconcile = () => {
|
|
945
|
+
if (detailDrag && (detailDrag.source === "drawer" ? !touchDrawer?.matches : !phone?.matches)) finishDetailDrag(true);
|
|
946
|
+
allRoots().forEach(root => {
|
|
947
|
+
if (!phone?.matches) {
|
|
948
|
+
for (const aside of rootElements(root, detailSelector)) {
|
|
949
|
+
if (aside.dataset.workspaceDetailSheet === "full") setDetent(aside, false);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
rememberTrailPadding(root);
|
|
953
|
+
});
|
|
327
954
|
roots().forEach(root => {
|
|
328
955
|
// `data-workspace-resizable="false"` already refuses pointer and keyboard
|
|
329
956
|
// resizing; without this the same workspace still had persisted sizes
|
|
@@ -347,6 +974,7 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
347
974
|
});
|
|
348
975
|
reconcilePanes(root, layoutState, active?.root === root ? active : null);
|
|
349
976
|
});
|
|
977
|
+
heldTrails.forEach(shrinkHold);
|
|
350
978
|
};
|
|
351
979
|
/**
|
|
352
980
|
* A handle's limits move whenever anything around it does — opening a detail
|
|
@@ -400,28 +1028,94 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
400
1028
|
scheduleReconcile(true);
|
|
401
1029
|
});
|
|
402
1030
|
const syncObservedRoots = () => {
|
|
403
|
-
|
|
1031
|
+
for (const elements of [touchedDetails, titleTabIndices, motionRoots]) {
|
|
1032
|
+
elements.forEach(element => {
|
|
1033
|
+
if (!element.isConnected) elements.delete(element);
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
404
1036
|
const next = new Set(allRoots());
|
|
405
1037
|
observedRoots.forEach(root => {
|
|
406
1038
|
if (!next.has(root)) {
|
|
407
|
-
resizeObserver
|
|
1039
|
+
resizeObserver?.unobserve(root);
|
|
1040
|
+
const frame = motionFrames.get(root);
|
|
1041
|
+
if (frame !== undefined) cancelAnimationFrame(frame);
|
|
1042
|
+
motionFrames.delete(root);
|
|
408
1043
|
observedRoots.delete(root);
|
|
409
1044
|
}
|
|
410
1045
|
});
|
|
1046
|
+
touchMoveAsides.forEach(aside => {
|
|
1047
|
+
if (aside.isConnected) return;
|
|
1048
|
+
aside.removeEventListener("touchmove", onDetailTouchMove);
|
|
1049
|
+
touchMoveAsides.delete(aside);
|
|
1050
|
+
});
|
|
411
1051
|
next.forEach(root => {
|
|
1052
|
+
rootElements(root, detailSelector).forEach(aside => {
|
|
1053
|
+
if (!detailHidden.has(aside)) detailHidden.set(aside, Boolean(aside.hidden));
|
|
1054
|
+
if (touchMoveAsides.has(aside)) return;
|
|
1055
|
+
aside.addEventListener("touchmove", onDetailTouchMove, {
|
|
1056
|
+
passive: false
|
|
1057
|
+
});
|
|
1058
|
+
touchMoveAsides.add(aside);
|
|
1059
|
+
});
|
|
412
1060
|
if (observedRoots.has(root)) return;
|
|
413
1061
|
observedRoots.add(root);
|
|
414
|
-
resizeObserver
|
|
1062
|
+
resizeObserver?.observe(root);
|
|
1063
|
+
if (!root.hasAttribute("data-workspace-motion")) {
|
|
1064
|
+
motionRoots.add(root);
|
|
1065
|
+
motionFrames.set(root, requestAnimationFrame(() => {
|
|
1066
|
+
motionFrames.set(root, requestAnimationFrame(() => {
|
|
1067
|
+
motionFrames.delete(root);
|
|
1068
|
+
if (observedRoots.has(root)) root.dataset.workspaceMotion = "true";
|
|
1069
|
+
}));
|
|
1070
|
+
}));
|
|
1071
|
+
}
|
|
1072
|
+
rememberTrailPadding(root);
|
|
415
1073
|
});
|
|
416
1074
|
};
|
|
417
1075
|
const layoutNode = node => node instanceof Element && (node.matches(LAYOUT_REGION_SELECTOR) || Boolean(node.querySelector(LAYOUT_REGION_SELECTOR)));
|
|
418
1076
|
const mutationObserver = typeof MutationObserver === "undefined" ? null : new MutationObserver(records => {
|
|
1077
|
+
if (pendingTitle && (pendingTitle.aside.hidden || !pendingTitle.aside.isConnected)) cancelTitle();
|
|
1078
|
+
// Hiding or removing the sidebar, or its button, ends the overlay.
|
|
1079
|
+
if (overlay && (overlay.sidebar.hidden || !overlay.sidebar.isConnected || !overlay.toggle.isConnected)) closeOverlay("kept");
|
|
1080
|
+
const details = new Set();
|
|
1081
|
+
for (const record of records) {
|
|
1082
|
+
if (record.type === "attributes" && record.target instanceof HTMLElement && record.target.matches(detailSelector) && !details.has(record.target)) {
|
|
1083
|
+
details.add(record.target);
|
|
1084
|
+
detailTransition(record.target, detailHidden.get(record.target) ?? record.oldValue !== null);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
419
1087
|
const changed = records.some(record => record.type === "attributes" ? record.target instanceof Element && record.target.matches(LAYOUT_REGION_SELECTOR) : [...Array.from(record.addedNodes), ...Array.from(record.removedNodes)].some(layoutNode));
|
|
420
1088
|
if (!changed) return;
|
|
421
1089
|
syncObservedRoots();
|
|
422
1090
|
scheduleReconcile();
|
|
423
1091
|
});
|
|
424
1092
|
eventRoot.addEventListener("pointerdown", onPointerDown);
|
|
1093
|
+
eventRoot.addEventListener("click", onClick);
|
|
1094
|
+
ownerDocument.addEventListener("keydown", onOverlayKeyDown);
|
|
1095
|
+
ownerWindow.addEventListener("keydown", onDetailKeyDown);
|
|
1096
|
+
ownerDocument.addEventListener("focusin", cancelTitleOnInteraction, true);
|
|
1097
|
+
ownerDocument.addEventListener("pointerdown", cancelTitleOnInteraction, true);
|
|
1098
|
+
ownerDocument.addEventListener("keydown", cancelTitleOnInteraction, true);
|
|
1099
|
+
eventRoot.addEventListener("pointerdown", rememberInteraction, true);
|
|
1100
|
+
eventRoot.addEventListener("keydown", rememberInteraction, true);
|
|
1101
|
+
eventRoot.addEventListener("focusin", onDetailFocusIn);
|
|
1102
|
+
eventRoot.addEventListener("scroll", onTrailScroll, {
|
|
1103
|
+
passive: true,
|
|
1104
|
+
capture: true
|
|
1105
|
+
});
|
|
1106
|
+
eventRoot.addEventListener("pointerdown", onSheetPointerDown);
|
|
1107
|
+
eventRoot.addEventListener("click", onGrabberClick);
|
|
1108
|
+
eventRoot.addEventListener("dblclick", onDetailDoubleClick);
|
|
1109
|
+
window.addEventListener("pointermove", onSheetPointerMove);
|
|
1110
|
+
window.addEventListener("pointerup", onSheetPointerEnd);
|
|
1111
|
+
window.addEventListener("pointercancel", onSheetPointerEnd);
|
|
1112
|
+
eventRoot.addEventListener("lostpointercapture", onSheetPointerEnd);
|
|
1113
|
+
eventRoot.addEventListener("touchstart", onDetailTouchStart, {
|
|
1114
|
+
passive: true
|
|
1115
|
+
});
|
|
1116
|
+
eventRoot.addEventListener("touchend", onDetailTouchEnd);
|
|
1117
|
+
eventRoot.addEventListener("touchcancel", onDetailTouchEnd);
|
|
1118
|
+
compact?.addEventListener("change", onCompactChange);
|
|
425
1119
|
eventRoot.addEventListener("keydown", onKeyDown);
|
|
426
1120
|
eventRoot.addEventListener("focusin", onFocusIn);
|
|
427
1121
|
eventRoot.addEventListener("pointerover", onPointerOver);
|
|
@@ -429,13 +1123,46 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
429
1123
|
syncObservedRoots();
|
|
430
1124
|
mutationObserver?.observe(eventRoot, {
|
|
431
1125
|
attributes: true,
|
|
1126
|
+
attributeOldValue: true,
|
|
432
1127
|
attributeFilter: ["hidden"],
|
|
433
1128
|
childList: true,
|
|
434
1129
|
subtree: true
|
|
435
1130
|
});
|
|
436
1131
|
scheduleReconcile();
|
|
437
1132
|
return () => {
|
|
1133
|
+
cancelTitle();
|
|
438
1134
|
stopScrollFades();
|
|
1135
|
+
finishDetailDrag(true);
|
|
1136
|
+
if (suppressedClickTimer !== null) clearTimeout(suppressedClickTimer);
|
|
1137
|
+
motionFrames.forEach(cancelAnimationFrame);
|
|
1138
|
+
revealFrames.forEach(cancelAnimationFrame);
|
|
1139
|
+
motionRoots.forEach(root => delete root.dataset.workspaceMotion);
|
|
1140
|
+
heldTrails.forEach(trail => trail.style.removeProperty("--k2b-detail-trail-hold"));
|
|
1141
|
+
touchedDetails.forEach(aside => {
|
|
1142
|
+
clearDrag(aside);
|
|
1143
|
+
delete aside.dataset.workspaceDetailSheet;
|
|
1144
|
+
aside.querySelector(grabberSelector)?.setAttribute("aria-pressed", "false");
|
|
1145
|
+
});
|
|
1146
|
+
titleTabIndices.forEach(title => title.removeAttribute("tabindex"));
|
|
1147
|
+
ownerWindow.removeEventListener("keydown", onDetailKeyDown);
|
|
1148
|
+
ownerDocument.removeEventListener("focusin", cancelTitleOnInteraction, true);
|
|
1149
|
+
ownerDocument.removeEventListener("pointerdown", cancelTitleOnInteraction, true);
|
|
1150
|
+
ownerDocument.removeEventListener("keydown", cancelTitleOnInteraction, true);
|
|
1151
|
+
eventRoot.removeEventListener("pointerdown", rememberInteraction, true);
|
|
1152
|
+
eventRoot.removeEventListener("keydown", rememberInteraction, true);
|
|
1153
|
+
eventRoot.removeEventListener("focusin", onDetailFocusIn);
|
|
1154
|
+
eventRoot.removeEventListener("scroll", onTrailScroll, true);
|
|
1155
|
+
eventRoot.removeEventListener("pointerdown", onSheetPointerDown);
|
|
1156
|
+
eventRoot.removeEventListener("click", onGrabberClick);
|
|
1157
|
+
eventRoot.removeEventListener("dblclick", onDetailDoubleClick);
|
|
1158
|
+
window.removeEventListener("pointermove", onSheetPointerMove);
|
|
1159
|
+
window.removeEventListener("pointerup", onSheetPointerEnd);
|
|
1160
|
+
window.removeEventListener("pointercancel", onSheetPointerEnd);
|
|
1161
|
+
eventRoot.removeEventListener("lostpointercapture", onSheetPointerEnd);
|
|
1162
|
+
eventRoot.removeEventListener("touchstart", onDetailTouchStart);
|
|
1163
|
+
touchMoveAsides.forEach(aside => aside.removeEventListener("touchmove", onDetailTouchMove));
|
|
1164
|
+
eventRoot.removeEventListener("touchend", onDetailTouchEnd);
|
|
1165
|
+
eventRoot.removeEventListener("touchcancel", onDetailTouchEnd);
|
|
439
1166
|
// Flush the latest coalesced pointer sample before listeners and frames are
|
|
440
1167
|
// torn down, so unmounting during a drag cannot lose the final size.
|
|
441
1168
|
stopResize();
|
|
@@ -443,7 +1170,11 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
443
1170
|
mutationObserver?.disconnect();
|
|
444
1171
|
resizeObserver?.disconnect();
|
|
445
1172
|
observedRoots.clear();
|
|
1173
|
+
closeOverlay("none");
|
|
446
1174
|
eventRoot.removeEventListener("pointerdown", onPointerDown);
|
|
1175
|
+
eventRoot.removeEventListener("click", onClick);
|
|
1176
|
+
ownerDocument.removeEventListener("keydown", onOverlayKeyDown);
|
|
1177
|
+
compact?.removeEventListener("change", onCompactChange);
|
|
447
1178
|
eventRoot.removeEventListener("keydown", onKeyDown);
|
|
448
1179
|
eventRoot.removeEventListener("focusin", onFocusIn);
|
|
449
1180
|
eventRoot.removeEventListener("pointerover", onPointerOver);
|