@k2b/ui 0.1.0-rc.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/LICENSE +661 -0
- package/README.md +343 -0
- package/dist/.build-complete +0 -0
- package/dist/browser/actions/Button.js +236 -0
- package/dist/browser/actions/Button.js.map +1 -0
- package/dist/browser/actions/ContextMenu.js +199 -0
- package/dist/browser/actions/ContextMenu.js.map +1 -0
- package/dist/browser/actions/CopyButton.js +97 -0
- package/dist/browser/actions/CopyButton.js.map +1 -0
- package/dist/browser/actions/Disclosure.js +83 -0
- package/dist/browser/actions/Disclosure.js.map +1 -0
- package/dist/browser/actions/Dropdown.js +669 -0
- package/dist/browser/actions/Dropdown.js.map +1 -0
- package/dist/browser/actions/FilterChip.js +149 -0
- package/dist/browser/actions/FilterChip.js.map +1 -0
- package/dist/browser/actions/RemoveButton.js +47 -0
- package/dist/browser/actions/RemoveButton.js.map +1 -0
- package/dist/browser/actions/SegmentedControl.js +138 -0
- package/dist/browser/actions/SegmentedControl.js.map +1 -0
- package/dist/browser/actions/SplitButton.js +76 -0
- package/dist/browser/actions/SplitButton.js.map +1 -0
- package/dist/browser/actions/SpotlightSearch.js +87 -0
- package/dist/browser/actions/SpotlightSearch.js.map +1 -0
- package/dist/browser/actions/Tabs.js +185 -0
- package/dist/browser/actions/Tabs.js.map +1 -0
- package/dist/browser/actions/Toolbar.js +87 -0
- package/dist/browser/actions/Toolbar.js.map +1 -0
- package/dist/browser/actions/index.js +13 -0
- package/dist/browser/actions/index.js.map +1 -0
- package/dist/browser/chat/ChatComposer.js +760 -0
- package/dist/browser/chat/ChatComposer.js.map +1 -0
- package/dist/browser/chat/ChatPrimitives.js +688 -0
- package/dist/browser/chat/ChatPrimitives.js.map +1 -0
- package/dist/browser/chat/ChatRoot.js +27 -0
- package/dist/browser/chat/ChatRoot.js.map +1 -0
- package/dist/browser/chat/ChatTimeline.js +404 -0
- package/dist/browser/chat/ChatTimeline.js.map +1 -0
- package/dist/browser/chat/chat-behavior.js +53 -0
- package/dist/browser/chat/chat-behavior.js.map +1 -0
- package/dist/browser/chat/index.js +17 -0
- package/dist/browser/chat/index.js.map +1 -0
- package/dist/browser/chat/types.js +2 -0
- package/dist/browser/chat/types.js.map +1 -0
- package/dist/browser/content/Calendar.js +2168 -0
- package/dist/browser/content/Calendar.js.map +1 -0
- package/dist/browser/content/Chart.js +680 -0
- package/dist/browser/content/Chart.js.map +1 -0
- package/dist/browser/content/CodeDisplay.js +104 -0
- package/dist/browser/content/CodeDisplay.js.map +1 -0
- package/dist/browser/content/DataTable.js +724 -0
- package/dist/browser/content/DataTable.js.map +1 -0
- package/dist/browser/content/Docs.js +227 -0
- package/dist/browser/content/Docs.js.map +1 -0
- package/dist/browser/content/FileBrowser.js +462 -0
- package/dist/browser/content/FileBrowser.js.map +1 -0
- package/dist/browser/content/FileTree.js +453 -0
- package/dist/browser/content/FileTree.js.map +1 -0
- package/dist/browser/content/FileView.js +842 -0
- package/dist/browser/content/FileView.js.map +1 -0
- package/dist/browser/content/Lightbox.js +285 -0
- package/dist/browser/content/Lightbox.js.map +1 -0
- package/dist/browser/content/LogEntriesTable.js +139 -0
- package/dist/browser/content/LogEntriesTable.js.map +1 -0
- package/dist/browser/content/MarkdownView.js +138 -0
- package/dist/browser/content/MarkdownView.js.map +1 -0
- package/dist/browser/content/Pagination.js +182 -0
- package/dist/browser/content/Pagination.js.map +1 -0
- package/dist/browser/content/PdfPreview.js +204 -0
- package/dist/browser/content/PdfPreview.js.map +1 -0
- package/dist/browser/content/RangePicker.js +83 -0
- package/dist/browser/content/RangePicker.js.map +1 -0
- package/dist/browser/content/StructuredDataPreview.js +194 -0
- package/dist/browser/content/StructuredDataPreview.js.map +1 -0
- package/dist/browser/content/calendar-event-layout.js +92 -0
- package/dist/browser/content/calendar-event-layout.js.map +1 -0
- package/dist/browser/content/calendar-pointer.js +114 -0
- package/dist/browser/content/calendar-pointer.js.map +1 -0
- package/dist/browser/content/chart-map-viewport.js +33 -0
- package/dist/browser/content/chart-map-viewport.js.map +1 -0
- package/dist/browser/content/chart-state-timeline.js +124 -0
- package/dist/browser/content/chart-state-timeline.js.map +1 -0
- package/dist/browser/content/code-highlight.js +144 -0
- package/dist/browser/content/code-highlight.js.map +1 -0
- package/dist/browser/content/file-tree.js +93 -0
- package/dist/browser/content/file-tree.js.map +1 -0
- package/dist/browser/content/file-view-preview.js +112 -0
- package/dist/browser/content/file-view-preview.js.map +1 -0
- package/dist/browser/content/index.js +16 -0
- package/dist/browser/content/index.js.map +1 -0
- package/dist/browser/feedback/InlineGuidance.js +46 -0
- package/dist/browser/feedback/InlineGuidance.js.map +1 -0
- package/dist/browser/feedback/Tooltip.js +189 -0
- package/dist/browser/feedback/Tooltip.js.map +1 -0
- package/dist/browser/feedback/dialog-core.js +207 -0
- package/dist/browser/feedback/dialog-core.js.map +1 -0
- package/dist/browser/feedback/index.js +6 -0
- package/dist/browser/feedback/index.js.map +1 -0
- package/dist/browser/feedback/prompts.js +991 -0
- package/dist/browser/feedback/prompts.js.map +1 -0
- package/dist/browser/feedback/toast.js +271 -0
- package/dist/browser/feedback/toast.js.map +1 -0
- package/dist/browser/feedback/tooltip-position.js +25 -0
- package/dist/browser/feedback/tooltip-position.js.map +1 -0
- package/dist/browser/index.js +11 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/inputs/AutocompleteEditor.js +610 -0
- package/dist/browser/inputs/AutocompleteEditor.js.map +1 -0
- package/dist/browser/inputs/AutocompleteSelect.js +632 -0
- package/dist/browser/inputs/AutocompleteSelect.js.map +1 -0
- package/dist/browser/inputs/Checkbox.js +137 -0
- package/dist/browser/inputs/Checkbox.js.map +1 -0
- package/dist/browser/inputs/CheckboxCard.js +130 -0
- package/dist/browser/inputs/CheckboxCard.js.map +1 -0
- package/dist/browser/inputs/ChoiceGroups.js +174 -0
- package/dist/browser/inputs/ChoiceGroups.js.map +1 -0
- package/dist/browser/inputs/ChoiceInputs.js +400 -0
- package/dist/browser/inputs/ChoiceInputs.js.map +1 -0
- package/dist/browser/inputs/Combobox.js +274 -0
- package/dist/browser/inputs/Combobox.js.map +1 -0
- package/dist/browser/inputs/DatePicker.js +923 -0
- package/dist/browser/inputs/DatePicker.js.map +1 -0
- package/dist/browser/inputs/FileInputs.js +736 -0
- package/dist/browser/inputs/FileInputs.js.map +1 -0
- package/dist/browser/inputs/MultiSelectInput.js +565 -0
- package/dist/browser/inputs/MultiSelectInput.js.map +1 -0
- package/dist/browser/inputs/NumberInput.js +288 -0
- package/dist/browser/inputs/NumberInput.js.map +1 -0
- package/dist/browser/inputs/Select.js +507 -0
- package/dist/browser/inputs/Select.js.map +1 -0
- package/dist/browser/inputs/SelectChip.js +151 -0
- package/dist/browser/inputs/SelectChip.js.map +1 -0
- package/dist/browser/inputs/SpecialInputs.js +117 -0
- package/dist/browser/inputs/SpecialInputs.js.map +1 -0
- package/dist/browser/inputs/Switch.js +117 -0
- package/dist/browser/inputs/Switch.js.map +1 -0
- package/dist/browser/inputs/TagEditor.js +358 -0
- package/dist/browser/inputs/TagEditor.js.map +1 -0
- package/dist/browser/inputs/TagsInput.js +195 -0
- package/dist/browser/inputs/TagsInput.js.map +1 -0
- package/dist/browser/inputs/TemplateEditor.js +190 -0
- package/dist/browser/inputs/TemplateEditor.js.map +1 -0
- package/dist/browser/inputs/TextInput.js +318 -0
- package/dist/browser/inputs/TextInput.js.map +1 -0
- package/dist/browser/inputs/choice.js +188 -0
- package/dist/browser/inputs/choice.js.map +1 -0
- package/dist/browser/inputs/completion/behaviors.js +108 -0
- package/dist/browser/inputs/completion/behaviors.js.map +1 -0
- package/dist/browser/inputs/completion/engine.js +103 -0
- package/dist/browser/inputs/completion/engine.js.map +1 -0
- package/dist/browser/inputs/completion/index.js +4 -0
- package/dist/browser/inputs/completion/index.js.map +1 -0
- package/dist/browser/inputs/completion/overlay.js +25 -0
- package/dist/browser/inputs/completion/overlay.js.map +1 -0
- package/dist/browser/inputs/date-picker.js +123 -0
- package/dist/browser/inputs/date-picker.js.map +1 -0
- package/dist/browser/inputs/editor-dom.js +26 -0
- package/dist/browser/inputs/editor-dom.js.map +1 -0
- package/dist/browser/inputs/field-contract.js +9 -0
- package/dist/browser/inputs/field-contract.js.map +1 -0
- package/dist/browser/inputs/icon-options.js +46 -0
- package/dist/browser/inputs/icon-options.js.map +1 -0
- package/dist/browser/inputs/image-crop.js +145 -0
- package/dist/browser/inputs/image-crop.js.map +1 -0
- package/dist/browser/inputs/index.js +23 -0
- package/dist/browser/inputs/index.js.map +1 -0
- package/dist/browser/inputs/markdown/MarkdownEditor.js +725 -0
- package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -0
- package/dist/browser/inputs/markdown/Toolbar.js +172 -0
- package/dist/browser/inputs/markdown/Toolbar.js.map +1 -0
- package/dist/browser/inputs/markdown/actions.js +140 -0
- package/dist/browser/inputs/markdown/actions.js.map +1 -0
- package/dist/browser/inputs/markdown/active-formats.js +36 -0
- package/dist/browser/inputs/markdown/active-formats.js.map +1 -0
- package/dist/browser/inputs/markdown/behaviors.js +63 -0
- package/dist/browser/inputs/markdown/behaviors.js.map +1 -0
- package/dist/browser/inputs/markdown/code-zone.js +8 -0
- package/dist/browser/inputs/markdown/code-zone.js.map +1 -0
- package/dist/browser/internal/color.js +18 -0
- package/dist/browser/internal/color.js.map +1 -0
- package/dist/browser/internal/field.js +158 -0
- package/dist/browser/internal/field.js.map +1 -0
- package/dist/browser/internal/portal.js +17 -0
- package/dist/browser/internal/portal.js.map +1 -0
- package/dist/browser/intl/Format.js +273 -0
- package/dist/browser/intl/Format.js.map +1 -0
- package/dist/browser/intl/index.js +3 -0
- package/dist/browser/intl/index.js.map +1 -0
- package/dist/browser/intl/locale.js +63 -0
- package/dist/browser/intl/locale.js.map +1 -0
- package/dist/browser/intl/messages.js +753 -0
- package/dist/browser/intl/messages.js.map +1 -0
- package/dist/browser/layout/AppOverview.js +151 -0
- package/dist/browser/layout/AppOverview.js.map +1 -0
- package/dist/browser/layout/AppWorkspace.js +1502 -0
- package/dist/browser/layout/AppWorkspace.js.map +1 -0
- package/dist/browser/layout/DataPanel.js +122 -0
- package/dist/browser/layout/DataPanel.js.map +1 -0
- package/dist/browser/layout/DetailPanel.js +484 -0
- package/dist/browser/layout/DetailPanel.js.map +1 -0
- package/dist/browser/layout/Discussion.js +511 -0
- package/dist/browser/layout/Discussion.js.map +1 -0
- package/dist/browser/layout/FloatingWindow.js +332 -0
- package/dist/browser/layout/FloatingWindow.js.map +1 -0
- package/dist/browser/layout/PanelDialog.js +236 -0
- package/dist/browser/layout/PanelDialog.js.map +1 -0
- package/dist/browser/layout/PanelHeader.js +91 -0
- package/dist/browser/layout/PanelHeader.js.map +1 -0
- package/dist/browser/layout/Panes.js +978 -0
- package/dist/browser/layout/Panes.js.map +1 -0
- package/dist/browser/layout/ScrollArea.js +29 -0
- package/dist/browser/layout/ScrollArea.js.map +1 -0
- package/dist/browser/layout/Settings.js +381 -0
- package/dist/browser/layout/Settings.js.map +1 -0
- package/dist/browser/layout/SettingsCollection.js +212 -0
- package/dist/browser/layout/SettingsCollection.js.map +1 -0
- package/dist/browser/layout/SettingsModal.js +281 -0
- package/dist/browser/layout/SettingsModal.js.map +1 -0
- package/dist/browser/layout/app-workspace-controller.js +419 -0
- package/dist/browser/layout/app-workspace-controller.js.map +1 -0
- package/dist/browser/layout/app-workspace-state.js +125 -0
- package/dist/browser/layout/app-workspace-state.js.map +1 -0
- package/dist/browser/layout/floating-window-geometry.js +15 -0
- package/dist/browser/layout/floating-window-geometry.js.map +1 -0
- package/dist/browser/layout/index.js +17 -0
- package/dist/browser/layout/index.js.map +1 -0
- package/dist/browser/layout/panes-layout.js +436 -0
- package/dist/browser/layout/panes-layout.js.map +1 -0
- package/dist/browser/layout/stable-id.js +17 -0
- package/dist/browser/layout/stable-id.js.map +1 -0
- package/dist/browser/semantics.js +2 -0
- package/dist/browser/semantics.js.map +1 -0
- package/dist/browser/surfaces/Avatar.js +97 -0
- package/dist/browser/surfaces/Avatar.js.map +1 -0
- package/dist/browser/surfaces/DescriptionList.js +66 -0
- package/dist/browser/surfaces/DescriptionList.js.map +1 -0
- package/dist/browser/surfaces/LinkCard.js +40 -0
- package/dist/browser/surfaces/LinkCard.js.map +1 -0
- package/dist/browser/surfaces/NotFoundState.js +85 -0
- package/dist/browser/surfaces/NotFoundState.js.map +1 -0
- package/dist/browser/surfaces/NoticeCard.js +145 -0
- package/dist/browser/surfaces/NoticeCard.js.map +1 -0
- package/dist/browser/surfaces/Paper.js +33 -0
- package/dist/browser/surfaces/Paper.js.map +1 -0
- package/dist/browser/surfaces/Placeholder.js +90 -0
- package/dist/browser/surfaces/Placeholder.js.map +1 -0
- package/dist/browser/surfaces/ProgressBar.js +58 -0
- package/dist/browser/surfaces/ProgressBar.js.map +1 -0
- package/dist/browser/surfaces/StatCell.js +172 -0
- package/dist/browser/surfaces/StatCell.js.map +1 -0
- package/dist/browser/surfaces/StatGrid.js +80 -0
- package/dist/browser/surfaces/StatGrid.js.map +1 -0
- package/dist/browser/surfaces/StatusBadge.js +70 -0
- package/dist/browser/surfaces/StatusBadge.js.map +1 -0
- package/dist/browser/surfaces/Tag.js +94 -0
- package/dist/browser/surfaces/Tag.js.map +1 -0
- package/dist/browser/surfaces/index.js +13 -0
- package/dist/browser/surfaces/index.js.map +1 -0
- package/dist/browser/widgets/Widget.js +89 -0
- package/dist/browser/widgets/Widget.js.map +1 -0
- package/dist/browser/widgets/WidgetHero.js +47 -0
- package/dist/browser/widgets/WidgetHero.js.map +1 -0
- package/dist/browser/widgets/WidgetList.js +125 -0
- package/dist/browser/widgets/WidgetList.js.map +1 -0
- package/dist/browser/widgets/WidgetPills.js +78 -0
- package/dist/browser/widgets/WidgetPills.js.map +1 -0
- package/dist/browser/widgets/WidgetStat.js +114 -0
- package/dist/browser/widgets/WidgetStat.js.map +1 -0
- package/dist/browser/widgets/WidgetStatus.js +54 -0
- package/dist/browser/widgets/WidgetStatus.js.map +1 -0
- package/dist/browser/widgets/index.js +7 -0
- package/dist/browser/widgets/index.js.map +1 -0
- package/dist/global.css +3 -0
- package/dist/licenses/ibm-plex-mono.txt +93 -0
- package/dist/licenses/ibm-plex-sans.txt +93 -0
- package/dist/licenses/tabler-icons.txt +21 -0
- package/dist/plex.css +1 -0
- package/dist/ssr/actions/Button.js +203 -0
- package/dist/ssr/actions/Button.js.map +1 -0
- package/dist/ssr/actions/ContextMenu.js +128 -0
- package/dist/ssr/actions/ContextMenu.js.map +1 -0
- package/dist/ssr/actions/CopyButton.js +79 -0
- package/dist/ssr/actions/CopyButton.js.map +1 -0
- package/dist/ssr/actions/Disclosure.js +26 -0
- package/dist/ssr/actions/Disclosure.js.map +1 -0
- package/dist/ssr/actions/Dropdown.js +443 -0
- package/dist/ssr/actions/Dropdown.js.map +1 -0
- package/dist/ssr/actions/FilterChip.js +132 -0
- package/dist/ssr/actions/FilterChip.js.map +1 -0
- package/dist/ssr/actions/RemoveButton.js +45 -0
- package/dist/ssr/actions/RemoveButton.js.map +1 -0
- package/dist/ssr/actions/SegmentedControl.js +57 -0
- package/dist/ssr/actions/SegmentedControl.js.map +1 -0
- package/dist/ssr/actions/SplitButton.js +74 -0
- package/dist/ssr/actions/SplitButton.js.map +1 -0
- package/dist/ssr/actions/SpotlightSearch.js +38 -0
- package/dist/ssr/actions/SpotlightSearch.js.map +1 -0
- package/dist/ssr/actions/Tabs.js +91 -0
- package/dist/ssr/actions/Tabs.js.map +1 -0
- package/dist/ssr/actions/Toolbar.js +33 -0
- package/dist/ssr/actions/Toolbar.js.map +1 -0
- package/dist/ssr/actions/index.js +13 -0
- package/dist/ssr/actions/index.js.map +1 -0
- package/dist/ssr/chat/ChatComposer.js +392 -0
- package/dist/ssr/chat/ChatComposer.js.map +1 -0
- package/dist/ssr/chat/ChatPrimitives.js +377 -0
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -0
- package/dist/ssr/chat/ChatRoot.js +10 -0
- package/dist/ssr/chat/ChatRoot.js.map +1 -0
- package/dist/ssr/chat/ChatTimeline.js +301 -0
- package/dist/ssr/chat/ChatTimeline.js.map +1 -0
- package/dist/ssr/chat/chat-behavior.js +53 -0
- package/dist/ssr/chat/chat-behavior.js.map +1 -0
- package/dist/ssr/chat/index.js +17 -0
- package/dist/ssr/chat/index.js.map +1 -0
- package/dist/ssr/chat/types.js +2 -0
- package/dist/ssr/chat/types.js.map +1 -0
- package/dist/ssr/content/Calendar.js +1542 -0
- package/dist/ssr/content/Calendar.js.map +1 -0
- package/dist/ssr/content/Chart.js +552 -0
- package/dist/ssr/content/Chart.js.map +1 -0
- package/dist/ssr/content/CodeDisplay.js +55 -0
- package/dist/ssr/content/CodeDisplay.js.map +1 -0
- package/dist/ssr/content/DataTable.js +470 -0
- package/dist/ssr/content/DataTable.js.map +1 -0
- package/dist/ssr/content/Docs.js +108 -0
- package/dist/ssr/content/Docs.js.map +1 -0
- package/dist/ssr/content/FileBrowser.js +422 -0
- package/dist/ssr/content/FileBrowser.js.map +1 -0
- package/dist/ssr/content/FileTree.js +299 -0
- package/dist/ssr/content/FileTree.js.map +1 -0
- package/dist/ssr/content/FileView.js +612 -0
- package/dist/ssr/content/FileView.js.map +1 -0
- package/dist/ssr/content/Lightbox.js +164 -0
- package/dist/ssr/content/Lightbox.js.map +1 -0
- package/dist/ssr/content/LogEntriesTable.js +106 -0
- package/dist/ssr/content/LogEntriesTable.js.map +1 -0
- package/dist/ssr/content/MarkdownView.js +119 -0
- package/dist/ssr/content/MarkdownView.js.map +1 -0
- package/dist/ssr/content/Pagination.js +141 -0
- package/dist/ssr/content/Pagination.js.map +1 -0
- package/dist/ssr/content/PdfPreview.js +126 -0
- package/dist/ssr/content/PdfPreview.js.map +1 -0
- package/dist/ssr/content/RangePicker.js +35 -0
- package/dist/ssr/content/RangePicker.js.map +1 -0
- package/dist/ssr/content/StructuredDataPreview.js +127 -0
- package/dist/ssr/content/StructuredDataPreview.js.map +1 -0
- package/dist/ssr/content/calendar-event-layout.js +92 -0
- package/dist/ssr/content/calendar-event-layout.js.map +1 -0
- package/dist/ssr/content/calendar-pointer.js +114 -0
- package/dist/ssr/content/calendar-pointer.js.map +1 -0
- package/dist/ssr/content/chart-map-viewport.js +33 -0
- package/dist/ssr/content/chart-map-viewport.js.map +1 -0
- package/dist/ssr/content/chart-state-timeline.js +124 -0
- package/dist/ssr/content/chart-state-timeline.js.map +1 -0
- package/dist/ssr/content/code-highlight.js +144 -0
- package/dist/ssr/content/code-highlight.js.map +1 -0
- package/dist/ssr/content/file-tree.js +93 -0
- package/dist/ssr/content/file-tree.js.map +1 -0
- package/dist/ssr/content/file-view-preview.js +112 -0
- package/dist/ssr/content/file-view-preview.js.map +1 -0
- package/dist/ssr/content/index.js +16 -0
- package/dist/ssr/content/index.js.map +1 -0
- package/dist/ssr/feedback/InlineGuidance.js +26 -0
- package/dist/ssr/feedback/InlineGuidance.js.map +1 -0
- package/dist/ssr/feedback/Tooltip.js +156 -0
- package/dist/ssr/feedback/Tooltip.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +207 -0
- package/dist/ssr/feedback/dialog-core.js.map +1 -0
- package/dist/ssr/feedback/index.js +6 -0
- package/dist/ssr/feedback/index.js.map +1 -0
- package/dist/ssr/feedback/prompts.js +703 -0
- package/dist/ssr/feedback/prompts.js.map +1 -0
- package/dist/ssr/feedback/toast.js +271 -0
- package/dist/ssr/feedback/toast.js.map +1 -0
- package/dist/ssr/feedback/tooltip-position.js +25 -0
- package/dist/ssr/feedback/tooltip-position.js.map +1 -0
- package/dist/ssr/index.js +11 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/ssr/inputs/AutocompleteEditor.js +463 -0
- package/dist/ssr/inputs/AutocompleteEditor.js.map +1 -0
- package/dist/ssr/inputs/AutocompleteSelect.js +420 -0
- package/dist/ssr/inputs/AutocompleteSelect.js.map +1 -0
- package/dist/ssr/inputs/Checkbox.js +75 -0
- package/dist/ssr/inputs/Checkbox.js.map +1 -0
- package/dist/ssr/inputs/CheckboxCard.js +69 -0
- package/dist/ssr/inputs/CheckboxCard.js.map +1 -0
- package/dist/ssr/inputs/ChoiceGroups.js +101 -0
- package/dist/ssr/inputs/ChoiceGroups.js.map +1 -0
- package/dist/ssr/inputs/ChoiceInputs.js +250 -0
- package/dist/ssr/inputs/ChoiceInputs.js.map +1 -0
- package/dist/ssr/inputs/Combobox.js +177 -0
- package/dist/ssr/inputs/Combobox.js.map +1 -0
- package/dist/ssr/inputs/DatePicker.js +629 -0
- package/dist/ssr/inputs/DatePicker.js.map +1 -0
- package/dist/ssr/inputs/FileInputs.js +543 -0
- package/dist/ssr/inputs/FileInputs.js.map +1 -0
- package/dist/ssr/inputs/MultiSelectInput.js +347 -0
- package/dist/ssr/inputs/MultiSelectInput.js.map +1 -0
- package/dist/ssr/inputs/NumberInput.js +177 -0
- package/dist/ssr/inputs/NumberInput.js.map +1 -0
- package/dist/ssr/inputs/Select.js +308 -0
- package/dist/ssr/inputs/Select.js.map +1 -0
- package/dist/ssr/inputs/SelectChip.js +129 -0
- package/dist/ssr/inputs/SelectChip.js.map +1 -0
- package/dist/ssr/inputs/SpecialInputs.js +116 -0
- package/dist/ssr/inputs/SpecialInputs.js.map +1 -0
- package/dist/ssr/inputs/Switch.js +62 -0
- package/dist/ssr/inputs/Switch.js.map +1 -0
- package/dist/ssr/inputs/TagEditor.js +280 -0
- package/dist/ssr/inputs/TagEditor.js.map +1 -0
- package/dist/ssr/inputs/TagsInput.js +122 -0
- package/dist/ssr/inputs/TagsInput.js.map +1 -0
- package/dist/ssr/inputs/TemplateEditor.js +164 -0
- package/dist/ssr/inputs/TemplateEditor.js.map +1 -0
- package/dist/ssr/inputs/TextInput.js +211 -0
- package/dist/ssr/inputs/TextInput.js.map +1 -0
- package/dist/ssr/inputs/choice.js +188 -0
- package/dist/ssr/inputs/choice.js.map +1 -0
- package/dist/ssr/inputs/completion/behaviors.js +108 -0
- package/dist/ssr/inputs/completion/behaviors.js.map +1 -0
- package/dist/ssr/inputs/completion/engine.js +103 -0
- package/dist/ssr/inputs/completion/engine.js.map +1 -0
- package/dist/ssr/inputs/completion/index.js +4 -0
- package/dist/ssr/inputs/completion/index.js.map +1 -0
- package/dist/ssr/inputs/completion/overlay.js +25 -0
- package/dist/ssr/inputs/completion/overlay.js.map +1 -0
- package/dist/ssr/inputs/date-picker.js +123 -0
- package/dist/ssr/inputs/date-picker.js.map +1 -0
- package/dist/ssr/inputs/editor-dom.js +26 -0
- package/dist/ssr/inputs/editor-dom.js.map +1 -0
- package/dist/ssr/inputs/field-contract.js +9 -0
- package/dist/ssr/inputs/field-contract.js.map +1 -0
- package/dist/ssr/inputs/icon-options.js +46 -0
- package/dist/ssr/inputs/icon-options.js.map +1 -0
- package/dist/ssr/inputs/image-crop.js +145 -0
- package/dist/ssr/inputs/image-crop.js.map +1 -0
- package/dist/ssr/inputs/index.js +23 -0
- package/dist/ssr/inputs/index.js.map +1 -0
- package/dist/ssr/inputs/markdown/MarkdownEditor.js +516 -0
- package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -0
- package/dist/ssr/inputs/markdown/Toolbar.js +115 -0
- package/dist/ssr/inputs/markdown/Toolbar.js.map +1 -0
- package/dist/ssr/inputs/markdown/actions.js +140 -0
- package/dist/ssr/inputs/markdown/actions.js.map +1 -0
- package/dist/ssr/inputs/markdown/active-formats.js +36 -0
- package/dist/ssr/inputs/markdown/active-formats.js.map +1 -0
- package/dist/ssr/inputs/markdown/behaviors.js +63 -0
- package/dist/ssr/inputs/markdown/behaviors.js.map +1 -0
- package/dist/ssr/inputs/markdown/code-zone.js +8 -0
- package/dist/ssr/inputs/markdown/code-zone.js.map +1 -0
- package/dist/ssr/internal/color.js +18 -0
- package/dist/ssr/internal/color.js.map +1 -0
- package/dist/ssr/internal/field.js +90 -0
- package/dist/ssr/internal/field.js.map +1 -0
- package/dist/ssr/internal/portal.js +17 -0
- package/dist/ssr/internal/portal.js.map +1 -0
- package/dist/ssr/intl/Format.js +192 -0
- package/dist/ssr/intl/Format.js.map +1 -0
- package/dist/ssr/intl/index.js +3 -0
- package/dist/ssr/intl/index.js.map +1 -0
- package/dist/ssr/intl/locale.js +63 -0
- package/dist/ssr/intl/locale.js.map +1 -0
- package/dist/ssr/intl/messages.js +753 -0
- package/dist/ssr/intl/messages.js.map +1 -0
- package/dist/ssr/layout/AppOverview.js +85 -0
- package/dist/ssr/layout/AppOverview.js.map +1 -0
- package/dist/ssr/layout/AppWorkspace.js +976 -0
- package/dist/ssr/layout/AppWorkspace.js.map +1 -0
- package/dist/ssr/layout/DataPanel.js +101 -0
- package/dist/ssr/layout/DataPanel.js.map +1 -0
- package/dist/ssr/layout/DetailPanel.js +284 -0
- package/dist/ssr/layout/DetailPanel.js.map +1 -0
- package/dist/ssr/layout/Discussion.js +319 -0
- package/dist/ssr/layout/Discussion.js.map +1 -0
- package/dist/ssr/layout/FloatingWindow.js +259 -0
- package/dist/ssr/layout/FloatingWindow.js.map +1 -0
- package/dist/ssr/layout/PanelDialog.js +136 -0
- package/dist/ssr/layout/PanelDialog.js.map +1 -0
- package/dist/ssr/layout/PanelHeader.js +45 -0
- package/dist/ssr/layout/PanelHeader.js.map +1 -0
- package/dist/ssr/layout/Panes.js +678 -0
- package/dist/ssr/layout/Panes.js.map +1 -0
- package/dist/ssr/layout/ScrollArea.js +18 -0
- package/dist/ssr/layout/ScrollArea.js.map +1 -0
- package/dist/ssr/layout/Settings.js +219 -0
- package/dist/ssr/layout/Settings.js.map +1 -0
- package/dist/ssr/layout/SettingsCollection.js +150 -0
- package/dist/ssr/layout/SettingsCollection.js.map +1 -0
- package/dist/ssr/layout/SettingsModal.js +156 -0
- package/dist/ssr/layout/SettingsModal.js.map +1 -0
- package/dist/ssr/layout/app-workspace-controller.js +419 -0
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -0
- package/dist/ssr/layout/app-workspace-state.js +125 -0
- package/dist/ssr/layout/app-workspace-state.js.map +1 -0
- package/dist/ssr/layout/floating-window-geometry.js +15 -0
- package/dist/ssr/layout/floating-window-geometry.js.map +1 -0
- package/dist/ssr/layout/index.js +17 -0
- package/dist/ssr/layout/index.js.map +1 -0
- package/dist/ssr/layout/panes-layout.js +436 -0
- package/dist/ssr/layout/panes-layout.js.map +1 -0
- package/dist/ssr/layout/stable-id.js +17 -0
- package/dist/ssr/layout/stable-id.js.map +1 -0
- package/dist/ssr/semantics.js +2 -0
- package/dist/ssr/semantics.js.map +1 -0
- package/dist/ssr/surfaces/Avatar.js +43 -0
- package/dist/ssr/surfaces/Avatar.js.map +1 -0
- package/dist/ssr/surfaces/DescriptionList.js +25 -0
- package/dist/ssr/surfaces/DescriptionList.js.map +1 -0
- package/dist/ssr/surfaces/LinkCard.js +25 -0
- package/dist/ssr/surfaces/LinkCard.js.map +1 -0
- package/dist/ssr/surfaces/NotFoundState.js +38 -0
- package/dist/ssr/surfaces/NotFoundState.js.map +1 -0
- package/dist/ssr/surfaces/NoticeCard.js +83 -0
- package/dist/ssr/surfaces/NoticeCard.js.map +1 -0
- package/dist/ssr/surfaces/Paper.js +32 -0
- package/dist/ssr/surfaces/Paper.js.map +1 -0
- package/dist/ssr/surfaces/Placeholder.js +76 -0
- package/dist/ssr/surfaces/Placeholder.js.map +1 -0
- package/dist/ssr/surfaces/ProgressBar.js +13 -0
- package/dist/ssr/surfaces/ProgressBar.js.map +1 -0
- package/dist/ssr/surfaces/StatCell.js +80 -0
- package/dist/ssr/surfaces/StatCell.js.map +1 -0
- package/dist/ssr/surfaces/StatGrid.js +62 -0
- package/dist/ssr/surfaces/StatGrid.js.map +1 -0
- package/dist/ssr/surfaces/StatusBadge.js +38 -0
- package/dist/ssr/surfaces/StatusBadge.js.map +1 -0
- package/dist/ssr/surfaces/Tag.js +32 -0
- package/dist/ssr/surfaces/Tag.js.map +1 -0
- package/dist/ssr/surfaces/index.js +13 -0
- package/dist/ssr/surfaces/index.js.map +1 -0
- package/dist/ssr/widgets/Widget.js +54 -0
- package/dist/ssr/widgets/Widget.js.map +1 -0
- package/dist/ssr/widgets/WidgetHero.js +23 -0
- package/dist/ssr/widgets/WidgetHero.js.map +1 -0
- package/dist/ssr/widgets/WidgetList.js +73 -0
- package/dist/ssr/widgets/WidgetList.js.map +1 -0
- package/dist/ssr/widgets/WidgetPills.js +40 -0
- package/dist/ssr/widgets/WidgetPills.js.map +1 -0
- package/dist/ssr/widgets/WidgetStat.js +45 -0
- package/dist/ssr/widgets/WidgetStat.js.map +1 -0
- package/dist/ssr/widgets/WidgetStatus.js +23 -0
- package/dist/ssr/widgets/WidgetStatus.js.map +1 -0
- package/dist/ssr/widgets/index.js +7 -0
- package/dist/ssr/widgets/index.js.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/tabler-icons-q30jt7jk.woff2 +0 -0
- package/dist/tabler.css +4 -0
- package/package.json +77 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { createEffect, createSignal, onCleanup } from "solid-js";
|
|
2
|
+
export const filterChoiceOptions = (options, query) => {
|
|
3
|
+
const normalized = query.trim().toLocaleLowerCase();
|
|
4
|
+
if (!normalized) return options;
|
|
5
|
+
return options.filter(option => [option.label, option.description, option.value].some(part => part?.toLocaleLowerCase().includes(normalized)));
|
|
6
|
+
};
|
|
7
|
+
export const nextEnabledChoiceIndex = (options, current, direction) => {
|
|
8
|
+
if (options.length === 0 || options.every(option => option.disabled)) return -1;
|
|
9
|
+
let index = current;
|
|
10
|
+
for (let visited = 0; visited < options.length; visited += 1) {
|
|
11
|
+
index = (index + direction + options.length) % options.length;
|
|
12
|
+
if (!options[index]?.disabled) return index;
|
|
13
|
+
}
|
|
14
|
+
return -1;
|
|
15
|
+
};
|
|
16
|
+
const errorMessage = error => error instanceof Error ? error.message : "Failed to load options";
|
|
17
|
+
export function createChoiceLoader(loader, debounceMs) {
|
|
18
|
+
const [options, setOptions] = createSignal([]);
|
|
19
|
+
const [loading, setLoading] = createSignal(false);
|
|
20
|
+
const [error, setError] = createSignal();
|
|
21
|
+
let controller;
|
|
22
|
+
let timer;
|
|
23
|
+
let request = 0;
|
|
24
|
+
let lastQuery = "";
|
|
25
|
+
const cancel = () => {
|
|
26
|
+
if (timer) clearTimeout(timer);
|
|
27
|
+
timer = undefined;
|
|
28
|
+
controller?.abort();
|
|
29
|
+
controller = undefined;
|
|
30
|
+
};
|
|
31
|
+
const run = async query => {
|
|
32
|
+
const loadOptions = loader();
|
|
33
|
+
if (!loadOptions) return;
|
|
34
|
+
controller?.abort();
|
|
35
|
+
controller = new AbortController();
|
|
36
|
+
const currentController = controller;
|
|
37
|
+
const currentRequest = ++request;
|
|
38
|
+
setLoading(true);
|
|
39
|
+
setError(undefined);
|
|
40
|
+
try {
|
|
41
|
+
const next = await loadOptions(query, currentController.signal);
|
|
42
|
+
if (currentRequest === request && !currentController.signal.aborted) setOptions(next);
|
|
43
|
+
} catch (reason) {
|
|
44
|
+
if (currentRequest === request && !currentController.signal.aborted) {
|
|
45
|
+
setOptions([]);
|
|
46
|
+
setError(errorMessage(reason));
|
|
47
|
+
}
|
|
48
|
+
} finally {
|
|
49
|
+
if (currentRequest === request) setLoading(false);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const load = (query, immediate = false) => {
|
|
53
|
+
lastQuery = query;
|
|
54
|
+
if (timer) clearTimeout(timer);
|
|
55
|
+
timer = undefined;
|
|
56
|
+
if (immediate || debounceMs() <= 0) {
|
|
57
|
+
void run(query);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
timer = setTimeout(() => {
|
|
61
|
+
timer = undefined;
|
|
62
|
+
void run(query);
|
|
63
|
+
}, debounceMs());
|
|
64
|
+
};
|
|
65
|
+
onCleanup(cancel);
|
|
66
|
+
return {
|
|
67
|
+
options,
|
|
68
|
+
loading,
|
|
69
|
+
error,
|
|
70
|
+
load,
|
|
71
|
+
retry: () => load(lastQuery, true),
|
|
72
|
+
cancel
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const popoverIsOpen = popover => {
|
|
76
|
+
if (!popover) return false;
|
|
77
|
+
try {
|
|
78
|
+
return popover.matches(":popover-open");
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
export const placeChoicePopover = (trigger, popover) => {
|
|
84
|
+
const margin = 8;
|
|
85
|
+
const gap = 4;
|
|
86
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
87
|
+
// Cloud sizes its dropdowns to the trigger exactly (`dialog.style.width =
|
|
88
|
+
// rect.width`). Keep that so a narrow toolbar select does not open a wide
|
|
89
|
+
// panel that no longer lines up with the control it belongs to.
|
|
90
|
+
const width = Math.min(triggerRect.width, window.innerWidth - margin * 2);
|
|
91
|
+
popover.style.width = `${width}px`;
|
|
92
|
+
const popoverRect = popover.getBoundingClientRect();
|
|
93
|
+
const left = Math.max(margin, Math.min(triggerRect.left, window.innerWidth - width - margin));
|
|
94
|
+
const roomBelow = window.innerHeight - triggerRect.bottom - gap - margin;
|
|
95
|
+
const roomAbove = triggerRect.top - gap - margin;
|
|
96
|
+
const opensAbove = popoverRect.height > roomBelow && roomAbove > roomBelow;
|
|
97
|
+
const top = opensAbove ? Math.max(margin, triggerRect.top - popoverRect.height - gap) : Math.min(triggerRect.bottom + gap, window.innerHeight - popoverRect.height - margin);
|
|
98
|
+
popover.style.left = `${left}px`;
|
|
99
|
+
popover.style.top = `${Math.max(margin, top)}px`;
|
|
100
|
+
};
|
|
101
|
+
export function createChoicePopover(disabled) {
|
|
102
|
+
const [open, setOpen] = createSignal(false);
|
|
103
|
+
const [trigger, setTrigger] = createSignal();
|
|
104
|
+
const [popover, setPopover] = createSignal();
|
|
105
|
+
const place = () => {
|
|
106
|
+
const triggerElement = trigger();
|
|
107
|
+
const popoverElement = popover();
|
|
108
|
+
if (triggerElement && popoverElement && open()) placeChoicePopover(triggerElement, popoverElement);
|
|
109
|
+
};
|
|
110
|
+
const show = () => {
|
|
111
|
+
const popoverElement = popover();
|
|
112
|
+
if (disabled() || !popoverElement || popoverIsOpen(popoverElement)) return;
|
|
113
|
+
popoverElement.showPopover();
|
|
114
|
+
setOpen(true);
|
|
115
|
+
queueMicrotask(place);
|
|
116
|
+
};
|
|
117
|
+
const hide = (restoreFocus = false) => {
|
|
118
|
+
const popoverElement = popover();
|
|
119
|
+
if (popoverIsOpen(popoverElement)) popoverElement?.hidePopover();
|
|
120
|
+
setOpen(false);
|
|
121
|
+
if (restoreFocus) queueMicrotask(() => trigger()?.focus());
|
|
122
|
+
};
|
|
123
|
+
createEffect(() => {
|
|
124
|
+
const popoverElement = popover();
|
|
125
|
+
if (!popoverElement) return;
|
|
126
|
+
const syncOpenState = () => setOpen(popoverIsOpen(popoverElement));
|
|
127
|
+
const containWheel = event => {
|
|
128
|
+
if (event.ctrlKey) return;
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
const target = event.target instanceof Element ? event.target : undefined;
|
|
131
|
+
const groups = target?.closest(".k2b-choice-groups");
|
|
132
|
+
const horizontalDelta = event.shiftKey && event.deltaX === 0 ? event.deltaY : event.deltaX;
|
|
133
|
+
if (groups && (event.shiftKey || Math.abs(event.deltaX) > Math.abs(event.deltaY)) && groups.scrollWidth > groups.clientWidth) {
|
|
134
|
+
const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? groups.clientWidth : 1;
|
|
135
|
+
groups.scrollLeft += horizontalDelta * unit;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const options = popoverElement.querySelector(".k2b-choice-options");
|
|
139
|
+
if (!options || options.scrollHeight <= options.clientHeight) return;
|
|
140
|
+
const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? options.clientHeight : 1;
|
|
141
|
+
options.scrollTop += event.deltaY * unit;
|
|
142
|
+
};
|
|
143
|
+
popoverElement.addEventListener("toggle", syncOpenState);
|
|
144
|
+
popoverElement.addEventListener("wheel", containWheel, {
|
|
145
|
+
passive: false
|
|
146
|
+
});
|
|
147
|
+
onCleanup(() => {
|
|
148
|
+
popoverElement.removeEventListener("toggle", syncOpenState);
|
|
149
|
+
popoverElement.removeEventListener("wheel", containWheel);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
createEffect(() => {
|
|
153
|
+
if (!open()) return;
|
|
154
|
+
const dismiss = event => {
|
|
155
|
+
const target = event.target;
|
|
156
|
+
if (!(target instanceof Node) || trigger()?.contains(target) || popover()?.contains(target)) return;
|
|
157
|
+
hide();
|
|
158
|
+
};
|
|
159
|
+
const reposition = () => place();
|
|
160
|
+
|
|
161
|
+
// Async option lists arrive after the popover is already open, so the first
|
|
162
|
+
// placement measures an empty panel. Re-place whenever the panel resizes,
|
|
163
|
+
// otherwise a dropdown that grows past the viewport bottom stays clipped.
|
|
164
|
+
const popoverElement = popover();
|
|
165
|
+
const observer = popoverElement && typeof ResizeObserver !== "undefined" ? new ResizeObserver(reposition) : undefined;
|
|
166
|
+
if (popoverElement) observer?.observe(popoverElement);
|
|
167
|
+
document.addEventListener("pointerdown", dismiss, true);
|
|
168
|
+
window.addEventListener("resize", reposition);
|
|
169
|
+
window.addEventListener("scroll", reposition, true);
|
|
170
|
+
onCleanup(() => {
|
|
171
|
+
observer?.disconnect();
|
|
172
|
+
document.removeEventListener("pointerdown", dismiss, true);
|
|
173
|
+
window.removeEventListener("resize", reposition);
|
|
174
|
+
window.removeEventListener("scroll", reposition, true);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
onCleanup(() => hide());
|
|
178
|
+
return {
|
|
179
|
+
open,
|
|
180
|
+
setTrigger,
|
|
181
|
+
setPopover,
|
|
182
|
+
show,
|
|
183
|
+
hide,
|
|
184
|
+
toggle: () => open() ? hide() : show(),
|
|
185
|
+
trigger
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=choice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createEffect","createSignal","onCleanup","filterChoiceOptions","options","query","normalized","trim","toLocaleLowerCase","filter","option","label","description","value","some","part","includes","nextEnabledChoiceIndex","current","direction","length","every","disabled","index","visited","errorMessage","error","Error","message","createChoiceLoader","loader","debounceMs","setOptions","loading","setLoading","setError","controller","timer","request","lastQuery","cancel","clearTimeout","undefined","abort","run","loadOptions","AbortController","currentController","currentRequest","next","signal","aborted","reason","load","immediate","setTimeout","retry","popoverIsOpen","popover","matches","placeChoicePopover","trigger","margin","gap","triggerRect","getBoundingClientRect","width","Math","min","window","innerWidth","style","popoverRect","left","max","roomBelow","innerHeight","bottom","roomAbove","top","opensAbove","height","createChoicePopover","open","setOpen","setTrigger","setPopover","place","triggerElement","popoverElement","show","showPopover","queueMicrotask","hide","restoreFocus","hidePopover","focus","syncOpenState","containWheel","event","ctrlKey","preventDefault","target","Element","groups","closest","horizontalDelta","shiftKey","deltaX","deltaY","abs","scrollWidth","clientWidth","unit","deltaMode","scrollLeft","querySelector","scrollHeight","clientHeight","scrollTop","addEventListener","passive","removeEventListener","dismiss","Node","contains","reposition","observer","ResizeObserver","observe","document","disconnect","toggle"],"sources":["inputs/choice.ts"],"sourcesContent":["import { createEffect, createSignal, onCleanup, type Setter } from \"solid-js\";\n\nexport type ChoiceOption<T extends string = string> = {\n value: T;\n label: string;\n description?: string;\n icon?: string;\n color?: string;\n disabled?: boolean;\n /** Optional overlapping groups used by choice controls that expose group filtering. */\n groups?: readonly string[];\n};\n\nexport type ChoiceOptionsLoader<T extends string = string> = (query: string, signal: AbortSignal) => Promise<readonly ChoiceOption<T>[]>;\n\nexport const filterChoiceOptions = <T extends string>(options: readonly ChoiceOption<T>[], query: string): readonly ChoiceOption<T>[] => {\n const normalized = query.trim().toLocaleLowerCase();\n if (!normalized) return options;\n return options.filter((option) =>\n [option.label, option.description, option.value].some((part) => part?.toLocaleLowerCase().includes(normalized)),\n );\n};\n\nexport const nextEnabledChoiceIndex = <T extends string>(\n options: readonly ChoiceOption<T>[],\n current: number,\n direction: 1 | -1,\n): number => {\n if (options.length === 0 || options.every((option) => option.disabled)) return -1;\n\n let index = current;\n for (let visited = 0; visited < options.length; visited += 1) {\n index = (index + direction + options.length) % options.length;\n if (!options[index]?.disabled) return index;\n }\n return -1;\n};\n\nconst errorMessage = (error: unknown): string => (error instanceof Error ? error.message : \"Failed to load options\");\n\nexport function createChoiceLoader<T extends string>(\n loader: () => ChoiceOptionsLoader<T> | undefined,\n debounceMs: () => number,\n): {\n options: () => readonly ChoiceOption<T>[];\n loading: () => boolean;\n error: () => string | undefined;\n load: (query: string, immediate?: boolean) => void;\n retry: () => void;\n cancel: () => void;\n} {\n const [options, setOptions] = createSignal<readonly ChoiceOption<T>[]>([]);\n const [loading, setLoading] = createSignal(false);\n const [error, setError] = createSignal<string>();\n let controller: AbortController | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let request = 0;\n let lastQuery = \"\";\n\n const cancel = () => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n controller?.abort();\n controller = undefined;\n };\n\n const run = async (query: string) => {\n const loadOptions = loader();\n if (!loadOptions) return;\n\n controller?.abort();\n controller = new AbortController();\n const currentController = controller;\n const currentRequest = ++request;\n setLoading(true);\n setError(undefined);\n\n try {\n const next = await loadOptions(query, currentController.signal);\n if (currentRequest === request && !currentController.signal.aborted) setOptions(next);\n } catch (reason) {\n if (currentRequest === request && !currentController.signal.aborted) {\n setOptions([]);\n setError(errorMessage(reason));\n }\n } finally {\n if (currentRequest === request) setLoading(false);\n }\n };\n\n const load = (query: string, immediate = false) => {\n lastQuery = query;\n if (timer) clearTimeout(timer);\n timer = undefined;\n if (immediate || debounceMs() <= 0) {\n void run(query);\n return;\n }\n timer = setTimeout(() => {\n timer = undefined;\n void run(query);\n }, debounceMs());\n };\n\n onCleanup(cancel);\n return { options, loading, error, load, retry: () => load(lastQuery, true), cancel };\n}\n\nconst popoverIsOpen = (popover: HTMLElement | undefined): boolean => {\n if (!popover) return false;\n try {\n return popover.matches(\":popover-open\");\n } catch {\n return false;\n }\n};\n\nexport const placeChoicePopover = (trigger: HTMLElement, popover: HTMLElement): void => {\n const margin = 8;\n const gap = 4;\n const triggerRect = trigger.getBoundingClientRect();\n // Cloud sizes its dropdowns to the trigger exactly (`dialog.style.width =\n // rect.width`). Keep that so a narrow toolbar select does not open a wide\n // panel that no longer lines up with the control it belongs to.\n const width = Math.min(triggerRect.width, window.innerWidth - margin * 2);\n popover.style.width = `${width}px`;\n\n const popoverRect = popover.getBoundingClientRect();\n const left = Math.max(margin, Math.min(triggerRect.left, window.innerWidth - width - margin));\n const roomBelow = window.innerHeight - triggerRect.bottom - gap - margin;\n const roomAbove = triggerRect.top - gap - margin;\n const opensAbove = popoverRect.height > roomBelow && roomAbove > roomBelow;\n const top = opensAbove\n ? Math.max(margin, triggerRect.top - popoverRect.height - gap)\n : Math.min(triggerRect.bottom + gap, window.innerHeight - popoverRect.height - margin);\n\n popover.style.left = `${left}px`;\n popover.style.top = `${Math.max(margin, top)}px`;\n};\n\nexport function createChoicePopover(disabled: () => boolean): {\n open: () => boolean;\n setTrigger: Setter<HTMLElement | undefined>;\n setPopover: Setter<HTMLElement | undefined>;\n show: () => void;\n hide: (restoreFocus?: boolean) => void;\n toggle: () => void;\n trigger: () => HTMLElement | undefined;\n} {\n const [open, setOpen] = createSignal(false);\n const [trigger, setTrigger] = createSignal<HTMLElement>();\n const [popover, setPopover] = createSignal<HTMLElement>();\n\n const place = () => {\n const triggerElement = trigger();\n const popoverElement = popover();\n if (triggerElement && popoverElement && open()) placeChoicePopover(triggerElement, popoverElement);\n };\n\n const show = () => {\n const popoverElement = popover();\n if (disabled() || !popoverElement || popoverIsOpen(popoverElement)) return;\n popoverElement.showPopover();\n setOpen(true);\n queueMicrotask(place);\n };\n\n const hide = (restoreFocus = false) => {\n const popoverElement = popover();\n if (popoverIsOpen(popoverElement)) popoverElement?.hidePopover();\n setOpen(false);\n if (restoreFocus) queueMicrotask(() => trigger()?.focus());\n };\n\n createEffect(() => {\n const popoverElement = popover();\n if (!popoverElement) return;\n const syncOpenState = () => setOpen(popoverIsOpen(popoverElement));\n const containWheel = (event: WheelEvent) => {\n if (event.ctrlKey) return;\n event.preventDefault();\n\n const target = event.target instanceof Element ? event.target : undefined;\n const groups = target?.closest<HTMLElement>(\".k2b-choice-groups\");\n const horizontalDelta = event.shiftKey && event.deltaX === 0 ? event.deltaY : event.deltaX;\n if (groups && (event.shiftKey || Math.abs(event.deltaX) > Math.abs(event.deltaY)) && groups.scrollWidth > groups.clientWidth) {\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? groups.clientWidth : 1;\n groups.scrollLeft += horizontalDelta * unit;\n return;\n }\n\n const options = popoverElement.querySelector<HTMLElement>(\".k2b-choice-options\");\n if (!options || options.scrollHeight <= options.clientHeight) return;\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? options.clientHeight : 1;\n options.scrollTop += event.deltaY * unit;\n };\n popoverElement.addEventListener(\"toggle\", syncOpenState);\n popoverElement.addEventListener(\"wheel\", containWheel, { passive: false });\n onCleanup(() => {\n popoverElement.removeEventListener(\"toggle\", syncOpenState);\n popoverElement.removeEventListener(\"wheel\", containWheel);\n });\n });\n\n createEffect(() => {\n if (!open()) return;\n\n const dismiss = (event: PointerEvent) => {\n const target = event.target;\n if (!(target instanceof Node) || trigger()?.contains(target) || popover()?.contains(target)) return;\n hide();\n };\n const reposition = () => place();\n\n // Async option lists arrive after the popover is already open, so the first\n // placement measures an empty panel. Re-place whenever the panel resizes,\n // otherwise a dropdown that grows past the viewport bottom stays clipped.\n const popoverElement = popover();\n const observer = popoverElement && typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(reposition) : undefined;\n if (popoverElement) observer?.observe(popoverElement);\n\n document.addEventListener(\"pointerdown\", dismiss, true);\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"scroll\", reposition, true);\n onCleanup(() => {\n observer?.disconnect();\n document.removeEventListener(\"pointerdown\", dismiss, true);\n window.removeEventListener(\"resize\", reposition);\n window.removeEventListener(\"scroll\", reposition, true);\n });\n });\n\n onCleanup(() => hide());\n return {\n open,\n setTrigger,\n setPopover,\n show,\n hide,\n toggle: () => (open() ? hide() : show()),\n trigger,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { replaceTextareaRange } from "../editor-dom";
|
|
2
|
+
import { suggestSync, TRIGGER_CHARS, WORD_CHAR } from "./engine";
|
|
3
|
+
const findExpansion = (word, completions, context) => {
|
|
4
|
+
for (const completion of completions) {
|
|
5
|
+
if (completion.trigger !== undefined) continue;
|
|
6
|
+
const suggestions = suggestSync(completion, word, context);
|
|
7
|
+
if (!suggestions) continue;
|
|
8
|
+
const exact = suggestions.find(suggestion => suggestion.text === word && suggestion.expansion && suggestion.expansion !== word);
|
|
9
|
+
if (exact) return exact;
|
|
10
|
+
const normalized = word.toLowerCase();
|
|
11
|
+
const insensitive = suggestions.find(suggestion => suggestion.text.toLowerCase() === normalized && suggestion.expansion && suggestion.expansion !== word);
|
|
12
|
+
if (insensitive) return insensitive;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
};
|
|
16
|
+
/** Keeps abbreviation restoration isolated to one editor instance. */
|
|
17
|
+
export const createCompletionBehaviorState = () => {
|
|
18
|
+
let lastExpansion = null;
|
|
19
|
+
let suppressNextExpansion = false;
|
|
20
|
+
const reset = () => {
|
|
21
|
+
lastExpansion = null;
|
|
22
|
+
suppressNextExpansion = false;
|
|
23
|
+
};
|
|
24
|
+
const tryExpand = (textarea, completions, options = {}) => {
|
|
25
|
+
if (suppressNextExpansion) {
|
|
26
|
+
suppressNextExpansion = false;
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
if (!completions || completions.length === 0) return false;
|
|
30
|
+
const value = textarea.value;
|
|
31
|
+
const caret = textarea.selectionStart;
|
|
32
|
+
if (caret === 0 || caret !== textarea.selectionEnd) return false;
|
|
33
|
+
const triggerChar = value[caret - 1];
|
|
34
|
+
if (!triggerChar || !TRIGGER_CHARS.has(triggerChar)) return false;
|
|
35
|
+
const wordEnd = caret - 1;
|
|
36
|
+
let wordStart = wordEnd;
|
|
37
|
+
while (wordStart > 0 && WORD_CHAR.test(value[wordStart - 1])) wordStart--;
|
|
38
|
+
if (wordStart === wordEnd || options.isExcluded?.(value, wordStart)) return false;
|
|
39
|
+
const originalWord = value.slice(wordStart, wordEnd);
|
|
40
|
+
const suggestion = findExpansion(originalWord, completions, {
|
|
41
|
+
fullText: value,
|
|
42
|
+
caret,
|
|
43
|
+
tokenStart: wordStart
|
|
44
|
+
});
|
|
45
|
+
if (!suggestion?.expansion || suggestion.expansion === originalWord) return false;
|
|
46
|
+
if (!replaceTextareaRange(textarea, wordStart, caret, suggestion.expansion + triggerChar)) return false;
|
|
47
|
+
lastExpansion = {
|
|
48
|
+
textarea,
|
|
49
|
+
startOffset: wordStart,
|
|
50
|
+
originalWord,
|
|
51
|
+
triggerChar,
|
|
52
|
+
expansion: suggestion.expansion
|
|
53
|
+
};
|
|
54
|
+
suppressNextExpansion = true;
|
|
55
|
+
return true;
|
|
56
|
+
};
|
|
57
|
+
const tryRestore = textarea => {
|
|
58
|
+
const last = lastExpansion;
|
|
59
|
+
if (!last || last.textarea !== textarea) return false;
|
|
60
|
+
const tail = last.startOffset + last.expansion.length + last.triggerChar.length;
|
|
61
|
+
if (textarea.selectionStart !== tail || textarea.selectionEnd !== tail || textarea.value.slice(last.startOffset, tail) !== last.expansion + last.triggerChar) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (!replaceTextareaRange(textarea, last.startOffset, tail, last.originalWord + last.triggerChar)) return false;
|
|
65
|
+
suppressNextExpansion = true;
|
|
66
|
+
lastExpansion = null;
|
|
67
|
+
return true;
|
|
68
|
+
};
|
|
69
|
+
const applySuggestion = (textarea, context, suggestion, options = {}) => {
|
|
70
|
+
if (suggestion.textEdit) {
|
|
71
|
+
const {
|
|
72
|
+
start,
|
|
73
|
+
end,
|
|
74
|
+
text
|
|
75
|
+
} = suggestion.textEdit;
|
|
76
|
+
if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start || end > textarea.value.length || textarea.value.slice(start, end) === text) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return replaceTextareaRange(textarea, start, end, text);
|
|
80
|
+
}
|
|
81
|
+
const baseText = suggestion.expansion ?? suggestion.text;
|
|
82
|
+
if (baseText === context.text) return false;
|
|
83
|
+
const nextChar = textarea.value[context.end];
|
|
84
|
+
const alreadySeparated = nextChar === " " || nextChar === "\t";
|
|
85
|
+
const opensScope = /[([{]$/.test(baseText);
|
|
86
|
+
const appendSpace = suggestion.appendSpace ?? true;
|
|
87
|
+
const insertText = alreadySeparated || opensScope || !appendSpace ? baseText : `${baseText} `;
|
|
88
|
+
if (!replaceTextareaRange(textarea, context.start, context.end, insertText)) return false;
|
|
89
|
+
if ((options.trackExpansion ?? true) && suggestion.expansion !== undefined && suggestion.expansion !== suggestion.text) {
|
|
90
|
+
lastExpansion = {
|
|
91
|
+
textarea,
|
|
92
|
+
startOffset: context.start,
|
|
93
|
+
originalWord: suggestion.text,
|
|
94
|
+
triggerChar: alreadySeparated || opensScope || !appendSpace ? "" : " ",
|
|
95
|
+
expansion: suggestion.expansion
|
|
96
|
+
};
|
|
97
|
+
suppressNextExpansion = true;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
applySuggestion,
|
|
103
|
+
reset,
|
|
104
|
+
tryExpand,
|
|
105
|
+
tryRestore
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=behaviors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["replaceTextareaRange","suggestSync","TRIGGER_CHARS","WORD_CHAR","findExpansion","word","completions","context","completion","trigger","undefined","suggestions","exact","find","suggestion","text","expansion","normalized","toLowerCase","insensitive","createCompletionBehaviorState","lastExpansion","suppressNextExpansion","reset","tryExpand","textarea","options","length","value","caret","selectionStart","selectionEnd","triggerChar","has","wordEnd","wordStart","test","isExcluded","originalWord","slice","fullText","tokenStart","startOffset","tryRestore","last","tail","applySuggestion","textEdit","start","end","Number","isInteger","baseText","nextChar","alreadySeparated","opensScope","appendSpace","insertText","trackExpansion"],"sources":["inputs/completion/behaviors.ts"],"sourcesContent":["import { replaceTextareaRange } from \"../editor-dom\";\nimport { type Completion, type QueryContext, type SuggestContext, type Suggestion, suggestSync, TRIGGER_CHARS, WORD_CHAR } from \"./engine\";\n\ntype LastExpansion = {\n textarea: HTMLTextAreaElement;\n startOffset: number;\n originalWord: string;\n triggerChar: string;\n expansion: string;\n};\n\nconst findExpansion = (word: string, completions: readonly Completion[], context: SuggestContext): Suggestion | null => {\n for (const completion of completions) {\n if (completion.trigger !== undefined) continue;\n const suggestions = suggestSync(completion, word, context);\n if (!suggestions) continue;\n const exact = suggestions.find((suggestion) => suggestion.text === word && suggestion.expansion && suggestion.expansion !== word);\n if (exact) return exact;\n const normalized = word.toLowerCase();\n const insensitive = suggestions.find(\n (suggestion) => suggestion.text.toLowerCase() === normalized && suggestion.expansion && suggestion.expansion !== word,\n );\n if (insensitive) return insensitive;\n }\n return null;\n};\n\nexport type TryExpandOptions = {\n isExcluded?: (text: string, position: number) => boolean;\n};\n\n/** Keeps abbreviation restoration isolated to one editor instance. */\nexport const createCompletionBehaviorState = () => {\n let lastExpansion: LastExpansion | null = null;\n let suppressNextExpansion = false;\n\n const reset = (): void => {\n lastExpansion = null;\n suppressNextExpansion = false;\n };\n\n const tryExpand = (\n textarea: HTMLTextAreaElement,\n completions: readonly Completion[] | undefined,\n options: TryExpandOptions = {},\n ): boolean => {\n if (suppressNextExpansion) {\n suppressNextExpansion = false;\n return false;\n }\n if (!completions || completions.length === 0) return false;\n\n const value = textarea.value;\n const caret = textarea.selectionStart;\n if (caret === 0 || caret !== textarea.selectionEnd) return false;\n const triggerChar = value[caret - 1];\n if (!triggerChar || !TRIGGER_CHARS.has(triggerChar)) return false;\n\n const wordEnd = caret - 1;\n let wordStart = wordEnd;\n while (wordStart > 0 && WORD_CHAR.test(value[wordStart - 1]!)) wordStart--;\n if (wordStart === wordEnd || options.isExcluded?.(value, wordStart)) return false;\n\n const originalWord = value.slice(wordStart, wordEnd);\n const suggestion = findExpansion(originalWord, completions, {\n fullText: value,\n caret,\n tokenStart: wordStart,\n });\n if (!suggestion?.expansion || suggestion.expansion === originalWord) return false;\n if (!replaceTextareaRange(textarea, wordStart, caret, suggestion.expansion + triggerChar)) return false;\n\n lastExpansion = {\n textarea,\n startOffset: wordStart,\n originalWord,\n triggerChar,\n expansion: suggestion.expansion,\n };\n suppressNextExpansion = true;\n return true;\n };\n\n const tryRestore = (textarea: HTMLTextAreaElement): boolean => {\n const last = lastExpansion;\n if (!last || last.textarea !== textarea) return false;\n const tail = last.startOffset + last.expansion.length + last.triggerChar.length;\n if (\n textarea.selectionStart !== tail ||\n textarea.selectionEnd !== tail ||\n textarea.value.slice(last.startOffset, tail) !== last.expansion + last.triggerChar\n ) {\n return false;\n }\n if (!replaceTextareaRange(textarea, last.startOffset, tail, last.originalWord + last.triggerChar)) return false;\n\n suppressNextExpansion = true;\n lastExpansion = null;\n return true;\n };\n\n const applySuggestion = (\n textarea: HTMLTextAreaElement,\n context: QueryContext,\n suggestion: Suggestion,\n options: { trackExpansion?: boolean } = {},\n ): boolean => {\n if (suggestion.textEdit) {\n const { start, end, text } = suggestion.textEdit;\n if (\n !Number.isInteger(start) ||\n !Number.isInteger(end) ||\n start < 0 ||\n end < start ||\n end > textarea.value.length ||\n textarea.value.slice(start, end) === text\n ) {\n return false;\n }\n return replaceTextareaRange(textarea, start, end, text);\n }\n\n const baseText = suggestion.expansion ?? suggestion.text;\n if (baseText === context.text) return false;\n const nextChar = textarea.value[context.end];\n const alreadySeparated = nextChar === \" \" || nextChar === \"\\t\";\n const opensScope = /[([{]$/.test(baseText);\n const appendSpace = suggestion.appendSpace ?? true;\n const insertText = alreadySeparated || opensScope || !appendSpace ? baseText : `${baseText} `;\n if (!replaceTextareaRange(textarea, context.start, context.end, insertText)) return false;\n\n if ((options.trackExpansion ?? true) && suggestion.expansion !== undefined && suggestion.expansion !== suggestion.text) {\n lastExpansion = {\n textarea,\n startOffset: context.start,\n originalWord: suggestion.text,\n triggerChar: alreadySeparated || opensScope || !appendSpace ? \"\" : \" \",\n expansion: suggestion.expansion,\n };\n suppressNextExpansion = true;\n }\n return true;\n };\n\n return { applySuggestion, reset, tryExpand, tryRestore };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export const TRIGGER_CHARS = new Set([" ", "\t", "\n", ",", ".", "!", "?", ";", ":", ")", "]", "}", '"', "'"]);
|
|
2
|
+
export const WORD_CHAR = /[\p{L}\p{N}_]/u;
|
|
3
|
+
export const GHOST_SENTINEL = String.fromCharCode(0xe010);
|
|
4
|
+
export const abbreviations = dictionary => {
|
|
5
|
+
const suggestions = Object.entries(dictionary).map(([text, expansion]) => ({
|
|
6
|
+
text,
|
|
7
|
+
expansion
|
|
8
|
+
}));
|
|
9
|
+
return {
|
|
10
|
+
knownLabels: suggestions.map(suggestion => suggestion.text),
|
|
11
|
+
suggest: query => {
|
|
12
|
+
if (query === "") return suggestions;
|
|
13
|
+
const normalized = query.toLowerCase();
|
|
14
|
+
return suggestions.filter(suggestion => suggestion.text === query || suggestion.text.toLowerCase().startsWith(normalized)).sort((left, right) => Number(!left.text.startsWith(query)) - Number(!right.text.startsWith(query)));
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export const detectQuery = (textarea, completions, options = {}) => {
|
|
19
|
+
if (!completions || completions.length === 0) return null;
|
|
20
|
+
if (textarea.selectionStart !== textarea.selectionEnd) return null;
|
|
21
|
+
const value = textarea.value;
|
|
22
|
+
const caret = textarea.selectionStart;
|
|
23
|
+
if (caret === 0 || options.isExcluded?.(value, caret)) return null;
|
|
24
|
+
const afterCaret = value[caret];
|
|
25
|
+
if (afterCaret !== undefined && WORD_CHAR.test(afterCaret)) return null;
|
|
26
|
+
let wordStart = caret;
|
|
27
|
+
while (wordStart > 0 && WORD_CHAR.test(value[wordStart - 1])) wordStart--;
|
|
28
|
+
const trigger = wordStart > 0 ? value[wordStart - 1] : undefined;
|
|
29
|
+
if (trigger) {
|
|
30
|
+
const completion = completions.find(candidate => candidate.trigger === trigger);
|
|
31
|
+
if (completion) {
|
|
32
|
+
const beforeTrigger = wordStart >= 2 ? value[wordStart - 2] : undefined;
|
|
33
|
+
if (!beforeTrigger || !WORD_CHAR.test(beforeTrigger) || completion.allowAfterWord) {
|
|
34
|
+
const query = value.slice(wordStart, caret);
|
|
35
|
+
return {
|
|
36
|
+
start: wordStart - 1,
|
|
37
|
+
end: caret,
|
|
38
|
+
text: trigger + query,
|
|
39
|
+
query,
|
|
40
|
+
completion
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (caret > wordStart) {
|
|
46
|
+
const completion = completions.find(candidate => candidate.trigger === undefined);
|
|
47
|
+
if (completion) {
|
|
48
|
+
const query = value.slice(wordStart, caret);
|
|
49
|
+
return {
|
|
50
|
+
start: wordStart,
|
|
51
|
+
end: caret,
|
|
52
|
+
text: query,
|
|
53
|
+
query,
|
|
54
|
+
completion
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
};
|
|
60
|
+
export const resolveSuggestions = (completion, query, context, signal) => {
|
|
61
|
+
const result = completion.suggest(query, context, signal);
|
|
62
|
+
return result instanceof Promise ? {
|
|
63
|
+
kind: "async",
|
|
64
|
+
promise: result
|
|
65
|
+
} : {
|
|
66
|
+
kind: "sync",
|
|
67
|
+
data: result
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export const suggestSync = (completion, query, context) => {
|
|
71
|
+
const controller = new AbortController();
|
|
72
|
+
let result;
|
|
73
|
+
try {
|
|
74
|
+
result = completion.suggest(query, context, controller.signal);
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
if (!(result instanceof Promise)) return result;
|
|
79
|
+
controller.abort();
|
|
80
|
+
void result.catch(() => undefined);
|
|
81
|
+
return null;
|
|
82
|
+
};
|
|
83
|
+
export const pickGhost = (suggestions, typed) => {
|
|
84
|
+
const normalized = typed.toLowerCase();
|
|
85
|
+
return suggestions.find(suggestion => suggestion.text.length > typed.length && suggestion.text.toLowerCase().startsWith(normalized)) ?? null;
|
|
86
|
+
};
|
|
87
|
+
export const collectKnownLabels = completions => {
|
|
88
|
+
const labels = new Set();
|
|
89
|
+
for (const completion of completions ?? []) {
|
|
90
|
+
for (const label of completion.knownLabels ?? []) labels.add(label);
|
|
91
|
+
}
|
|
92
|
+
return labels;
|
|
93
|
+
};
|
|
94
|
+
export const displayLabel = (suggestion, completion) => {
|
|
95
|
+
if (suggestion.label !== undefined) return suggestion.label;
|
|
96
|
+
return completion.trigger && suggestion.text.startsWith(completion.trigger) ? suggestion.text.slice(completion.trigger.length) : suggestion.text;
|
|
97
|
+
};
|
|
98
|
+
export const buildSuggestContext = (textarea, context) => ({
|
|
99
|
+
fullText: textarea.value,
|
|
100
|
+
caret: textarea.selectionStart,
|
|
101
|
+
tokenStart: context.start
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["TRIGGER_CHARS","Set","WORD_CHAR","GHOST_SENTINEL","String","fromCharCode","abbreviations","dictionary","suggestions","Object","entries","map","text","expansion","knownLabels","suggestion","suggest","query","normalized","toLowerCase","filter","startsWith","sort","left","right","Number","detectQuery","textarea","completions","options","length","selectionStart","selectionEnd","value","caret","isExcluded","afterCaret","undefined","test","wordStart","trigger","completion","find","candidate","beforeTrigger","allowAfterWord","slice","start","end","resolveSuggestions","context","signal","result","Promise","kind","promise","data","suggestSync","controller","AbortController","abort","catch","pickGhost","typed","collectKnownLabels","labels","label","add","displayLabel","buildSuggestContext","fullText","tokenStart"],"sources":["inputs/completion/engine.ts"],"sourcesContent":["export type Suggestion = {\n text: string;\n label?: string;\n expansion?: string;\n appendSpace?: boolean;\n hint?: string;\n textEdit?: {\n start: number;\n end: number;\n text: string;\n };\n};\n\nexport type SuggestContext = {\n fullText: string;\n caret: number;\n tokenStart: number;\n};\n\nexport type Completion = {\n trigger?: string;\n suggest: (query: string, context: SuggestContext, signal: AbortSignal) => readonly Suggestion[] | Promise<readonly Suggestion[]>;\n /** Static labels used by editor highlighting. Providers are never invoked to derive metadata. */\n knownLabels?: readonly string[];\n debounceMs?: number;\n dropdown?: boolean;\n allowAfterWord?: boolean;\n};\n\nexport type QueryContext = {\n start: number;\n end: number;\n text: string;\n query: string;\n completion: Completion;\n};\n\nexport type DetectOptions = {\n isExcluded?: (text: string, position: number) => boolean;\n};\n\nexport type ResolveResult = { kind: \"sync\"; data: readonly Suggestion[] } | { kind: \"async\"; promise: Promise<readonly Suggestion[]> };\n\nexport const TRIGGER_CHARS = new Set([\" \", \"\\t\", \"\\n\", \",\", \".\", \"!\", \"?\", \";\", \":\", \")\", \"]\", \"}\", '\"', \"'\"]);\nexport const WORD_CHAR = /[\\p{L}\\p{N}_]/u;\nexport const GHOST_SENTINEL = String.fromCharCode(0xe010);\n\nexport const abbreviations = (dictionary: Record<string, string>): Completion => {\n const suggestions = Object.entries(dictionary).map(([text, expansion]) => ({ text, expansion }));\n return {\n knownLabels: suggestions.map((suggestion) => suggestion.text),\n suggest: (query) => {\n if (query === \"\") return suggestions;\n const normalized = query.toLowerCase();\n return suggestions\n .filter((suggestion) => suggestion.text === query || suggestion.text.toLowerCase().startsWith(normalized))\n .sort((left, right) => Number(!left.text.startsWith(query)) - Number(!right.text.startsWith(query)));\n },\n };\n};\n\nexport const detectQuery = (\n textarea: HTMLTextAreaElement,\n completions: readonly Completion[] | undefined,\n options: DetectOptions = {},\n): QueryContext | null => {\n if (!completions || completions.length === 0) return null;\n if (textarea.selectionStart !== textarea.selectionEnd) return null;\n\n const value = textarea.value;\n const caret = textarea.selectionStart;\n if (caret === 0 || options.isExcluded?.(value, caret)) return null;\n const afterCaret = value[caret];\n if (afterCaret !== undefined && WORD_CHAR.test(afterCaret)) return null;\n\n let wordStart = caret;\n while (wordStart > 0 && WORD_CHAR.test(value[wordStart - 1]!)) wordStart--;\n const trigger = wordStart > 0 ? value[wordStart - 1] : undefined;\n\n if (trigger) {\n const completion = completions.find((candidate) => candidate.trigger === trigger);\n if (completion) {\n const beforeTrigger = wordStart >= 2 ? value[wordStart - 2] : undefined;\n if (!beforeTrigger || !WORD_CHAR.test(beforeTrigger) || completion.allowAfterWord) {\n const query = value.slice(wordStart, caret);\n return {\n start: wordStart - 1,\n end: caret,\n text: trigger + query,\n query,\n completion,\n };\n }\n }\n }\n\n if (caret > wordStart) {\n const completion = completions.find((candidate) => candidate.trigger === undefined);\n if (completion) {\n const query = value.slice(wordStart, caret);\n return { start: wordStart, end: caret, text: query, query, completion };\n }\n }\n return null;\n};\n\nexport const resolveSuggestions = (completion: Completion, query: string, context: SuggestContext, signal: AbortSignal): ResolveResult => {\n const result = completion.suggest(query, context, signal);\n return result instanceof Promise ? { kind: \"async\", promise: result } : { kind: \"sync\", data: result };\n};\n\nexport const suggestSync = (completion: Completion, query: string, context: SuggestContext): readonly Suggestion[] | null => {\n const controller = new AbortController();\n let result: readonly Suggestion[] | Promise<readonly Suggestion[]>;\n try {\n result = completion.suggest(query, context, controller.signal);\n } catch {\n return null;\n }\n if (!(result instanceof Promise)) return result;\n controller.abort();\n void result.catch(() => undefined);\n return null;\n};\n\nexport const pickGhost = (suggestions: readonly Suggestion[], typed: string): Suggestion | null => {\n const normalized = typed.toLowerCase();\n return (\n suggestions.find((suggestion) => suggestion.text.length > typed.length && suggestion.text.toLowerCase().startsWith(normalized)) ?? null\n );\n};\n\nexport const collectKnownLabels = (completions: readonly Completion[] | undefined): Set<string> => {\n const labels = new Set<string>();\n for (const completion of completions ?? []) {\n for (const label of completion.knownLabels ?? []) labels.add(label);\n }\n return labels;\n};\n\nexport const displayLabel = (suggestion: Suggestion, completion: Completion): string => {\n if (suggestion.label !== undefined) return suggestion.label;\n return completion.trigger && suggestion.text.startsWith(completion.trigger)\n ? suggestion.text.slice(completion.trigger.length)\n : suggestion.text;\n};\n\nexport const buildSuggestContext = (textarea: HTMLTextAreaElement, context: QueryContext): SuggestContext => ({\n fullText: textarea.value,\n caret: textarea.selectionStart,\n tokenStart: context.start,\n});\n"],"mappings":"AA2CA,OAAO,MAAMA,aAAa,GAAG,IAAIC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC9G,OAAO,MAAMC,SAAS,GAAG,gBAAgB;AACzC,OAAO,MAAMC,cAAc,GAAGC,MAAM,CAACC,YAAY,CAAC,MAAM,CAAC;AAEzD,OAAO,MAAMC,aAAa,GAAIC,UAAkC,IAAiB;EAC/E,MAAMC,WAAW,GAAGC,MAAM,CAACC,OAAO,CAACH,UAAU,CAAC,CAACI,GAAG,CAAC,CAAC,CAACC,IAAI,EAAEC,SAAS,CAAC,MAAM;IAAED,IAAI;IAAEC;EAAU,CAAC,CAAC,CAAC;EAChG,OAAO;IACLC,WAAW,EAAEN,WAAW,CAACG,GAAG,CAAEI,UAAU,IAAKA,UAAU,CAACH,IAAI,CAAC;IAC7DI,OAAO,EAAGC,KAAK,IAAK;MAClB,IAAIA,KAAK,KAAK,EAAE,EAAE,OAAOT,WAAW;MACpC,MAAMU,UAAU,GAAGD,KAAK,CAACE,WAAW,CAAC,CAAC;MACtC,OAAOX,WAAW,CACfY,MAAM,CAAEL,UAAU,IAAKA,UAAU,CAACH,IAAI,KAAKK,KAAK,IAAIF,UAAU,CAACH,IAAI,CAACO,WAAW,CAAC,CAAC,CAACE,UAAU,CAACH,UAAU,CAAC,CAAC,CACzGI,IAAI,CAAC,CAACC,IAAI,EAAEC,KAAK,KAAKC,MAAM,CAAC,CAACF,IAAI,CAACX,IAAI,CAACS,UAAU,CAACJ,KAAK,CAAC,CAAC,GAAGQ,MAAM,CAAC,CAACD,KAAK,CAACZ,IAAI,CAACS,UAAU,CAACJ,KAAK,CAAC,CAAC,CAAC;IACxG;EACF,CAAC;AACH,CAAC;AAED,OAAO,MAAMS,WAAW,GAAGA,CACzBC,QAA6B,EAC7BC,WAA8C,EAC9CC,OAAsB,GAAG,CAAC,CAAC,KACH;EACxB,IAAI,CAACD,WAAW,IAAIA,WAAW,CAACE,MAAM,KAAK,CAAC,EAAE,OAAO,IAAI;EACzD,IAAIH,QAAQ,CAACI,cAAc,KAAKJ,QAAQ,CAACK,YAAY,EAAE,OAAO,IAAI;EAElE,MAAMC,KAAK,GAAGN,QAAQ,CAACM,KAAK;EAC5B,MAAMC,KAAK,GAAGP,QAAQ,CAACI,cAAc;EACrC,IAAIG,KAAK,KAAK,CAAC,IAAIL,OAAO,CAACM,UAAU,GAAGF,KAAK,EAAEC,KAAK,CAAC,EAAE,OAAO,IAAI;EAClE,MAAME,UAAU,GAAGH,KAAK,CAACC,KAAK,CAAC;EAC/B,IAAIE,UAAU,KAAKC,SAAS,IAAInC,SAAS,CAACoC,IAAI,CAACF,UAAU,CAAC,EAAE,OAAO,IAAI;EAEvE,IAAIG,SAAS,GAAGL,KAAK;EACrB,OAAOK,SAAS,GAAG,CAAC,IAAIrC,SAAS,CAACoC,IAAI,CAACL,KAAK,CAACM,SAAS,GAAG,CAAC,CAAE,CAAC,EAAEA,SAAS,EAAE;EAC1E,MAAMC,OAAO,GAAGD,SAAS,GAAG,CAAC,GAAGN,KAAK,CAACM,SAAS,GAAG,CAAC,CAAC,GAAGF,SAAS;EAEhE,IAAIG,OAAO,EAAE;IACX,MAAMC,UAAU,GAAGb,WAAW,CAACc,IAAI,CAAEC,SAAS,IAAKA,SAAS,CAACH,OAAO,KAAKA,OAAO,CAAC;IACjF,IAAIC,UAAU,EAAE;MACd,MAAMG,aAAa,GAAGL,SAAS,IAAI,CAAC,GAAGN,KAAK,CAACM,SAAS,GAAG,CAAC,CAAC,GAAGF,SAAS;MACvE,IAAI,CAACO,aAAa,IAAI,CAAC1C,SAAS,CAACoC,IAAI,CAACM,aAAa,CAAC,IAAIH,UAAU,CAACI,cAAc,EAAE;QACjF,MAAM5B,KAAK,GAAGgB,KAAK,CAACa,KAAK,CAACP,SAAS,EAAEL,KAAK,CAAC;QAC3C,OAAO;UACLa,KAAK,EAAER,SAAS,GAAG,CAAC;UACpBS,GAAG,EAAEd,KAAK;UACVtB,IAAI,EAAE4B,OAAO,GAAGvB,KAAK;UACrBA,KAAK;UACLwB;QACF,CAAC;MACH;IACF;EACF;EAEA,IAAIP,KAAK,GAAGK,SAAS,EAAE;IACrB,MAAME,UAAU,GAAGb,WAAW,CAACc,IAAI,CAAEC,SAAS,IAAKA,SAAS,CAACH,OAAO,KAAKH,SAAS,CAAC;IACnF,IAAII,UAAU,EAAE;MACd,MAAMxB,KAAK,GAAGgB,KAAK,CAACa,KAAK,CAACP,SAAS,EAAEL,KAAK,CAAC;MAC3C,OAAO;QAAEa,KAAK,EAAER,SAAS;QAAES,GAAG,EAAEd,KAAK;QAAEtB,IAAI,EAAEK,KAAK;QAAEA,KAAK;QAAEwB;MAAW,CAAC;IACzE;EACF;EACA,OAAO,IAAI;AACb,CAAC;AAED,OAAO,MAAMQ,kBAAkB,GAAGA,CAACR,UAAsB,EAAExB,KAAa,EAAEiC,OAAuB,EAAEC,MAAmB,KAAoB;EACxI,MAAMC,MAAM,GAAGX,UAAU,CAACzB,OAAO,CAACC,KAAK,EAAEiC,OAAO,EAAEC,MAAM,CAAC;EACzD,OAAOC,MAAM,YAAYC,OAAO,GAAG;IAAEC,IAAI,EAAE,OAAO;IAAEC,OAAO,EAAEH;EAAO,CAAC,GAAG;IAAEE,IAAI,EAAE,MAAM;IAAEE,IAAI,EAAEJ;EAAO,CAAC;AACxG,CAAC;AAED,OAAO,MAAMK,WAAW,GAAGA,CAAChB,UAAsB,EAAExB,KAAa,EAAEiC,OAAuB,KAAmC;EAC3H,MAAMQ,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;EACxC,IAAIP,MAA8D;EAClE,IAAI;IACFA,MAAM,GAAGX,UAAU,CAACzB,OAAO,CAACC,KAAK,EAAEiC,OAAO,EAAEQ,UAAU,CAACP,MAAM,CAAC;EAChE,CAAC,CAAC,MAAM;IACN,OAAO,IAAI;EACb;EACA,IAAI,EAAEC,MAAM,YAAYC,OAAO,CAAC,EAAE,OAAOD,MAAM;EAC/CM,UAAU,CAACE,KAAK,CAAC,CAAC;EAClB,KAAKR,MAAM,CAACS,KAAK,CAAC,MAAMxB,SAAS,CAAC;EAClC,OAAO,IAAI;AACb,CAAC;AAED,OAAO,MAAMyB,SAAS,GAAGA,CAACtD,WAAkC,EAAEuD,KAAa,KAAwB;EACjG,MAAM7C,UAAU,GAAG6C,KAAK,CAAC5C,WAAW,CAAC,CAAC;EACtC,OACEX,WAAW,CAACkC,IAAI,CAAE3B,UAAU,IAAKA,UAAU,CAACH,IAAI,CAACkB,MAAM,GAAGiC,KAAK,CAACjC,MAAM,IAAIf,UAAU,CAACH,IAAI,CAACO,WAAW,CAAC,CAAC,CAACE,UAAU,CAACH,UAAU,CAAC,CAAC,IAAI,IAAI;AAE3I,CAAC;AAED,OAAO,MAAM8C,kBAAkB,GAAIpC,WAA8C,IAAkB;EACjG,MAAMqC,MAAM,GAAG,IAAIhE,GAAG,CAAS,CAAC;EAChC,KAAK,MAAMwC,UAAU,IAAIb,WAAW,IAAI,EAAE,EAAE;IAC1C,KAAK,MAAMsC,KAAK,IAAIzB,UAAU,CAAC3B,WAAW,IAAI,EAAE,EAAEmD,MAAM,CAACE,GAAG,CAACD,KAAK,CAAC;EACrE;EACA,OAAOD,MAAM;AACf,CAAC;AAED,OAAO,MAAMG,YAAY,GAAGA,CAACrD,UAAsB,EAAE0B,UAAsB,KAAa;EACtF,IAAI1B,UAAU,CAACmD,KAAK,KAAK7B,SAAS,EAAE,OAAOtB,UAAU,CAACmD,KAAK;EAC3D,OAAOzB,UAAU,CAACD,OAAO,IAAIzB,UAAU,CAACH,IAAI,CAACS,UAAU,CAACoB,UAAU,CAACD,OAAO,CAAC,GACvEzB,UAAU,CAACH,IAAI,CAACkC,KAAK,CAACL,UAAU,CAACD,OAAO,CAACV,MAAM,CAAC,GAChDf,UAAU,CAACH,IAAI;AACrB,CAAC;AAED,OAAO,MAAMyD,mBAAmB,GAAGA,CAAC1C,QAA6B,EAAEuB,OAAqB,MAAsB;EAC5GoB,QAAQ,EAAE3C,QAAQ,CAACM,KAAK;EACxBC,KAAK,EAAEP,QAAQ,CAACI,cAAc;EAC9BwC,UAAU,EAAErB,OAAO,CAACH;AACtB,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createCompletionBehaviorState } from "./behaviors";
|
|
2
|
+
export { abbreviations, buildSuggestContext, collectKnownLabels, detectQuery, displayLabel, GHOST_SENTINEL, pickGhost, resolveSuggestions, suggestSync, TRIGGER_CHARS, WORD_CHAR } from "./engine";
|
|
3
|
+
export { plainTextHighlight, renderWithOverlay } from "./overlay";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createCompletionBehaviorState","abbreviations","buildSuggestContext","collectKnownLabels","detectQuery","displayLabel","GHOST_SENTINEL","pickGhost","resolveSuggestions","suggestSync","TRIGGER_CHARS","WORD_CHAR","plainTextHighlight","renderWithOverlay"],"sources":["inputs/completion/index.ts"],"sourcesContent":["export {\n createCompletionBehaviorState,\n type TryExpandOptions,\n} from \"./behaviors\";\nexport {\n abbreviations,\n buildSuggestContext,\n type Completion,\n collectKnownLabels,\n type DetectOptions,\n detectQuery,\n displayLabel,\n GHOST_SENTINEL,\n pickGhost,\n type QueryContext,\n type ResolveResult,\n resolveSuggestions,\n type SuggestContext,\n type Suggestion,\n suggestSync,\n TRIGGER_CHARS,\n WORD_CHAR,\n} from \"./engine\";\nexport {\n plainTextHighlight,\n type RenderOptions,\n renderWithOverlay,\n} from \"./overlay\";\n"],"mappings":"AAAA,SACEA,6BAA6B,QAExB,aAAa;AACpB,SACEC,aAAa,EACbC,mBAAmB,EAEnBC,kBAAkB,EAElBC,WAAW,EACXC,YAAY,EACZC,cAAc,EACdC,SAAS,EAGTC,kBAAkB,EAGlBC,WAAW,EACXC,aAAa,EACbC,SAAS,QACJ,UAAU;AACjB,SACEC,kBAAkB,EAElBC,iBAAiB,QACZ,WAAW","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { GHOST_SENTINEL } from "./engine";
|
|
2
|
+
const ANCHOR_SENTINEL = String.fromCharCode(0xe011);
|
|
3
|
+
const escapeHtml = value => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
4
|
+
export const plainTextHighlight = escapeHtml;
|
|
5
|
+
export const renderWithOverlay = (text, highlighter, options = {}) => {
|
|
6
|
+
const injections = [options.anchor ? {
|
|
7
|
+
at: options.anchor.at,
|
|
8
|
+
marker: ANCHOR_SENTINEL,
|
|
9
|
+
order: 1
|
|
10
|
+
} : undefined, options.ghost ? {
|
|
11
|
+
at: options.ghost.at,
|
|
12
|
+
marker: GHOST_SENTINEL,
|
|
13
|
+
order: 0
|
|
14
|
+
} : undefined].filter(injection => Boolean(injection)).sort((left, right) => right.at - left.at || left.order - right.order);
|
|
15
|
+
const workText = injections.reduce((value, injection) => `${value.slice(0, injection.at)}${injection.marker}${value.slice(injection.at)}`, text);
|
|
16
|
+
let html = highlighter(workText);
|
|
17
|
+
if (options.ghost) {
|
|
18
|
+
html = html.split(GHOST_SENTINEL).join(`<span class="k2b-completion-ghost"${options.anchor ? "" : " data-completion-anchor"}>${escapeHtml(options.ghost.text)}<span class="k2b-completion-ghost__arrow" aria-hidden="true">→</span></span>`);
|
|
19
|
+
}
|
|
20
|
+
if (options.anchor) {
|
|
21
|
+
html = html.split(ANCHOR_SENTINEL).join('<span class="k2b-completion-anchor" data-completion-anchor aria-hidden="true">\u200b</span>');
|
|
22
|
+
}
|
|
23
|
+
return html;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["GHOST_SENTINEL","ANCHOR_SENTINEL","String","fromCharCode","escapeHtml","value","replace","plainTextHighlight","renderWithOverlay","text","highlighter","options","injections","anchor","at","marker","order","undefined","ghost","filter","injection","Boolean","sort","left","right","workText","reduce","slice","html","split","join"],"sources":["inputs/completion/overlay.ts"],"sourcesContent":["import { GHOST_SENTINEL } from \"./engine\";\n\nconst ANCHOR_SENTINEL = String.fromCharCode(0xe011);\n\nconst escapeHtml = (value: string): string =>\n value.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\").replace(/'/g, \"'\");\n\nexport const plainTextHighlight = escapeHtml;\n\nexport type RenderOptions = {\n ghost?: { at: number; text: string };\n anchor?: { at: number };\n};\n\nexport const renderWithOverlay = (text: string, highlighter: (text: string) => string, options: RenderOptions = {}): string => {\n const injections = [\n options.anchor ? { at: options.anchor.at, marker: ANCHOR_SENTINEL, order: 1 } : undefined,\n options.ghost ? { at: options.ghost.at, marker: GHOST_SENTINEL, order: 0 } : undefined,\n ]\n .filter((injection): injection is { at: number; marker: string; order: number } => Boolean(injection))\n .sort((left, right) => right.at - left.at || left.order - right.order);\n const workText = injections.reduce(\n (value, injection) => `${value.slice(0, injection.at)}${injection.marker}${value.slice(injection.at)}`,\n text,\n );\n let html = highlighter(workText);\n if (options.ghost) {\n html = html\n .split(GHOST_SENTINEL)\n .join(\n `<span class=\"k2b-completion-ghost\"${options.anchor ? \"\" : \" data-completion-anchor\"}>${escapeHtml(options.ghost.text)}<span class=\"k2b-completion-ghost__arrow\" aria-hidden=\"true\">→</span></span>`,\n );\n }\n if (options.anchor) {\n html = html.split(ANCHOR_SENTINEL).join('<span class=\"k2b-completion-anchor\" data-completion-anchor aria-hidden=\"true\">\\u200b</span>');\n }\n return html;\n};\n"],"mappings":"AAAA,SAASA,cAAc,QAAQ,UAAU;AAEzC,MAAMC,eAAe,GAAGC,MAAM,CAACC,YAAY,CAAC,MAAM,CAAC;AAEnD,MAAMC,UAAU,GAAIC,KAAa,IAC/BA,KAAK,CAACC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;AAEzH,OAAO,MAAMC,kBAAkB,GAAGH,UAAU;AAO5C,OAAO,MAAMI,iBAAiB,GAAGA,CAACC,IAAY,EAAEC,WAAqC,EAAEC,OAAsB,GAAG,CAAC,CAAC,KAAa;EAC7H,MAAMC,UAAU,GAAG,CACjBD,OAAO,CAACE,MAAM,GAAG;IAAEC,EAAE,EAAEH,OAAO,CAACE,MAAM,CAACC,EAAE;IAAEC,MAAM,EAAEd,eAAe;IAAEe,KAAK,EAAE;EAAE,CAAC,GAAGC,SAAS,EACzFN,OAAO,CAACO,KAAK,GAAG;IAAEJ,EAAE,EAAEH,OAAO,CAACO,KAAK,CAACJ,EAAE;IAAEC,MAAM,EAAEf,cAAc;IAAEgB,KAAK,EAAE;EAAE,CAAC,GAAGC,SAAS,CACvF,CACEE,MAAM,CAAEC,SAAS,IAAiEC,OAAO,CAACD,SAAS,CAAC,CAAC,CACrGE,IAAI,CAAC,CAACC,IAAI,EAAEC,KAAK,KAAKA,KAAK,CAACV,EAAE,GAAGS,IAAI,CAACT,EAAE,IAAIS,IAAI,CAACP,KAAK,GAAGQ,KAAK,CAACR,KAAK,CAAC;EACxE,MAAMS,QAAQ,GAAGb,UAAU,CAACc,MAAM,CAChC,CAACrB,KAAK,EAAEe,SAAS,KAAK,GAAGf,KAAK,CAACsB,KAAK,CAAC,CAAC,EAAEP,SAAS,CAACN,EAAE,CAAC,GAAGM,SAAS,CAACL,MAAM,GAAGV,KAAK,CAACsB,KAAK,CAACP,SAAS,CAACN,EAAE,CAAC,EAAE,EACtGL,IACF,CAAC;EACD,IAAImB,IAAI,GAAGlB,WAAW,CAACe,QAAQ,CAAC;EAChC,IAAId,OAAO,CAACO,KAAK,EAAE;IACjBU,IAAI,GAAGA,IAAI,CACRC,KAAK,CAAC7B,cAAc,CAAC,CACrB8B,IAAI,CACH,qCAAqCnB,OAAO,CAACE,MAAM,GAAG,EAAE,GAAG,yBAAyB,IAAIT,UAAU,CAACO,OAAO,CAACO,KAAK,CAACT,IAAI,CAAC,8EACxH,CAAC;EACL;EACA,IAAIE,OAAO,CAACE,MAAM,EAAE;IAClBe,IAAI,GAAGA,IAAI,CAACC,KAAK,CAAC5B,eAAe,CAAC,CAAC6B,IAAI,CAAC,6FAA6F,CAAC;EACxI;EACA,OAAOF,IAAI;AACb,CAAC","ignoreList":[]}
|