@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 @@
|
|
|
1
|
+
{"version":3,"names":["mutation","createEffect","createMemo","createResource","createSignal","For","Match","onCleanup","Show","Switch","untrack","toast","MarkdownEditor","useUiMessages","Placeholder","CodeDisplay","fileViewExtension","getFileViewPreviewKind","parseDelimitedText","MarkdownView","StructuredDataPreview","canPreviewFile","codeLanguage","path","extension","isMarkdown","file","content","encoding","mediaType","stripFrontmatter","text","match","exec","trimStart","slice","length","OverlayAction","props","classes","_$createComponent","when","href","fallback","_$ssr","_tmpl$","_$ssrAttribute","_$escape","title","icon","children","_tmpl$2","download","OverlayPanel","_tmpl$4","actions","_tmpl$3","DownloadAction","messages","downloadHref","lastIndexOf","EditorToolButton","_tmpl$5","disabled","MarkdownRenderer","editing","setEditing","editor","edit","onClick","_tmpl$6","markdown","draft","headingScale","_","_tmpl$7","aria-label","fill","value","onValueChange","setDraft","showStats","onSave","save","saveDisabled","dirty","saving","toolbarTrailing","preview","TextRenderer","code","language","_tmpl$8","textEditor","_tmpl$9","saveShortcut","JsonRenderer","parsed","ok","JSON","parse","parsedValue","result","data","maxRows","DelimitedTextRenderer","delimiter","headers","rows","emptyFile","description","delimitedFileEmpty","_tmpl$1","each","header","index","_tmpl$10","column","number","row","_tmpl$11","_tmpl$12","truncated","_tmpl$0","previewLimited","mediaSource","previewHref","ImageRenderer","_tmpl$13","PdfRenderer","noInlinePreview","_tmpl$14","AudioRenderer","_tmpl$15","audioUnsupported","VideoRenderer","_tmpl$16","videoUnsupported","BinaryRenderer","noPreview","binaryFile","action","_tmpl$17","BUILTIN_RENDERERS","id","component","editable","_file","formatFileViewSize","bytes","toFixed","FileView","savedDraft","setSavedDraft","nativeRevision","setNativeRevision","instanceRenderers","renderers","saveMutation","create","input","onSuccess","saved","success","fileSaved","onError","error","message","nativePreviewHref","kind","separator","includes","browserPreviewContent","candidate","some","renderer","refetch","revision","abort","loaded","load","loadedDraft","registerRefresh","unregister","resolvedContent","find","onDirtyChange","loading","mutate","_tmpl$18","class","undefined","failedLoadFile","String","active","Renderer"],"sources":["content/FileView.tsx"],"sourcesContent":["/**\n * FileView — renders one file through a small renderer registry keyed by\n * media type / path. Editing is enabled purely by the presence of `save`;\n * without it every renderer is read-only. IDE-style chrome: editors reuse\n * the markdown editor's surface (toolbar with an in-toolbar save, Ctrl/Cmd+S),\n * previews are quiet paper panels with icon-only actions overlaid top-right.\n * Custom renderers are passed per instance, which keeps SSR requests and\n * independently mounted applications isolated.\n */\n\nimport { mutation } from \"@k2b/stdlib/solid\";\nimport {\n type Component,\n createEffect,\n createMemo,\n createResource,\n createSignal,\n For,\n type JSX,\n Match,\n onCleanup,\n Show,\n Switch,\n untrack,\n} from \"solid-js\";\nimport { toast } from \"../feedback/toast\";\nimport { MarkdownEditor } from \"../inputs/markdown/MarkdownEditor\";\nimport { useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport CodeDisplay, { type CodeDisplayLanguage } from \"./CodeDisplay\";\nimport { type FileViewFile, fileViewExtension, getFileViewPreviewKind, parseDelimitedText } from \"./file-view-preview\";\nimport MarkdownView from \"./MarkdownView\";\nimport StructuredDataPreview, { type StructuredDataValue } from \"./StructuredDataPreview\";\n\nexport type { FileViewFile, FileViewPreviewKind } from \"./file-view-preview\";\nexport { canPreviewFile, getFileViewPreviewKind } from \"./file-view-preview\";\nexport type FileViewContent = { encoding: \"utf8\" | \"base64\"; content: string; mediaType: string };\n\nexport type FileViewProps = {\n file: FileViewFile;\n load: () => Promise<FileViewContent>;\n /** Refetch the current path when this host-owned revision changes. */\n revision?: unknown;\n /** Register an awaitable refresh for the currently visible preview. */\n registerRefresh?: (refresh: () => Promise<void>) => void | (() => void);\n /** Presence enables editing for text-based renderers. */\n save?: (content: string) => Promise<void>;\n /** Authenticated inline URL used by browser-native image, PDF, audio, and video previews. */\n previewHref?: string | null;\n downloadHref?: string | null;\n /** App-specific renderers matched before the built-ins for this instance. */\n renderers?: readonly FileViewRenderer[];\n /** Reports local edit state so a parent browser can guard navigation. */\n onDirtyChange?: (dirty: boolean) => void;\n class?: string;\n};\n\nexport type FileViewRendererProps = {\n file: FileViewFile;\n content: FileViewContent;\n previewHref: string | null;\n downloadHref: string | null;\n /** Null when the file is read-only. */\n editor: {\n draft: () => string;\n setDraft: (value: string) => void;\n dirty: () => boolean;\n saving: () => boolean;\n save: () => Promise<void>;\n } | null;\n};\n\nexport type FileViewRenderer = {\n id: string;\n match: (file: FileViewFile, content: FileViewContent) => boolean;\n component: Component<FileViewRendererProps>;\n /** Text renderers that support the edit affordance when `save` is present. */\n editable?: boolean;\n};\n\nconst codeLanguage = (path: string): CodeDisplayLanguage => {\n const extension = fileViewExtension(path);\n if (extension === \"ts\" || extension === \"mts\" || extension === \"cts\") return \"ts\";\n if (extension === \"tsx\") return \"tsx\";\n if (extension === \"js\" || extension === \"mjs\" || extension === \"cjs\") return \"js\";\n if (extension === \"jsx\") return \"jsx\";\n if (extension === \"md\" || extension === \"markdown\") return \"md\";\n return \"text\";\n};\n\nconst isMarkdown = (file: FileViewFile, content: FileViewContent) =>\n content.encoding === \"utf8\" && getFileViewPreviewKind({ ...file, mediaType: content.mediaType || file.mediaType }) === \"markdown\";\n\n/** Rendered previews hide a leading YAML frontmatter block — it's metadata, not content. */\nconst stripFrontmatter = (text: string): string => {\n const match = /^---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n?/.exec(text.trimStart());\n return match ? text.trimStart().slice(match[0].length) : text;\n};\n\n/** Icon-only action, IDE style — sits in the floating top-right cluster of previews. */\nfunction OverlayAction(props: { icon: string; title: string; onClick?: () => void; href?: string; download?: string }) {\n const classes = \"k2b-content-file-view__action\";\n return (\n <Show\n when={props.href}\n fallback={\n <button type=\"button\" class={classes} title={props.title} aria-label={props.title} onClick={props.onClick}>\n <i class={`ti ${props.icon}`} aria-hidden=\"true\" />\n </button>\n }\n >\n {(href) => (\n <a class={classes} href={href()} download={props.download ?? \"\"} title={props.title} aria-label={props.title}>\n <i class={`ti ${props.icon}`} aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{props.title}</span>\n </a>\n )}\n </Show>\n );\n}\n\n/** Scrollable preview panel with the floating action cluster overlaid top-right. */\nfunction OverlayPanel(props: { actions?: JSX.Element; children: JSX.Element }) {\n return (\n <div class=\"k2b-content-file-view__panel\">\n <div class=\"k2b-content-file-view__preview\">{props.children}</div>\n <Show when={props.actions}>\n <div class=\"k2b-content-file-view__overlay\">{props.actions}</div>\n </Show>\n </div>\n );\n}\n\nconst DownloadAction = (props: FileViewRendererProps): JSX.Element => {\n const messages = useUiMessages();\n return (\n <Show when={props.downloadHref}>\n {(href) => (\n <OverlayAction\n icon=\"ti-download\"\n title={messages().download}\n href={href()}\n download={props.file.path.slice(props.file.path.lastIndexOf(\"/\") + 1)}\n />\n )}\n </Show>\n );\n};\n\n/** Toolbar-styled icon button — reuses the package markdown-editor tool primitive. */\nfunction EditorToolButton(props: { icon: string; title: string; onClick: () => void; disabled?: boolean }) {\n return (\n <button\n type=\"button\"\n class=\"k2b-markdown-editor__tool\"\n title={props.title}\n aria-label={props.title}\n tabIndex={-1}\n disabled={props.disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={props.onClick}\n >\n <i class={props.icon} />\n </button>\n );\n}\n\n// ── Built-in renderers ──────────────────────────────────────────────────────\n\nfunction MarkdownRenderer(props: FileViewRendererProps) {\n const messages = useUiMessages();\n const [editing, setEditing] = createSignal(false);\n return (\n <Show\n when={props.editor && editing()}\n fallback={\n <OverlayPanel\n actions={\n <>\n <Show when={props.editor}>\n <OverlayAction icon=\"ti-pencil\" title={messages().edit} onClick={() => setEditing(true)} />\n </Show>\n <DownloadAction {...props} />\n </>\n }\n >\n <div class=\"k2b-content-file-view__document\">\n <MarkdownView markdown={stripFrontmatter(props.editor?.draft() ?? props.content.content)} headingScale=\"compact\" />\n </div>\n </OverlayPanel>\n }\n >\n {(_) => {\n const editor = props.editor!;\n return (\n <div class=\"k2b-content-file-view__editor\">\n <MarkdownEditor\n class=\"k2b-content-file-view__markdown-field\"\n aria-label={`Edit ${props.file.path.slice(props.file.path.lastIndexOf(\"/\") + 1)}`}\n fill\n value={editor.draft()}\n onValueChange={editor.setDraft}\n showStats={false}\n onSave={() => void editor.save()}\n saveDisabled={!editor.dirty()}\n saving={editor.saving()}\n toolbarTrailing={<EditorToolButton icon=\"ti ti-eye\" title={messages().preview} onClick={() => setEditing(false)} />}\n />\n </div>\n );\n }}\n </Show>\n );\n}\n\nfunction TextRenderer(props: FileViewRendererProps) {\n const messages = useUiMessages();\n return (\n <Show\n when={props.editor}\n fallback={\n <OverlayPanel actions={<DownloadAction {...props} />}>\n <CodeDisplay code={props.content.content} language={codeLanguage(props.file.path)} />\n </OverlayPanel>\n }\n >\n {(editor) => (\n // Same chrome as the markdown editor — literally the same classes, so\n // border, radius, focus ring, toolbar height and text metrics cannot drift.\n <div class=\"k2b-content-file-view__editor\">\n <div\n class=\"k2b-markdown-editor\"\n data-fill=\"true\"\n role=\"group\"\n aria-label={messages().textEditor}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"s\") {\n event.preventDefault();\n if (editor().dirty() && !editor().saving()) void editor().save();\n }\n }}\n >\n {/* No formatting tools here — the divider under an actions-only bar reads lost. */}\n <div class=\"k2b-markdown-editor__toolbar k2b-content-file-view__code-toolbar\">\n <span class=\"k2b-content-file-view__code-language\">{codeLanguage(props.file.path)}</span>\n <span class=\"k2b-markdown-editor__trailing\">\n <Show when={props.downloadHref}>\n {(href) => (\n <a\n class=\"k2b-markdown-editor__tool\"\n href={href()}\n download={props.file.path.slice(props.file.path.lastIndexOf(\"/\") + 1)}\n title={messages().download}\n aria-label={messages().download}\n >\n <i class=\"ti ti-download\" />\n </a>\n )}\n </Show>\n <EditorToolButton\n icon={editor().saving() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-device-floppy\"}\n title={messages().saveShortcut}\n disabled={!editor().dirty() || editor().saving()}\n onClick={() => void editor().save()}\n />\n </span>\n </div>\n <div class=\"k2b-markdown-editor__surface\">\n <textarea\n class=\"k2b-content-file-view__code-input\"\n value={editor().draft()}\n spellcheck={false}\n onInput={(event) => editor().setDraft(event.currentTarget.value)}\n />\n </div>\n </div>\n </div>\n )}\n </Show>\n );\n}\n\nfunction JsonRenderer(props: FileViewRendererProps) {\n const parsed = createMemo(() => {\n try {\n return { ok: true as const, value: JSON.parse(props.content.content) as StructuredDataValue };\n } catch {\n return { ok: false as const };\n }\n });\n const parsedValue = (): StructuredDataValue => {\n const result = parsed();\n return result.ok ? result.value : null;\n };\n\n return (\n <OverlayPanel actions={<DownloadAction {...props} />}>\n <div class=\"k2b-content-file-view__document\">\n <Show when={parsed().ok} fallback={<CodeDisplay code={props.content.content} language=\"text\" />}>\n <StructuredDataPreview data={parsedValue()} maxRows={200} />\n </Show>\n </div>\n </OverlayPanel>\n );\n}\n\nfunction DelimitedTextRenderer(props: FileViewRendererProps) {\n const messages = useUiMessages();\n const delimiter = () =>\n fileViewExtension(props.file.path) === \"tsv\" || props.content.mediaType === \"text/tab-separated-values\" ? \"\\t\" : \",\";\n const preview = createMemo(() => parseDelimitedText(props.content.content, delimiter()));\n const headers = createMemo(() => preview().rows[0] ?? []);\n const rows = createMemo(() => preview().rows.slice(1));\n\n return (\n <OverlayPanel actions={<DownloadAction {...props} />}>\n <Show\n when={headers().length > 0}\n fallback={<Placeholder icon=\"ti ti-table\" title={messages().emptyFile} description={messages().delimitedFileEmpty} />}\n >\n <div class=\"k2b-content-file-view__sheet\">\n <table class=\"k2b-content-file-view__table\">\n <thead>\n <tr>\n <For each={headers()}>\n {(header, index) => (\n <th scope=\"col\">\n <span>{header || messages().column({ number: index() + 1 })}</span>\n </th>\n )}\n </For>\n </tr>\n </thead>\n <tbody>\n <For each={rows()}>\n {(row) => (\n <tr>\n <For each={headers()}>{(_, index) => <td>{row[index()] ?? \"\"}</td>}</For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n <Show when={preview().truncated}>\n <p class=\"k2b-content-file-view__truncated\">{messages().previewLimited}</p>\n </Show>\n </div>\n </Show>\n </OverlayPanel>\n );\n}\n\nconst mediaSource = (props: FileViewRendererProps): string =>\n props.previewHref ?? `data:${props.content.mediaType};base64,${props.content.content}`;\n\nfunction ImageRenderer(props: FileViewRendererProps) {\n return (\n <OverlayPanel actions={<DownloadAction {...props} />}>\n <div class=\"k2b-content-file-view__media\">\n <img src={mediaSource(props)} alt={props.file.path} />\n </div>\n </OverlayPanel>\n );\n}\n\nfunction PdfRenderer(props: FileViewRendererProps) {\n const messages = useUiMessages();\n const href = () => props.previewHref ?? props.downloadHref;\n return (\n <Show when={href()} fallback={<Placeholder icon=\"ti ti-file-type-pdf\" title=\"PDF\" description={messages().noInlinePreview} />}>\n {(href) => <object data={href()} type=\"application/pdf\" class=\"k2b-content-file-view__pdf\" aria-label={props.file.path} />}\n </Show>\n );\n}\n\nfunction AudioRenderer(props: FileViewRendererProps) {\n const messages = useUiMessages();\n return (\n <OverlayPanel actions={<DownloadAction {...props} />}>\n <div class=\"k2b-content-file-view__media\" data-kind=\"audio\">\n <audio controls preload=\"metadata\" src={mediaSource(props)} aria-label={props.file.path}>\n {messages().audioUnsupported}\n </audio>\n </div>\n </OverlayPanel>\n );\n}\n\nfunction VideoRenderer(props: FileViewRendererProps) {\n const messages = useUiMessages();\n return (\n <OverlayPanel actions={<DownloadAction {...props} />}>\n <div class=\"k2b-content-file-view__media\" data-kind=\"video\">\n <video controls preload=\"metadata\" playsinline src={mediaSource(props)} aria-label={props.file.path}>\n {messages().videoUnsupported}\n </video>\n </div>\n </OverlayPanel>\n );\n}\n\nfunction BinaryRenderer(props: FileViewRendererProps) {\n const messages = useUiMessages();\n return (\n <Placeholder\n icon=\"ti ti-file-unknown\"\n title={messages().noPreview}\n description={props.content.mediaType || messages().binaryFile}\n action={\n <Show when={props.downloadHref}>\n {(href) => (\n <a class=\"k2b-button\" data-variant=\"secondary\" data-size=\"sm\" href={href()} download=\"\">\n <i class=\"ti ti-download\" aria-hidden=\"true\" />\n {messages().download}\n </a>\n )}\n </Show>\n }\n />\n );\n}\n\nconst BUILTIN_RENDERERS: FileViewRenderer[] = [\n { id: \"markdown\", match: isMarkdown, component: MarkdownRenderer, editable: true },\n {\n id: \"image\",\n match: (file, content) => getFileViewPreviewKind({ ...file, mediaType: content.mediaType || file.mediaType }) === \"image\",\n component: ImageRenderer,\n },\n {\n id: \"pdf\",\n match: (file, content) => getFileViewPreviewKind({ ...file, mediaType: content.mediaType || file.mediaType }) === \"pdf\",\n component: PdfRenderer,\n },\n {\n id: \"json\",\n match: (file, content) =>\n content.encoding === \"utf8\" && getFileViewPreviewKind({ ...file, mediaType: content.mediaType || file.mediaType }) === \"json\",\n component: JsonRenderer,\n },\n {\n id: \"delimited-text\",\n match: (file, content) =>\n content.encoding === \"utf8\" &&\n getFileViewPreviewKind({ ...file, mediaType: content.mediaType || file.mediaType }) === \"delimited-text\",\n component: DelimitedTextRenderer,\n },\n {\n id: \"audio\",\n match: (file, content) => getFileViewPreviewKind({ ...file, mediaType: content.mediaType || file.mediaType }) === \"audio\",\n component: AudioRenderer,\n },\n {\n id: \"video\",\n match: (file, content) => getFileViewPreviewKind({ ...file, mediaType: content.mediaType || file.mediaType }) === \"video\",\n component: VideoRenderer,\n },\n { id: \"text\", match: (_file, content) => content.encoding === \"utf8\", component: TextRenderer, editable: true },\n { id: \"binary\", match: () => true, component: BinaryRenderer },\n];\n\n// ── Component ───────────────────────────────────────────────────────────────\n\nexport const formatFileViewSize = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n};\n\nexport default function FileView(props: FileViewProps) {\n const messages = useUiMessages();\n const [draft, setDraft] = createSignal(\"\");\n const [savedDraft, setSavedDraft] = createSignal(\"\");\n const [nativeRevision, setNativeRevision] = createSignal(0);\n const dirty = createMemo(() => draft() !== savedDraft());\n const instanceRenderers = () => props.renderers ?? [];\n const saveMutation = mutation.create<{ path: string; content: string }, { path: string; content: string }>({\n mutation: async (input) => {\n await props.save!(input.content);\n return input;\n },\n onSuccess: (saved) => {\n if (props.file.path === saved.path) setSavedDraft(saved.content);\n toast.success(messages().fileSaved);\n },\n onError: (error) => toast.error(error.message),\n });\n const nativePreviewHref = createMemo(() => {\n const kind = getFileViewPreviewKind(props.file);\n const href = props.previewHref ?? (kind === \"pdf\" ? props.downloadHref : null);\n if (!href) return null;\n const separator = href.includes(\"?\") ? \"&\" : \"?\";\n return `${href}${separator}preview-revision=${nativeRevision()}`;\n });\n const browserPreviewContent = createMemo<FileViewContent | null>(() => {\n const kind = getFileViewPreviewKind(props.file);\n if (kind !== \"image\" && kind !== \"pdf\" && kind !== \"audio\" && kind !== \"video\") return null;\n const href = nativePreviewHref();\n if (!href) return null;\n\n const candidate: FileViewContent = {\n encoding: \"base64\",\n content: \"\",\n mediaType: props.file.mediaType ?? \"application/octet-stream\",\n };\n return instanceRenderers().some((renderer) => renderer.match(props.file, candidate)) ? null : candidate;\n });\n const [content, { refetch }] = createResource(\n () => (browserPreviewContent() ? null : { path: props.file.path, revision: props.revision }),\n async () => {\n saveMutation.abort();\n // `load` is an imperative source adapter. Host signal reads inside it\n // must not turn this resource into a hidden reactive feedback loop.\n const loaded = await untrack(() => props.load());\n const loadedDraft = loaded.encoding === \"utf8\" ? loaded.content : \"\";\n setDraft(loadedDraft);\n setSavedDraft(loadedDraft);\n return loaded;\n },\n );\n createEffect(() => {\n if (!props.registerRefresh) return;\n const unregister = props.registerRefresh(async () => {\n if (browserPreviewContent()) setNativeRevision((value) => value + 1);\n else await refetch();\n });\n if (unregister) onCleanup(unregister);\n });\n const resolvedContent = createMemo(() => browserPreviewContent() ?? content());\n\n const renderer = createMemo(() => {\n const loaded = resolvedContent();\n if (!loaded) return null;\n return [...instanceRenderers(), ...BUILTIN_RENDERERS].find((candidate) => candidate.match(props.file, loaded)) ?? null;\n });\n\n createEffect(() => {\n props.onDirtyChange?.(dirty());\n });\n\n const save = async () => {\n if (!props.save || saveMutation.loading()) return;\n await saveMutation.mutate({ path: props.file.path, content: draft() });\n };\n\n const editor = () =>\n props.save && renderer()?.editable && resolvedContent()?.encoding === \"utf8\"\n ? {\n draft,\n setDraft,\n dirty,\n saving: saveMutation.loading,\n save,\n }\n : null;\n\n return (\n <div class={`k2b-content-file-view ${props.class ?? \"\"}`}>\n <Switch>\n <Match when={content.loading && content() === undefined}>\n <Placeholder icon=\"ti ti-loader-2\" title={messages().loading} />\n </Match>\n <Match when={content.error}>\n <Placeholder icon=\"ti ti-alert-circle\" title={messages().failedLoadFile} description={String(content.error?.message ?? \"\")} />\n </Match>\n <Match when={resolvedContent() && renderer()}>\n {(active) => {\n const Renderer = active().component;\n return (\n <Renderer\n file={props.file}\n content={resolvedContent()!}\n previewHref={nativePreviewHref()}\n downloadHref={props.downloadHref ?? null}\n editor={editor()}\n />\n );\n }}\n </Match>\n </Switch>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
2
|
+
import { ssr as _$ssr } from "solid-js/web";
|
|
3
|
+
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
4
|
+
import { escape as _$escape } from "solid-js/web";
|
|
5
|
+
var _tmpl$ = ["<span class=\"k2b-content-lightbox__counter\" aria-live=\"polite\">", " / ", "</span>"],
|
|
6
|
+
_tmpl$2 = ["<div class=\"k2b-content-lightbox__caption\"><div class=\"k2b-content-lightbox__caption-text\">", "</div></div>"],
|
|
7
|
+
_tmpl$3 = ["<a", " download class=\"k2b-content-lightbox__button\"", "><i class=\"ti ti-download\" aria-hidden=\"true\"></i><span class=\"k2b-content-lightbox__button-label\">", "</span></a>"],
|
|
8
|
+
_tmpl$4 = ["<button type=\"button\" class=\"k2b-content-lightbox__nav\" data-direction=\"previous\"", "><i class=\"ti ti-chevron-left\" aria-hidden=\"true\"></i></button>"],
|
|
9
|
+
_tmpl$5 = ["<button type=\"button\" class=\"k2b-content-lightbox__nav\" data-direction=\"next\"", "><i class=\"ti ti-chevron-right\" aria-hidden=\"true\"></i></button>"],
|
|
10
|
+
_tmpl$6 = ["<div class=\"k2b-content-lightbox__dots\" role=\"group\"", ">", "</div>"],
|
|
11
|
+
_tmpl$7 = ["<dialog class=\"k2b-content-lightbox\"", "><div class=\"k2b-content-lightbox__bar\"><div class=\"k2b-content-lightbox__meta\">", "", "</div><div class=\"k2b-content-lightbox__actions\">", "<button type=\"button\" class=\"k2b-content-lightbox__button\"", "><i class=\"ti ti-x\" aria-hidden=\"true\"></i><span class=\"k2b-content-lightbox__button-label\">", "</span></button></div></div><div class=\"k2b-content-lightbox__stage\">", "</div>", "", "</dialog>"],
|
|
12
|
+
_tmpl$8 = ["<img", " class=\"k2b-content-lightbox__image\" draggable=\"false\">"],
|
|
13
|
+
_tmpl$9 = ["<button type=\"button\" class=\"k2b-content-lightbox__dot\"", "></button>"];
|
|
14
|
+
import { createEffect, createSignal, For, onCleanup, onMount, Show } from "solid-js";
|
|
15
|
+
import { useUiMessages } from "../intl/messages";
|
|
16
|
+
/**
|
|
17
|
+
* Minimal, accessible lightbox using native <dialog>.
|
|
18
|
+
* Supports keyboard navigation, touch swipe gestures, and screen readers.
|
|
19
|
+
*/
|
|
20
|
+
export default function Lightbox(props) {
|
|
21
|
+
const messages = useUiMessages();
|
|
22
|
+
const clampIndex = (value, images = props.images) => images.length === 0 ? 0 : Math.max(0, Math.min(value, images.length - 1));
|
|
23
|
+
const [index, setIndex] = createSignal(clampIndex(props.initialIndex ?? 0));
|
|
24
|
+
let dialogRef;
|
|
25
|
+
createEffect(previous => {
|
|
26
|
+
const images = props.images;
|
|
27
|
+
const initialIndex = props.initialIndex;
|
|
28
|
+
setIndex(currentIndex => {
|
|
29
|
+
if (initialIndex !== previous.initialIndex) return clampIndex(initialIndex ?? 0, images);
|
|
30
|
+
const previousImage = previous.images[currentIndex];
|
|
31
|
+
const retained = previousImage ? images.findIndex(image => image === previousImage || image.src === previousImage.src) : -1;
|
|
32
|
+
return retained >= 0 ? retained : clampIndex(currentIndex, images);
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
images,
|
|
36
|
+
initialIndex
|
|
37
|
+
};
|
|
38
|
+
}, {
|
|
39
|
+
images: props.images,
|
|
40
|
+
initialIndex: props.initialIndex
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Touch gesture tracking
|
|
44
|
+
let touchStartX = 0;
|
|
45
|
+
let touchStartY = 0;
|
|
46
|
+
const SWIPE_THRESHOLD = 50;
|
|
47
|
+
const current = () => props.images[index()];
|
|
48
|
+
const isMultiple = () => props.images.length > 1;
|
|
49
|
+
const prev = () => {
|
|
50
|
+
if (!isMultiple()) return;
|
|
51
|
+
setIndex(i => (i - 1 + props.images.length) % props.images.length);
|
|
52
|
+
};
|
|
53
|
+
const next = () => {
|
|
54
|
+
if (!isMultiple()) return;
|
|
55
|
+
setIndex(i => (i + 1) % props.images.length);
|
|
56
|
+
};
|
|
57
|
+
const close = () => {
|
|
58
|
+
dialogRef.close();
|
|
59
|
+
props.onClose();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Keyboard navigation
|
|
63
|
+
const handleKeyDown = e => {
|
|
64
|
+
switch (e.key) {
|
|
65
|
+
case "Escape":
|
|
66
|
+
close();
|
|
67
|
+
break;
|
|
68
|
+
case "ArrowLeft":
|
|
69
|
+
prev();
|
|
70
|
+
break;
|
|
71
|
+
case "ArrowRight":
|
|
72
|
+
next();
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Touch handlers for swipe gestures
|
|
78
|
+
const handleTouchStart = e => {
|
|
79
|
+
const touch = e.touches[0];
|
|
80
|
+
if (touch) {
|
|
81
|
+
touchStartX = touch.clientX;
|
|
82
|
+
touchStartY = touch.clientY;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const handleTouchEnd = e => {
|
|
86
|
+
const touch = e.changedTouches[0];
|
|
87
|
+
if (!touch) return;
|
|
88
|
+
const deltaX = touch.clientX - touchStartX;
|
|
89
|
+
const deltaY = touch.clientY - touchStartY;
|
|
90
|
+
|
|
91
|
+
// Only trigger swipe if horizontal movement is dominant
|
|
92
|
+
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > SWIPE_THRESHOLD) {
|
|
93
|
+
if (deltaX > 0) {
|
|
94
|
+
prev();
|
|
95
|
+
} else {
|
|
96
|
+
next();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Click on backdrop closes lightbox
|
|
102
|
+
const handleBackdropClick = e => {
|
|
103
|
+
if (e.target === dialogRef) {
|
|
104
|
+
close();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// Registration and teardown both live in onMount: onCleanup also runs when an
|
|
109
|
+
// SSR render is disposed, where `document` does not exist.
|
|
110
|
+
onMount(() => {
|
|
111
|
+
dialogRef.showModal();
|
|
112
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
113
|
+
onCleanup(() => document.removeEventListener("keydown", handleKeyDown));
|
|
114
|
+
});
|
|
115
|
+
return _$ssr(_tmpl$7, _$ssrAttribute("aria-label", _$escape(messages().imageLightbox, true), false), _$escape(_$createComponent(Show, {
|
|
116
|
+
get when() {
|
|
117
|
+
return isMultiple();
|
|
118
|
+
},
|
|
119
|
+
get children() {
|
|
120
|
+
return _$ssr(_tmpl$, _$escape(index()) + 1, _$escape(props.images.length));
|
|
121
|
+
}
|
|
122
|
+
})), _$escape(_$createComponent(Show, {
|
|
123
|
+
get when() {
|
|
124
|
+
return current()?.alt;
|
|
125
|
+
},
|
|
126
|
+
get children() {
|
|
127
|
+
return _$ssr(_tmpl$2, _$escape(current()?.alt));
|
|
128
|
+
}
|
|
129
|
+
})), _$escape(_$createComponent(Show, {
|
|
130
|
+
get when() {
|
|
131
|
+
return current()?.downloadUrl;
|
|
132
|
+
},
|
|
133
|
+
get children() {
|
|
134
|
+
return _$ssr(_tmpl$3, _$ssrAttribute("href", _$escape(current().downloadUrl, true), false), _$ssrAttribute("aria-label", _$escape(messages().downloadImage, true), false), _$escape(messages().download));
|
|
135
|
+
}
|
|
136
|
+
})), _$ssrAttribute("aria-label", _$escape(messages().closeLightbox, true), false), _$escape(messages().close), _$escape(_$createComponent(Show, {
|
|
137
|
+
get when() {
|
|
138
|
+
return current();
|
|
139
|
+
},
|
|
140
|
+
children: image => _$ssr(_tmpl$8, _$ssrAttribute("src", _$escape(image().src, true), false) + _$ssrAttribute("alt", _$escape(image().alt ?? "", true), false))
|
|
141
|
+
})), _$escape(_$createComponent(Show, {
|
|
142
|
+
get when() {
|
|
143
|
+
return isMultiple();
|
|
144
|
+
},
|
|
145
|
+
get children() {
|
|
146
|
+
return [_$ssr(_tmpl$4, _$ssrAttribute("aria-label", _$escape(messages().previousImage, true), false)), _$ssr(_tmpl$5, _$ssrAttribute("aria-label", _$escape(messages().nextImage, true), false))];
|
|
147
|
+
}
|
|
148
|
+
})), _$escape(_$createComponent(Show, {
|
|
149
|
+
get when() {
|
|
150
|
+
return isMultiple() && props.images.length <= 10;
|
|
151
|
+
},
|
|
152
|
+
get children() {
|
|
153
|
+
return _$ssr(_tmpl$6, _$ssrAttribute("aria-label", _$escape(messages().imageNavigation, true), false), _$escape(_$createComponent(For, {
|
|
154
|
+
get each() {
|
|
155
|
+
return props.images;
|
|
156
|
+
},
|
|
157
|
+
children: (_, i) => _$ssr(_tmpl$9, _$ssrAttribute("aria-current", index() === i() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("aria-label", _$escape(messages().goToImage({
|
|
158
|
+
index: i() + 1
|
|
159
|
+
}), true), false))
|
|
160
|
+
})));
|
|
161
|
+
}
|
|
162
|
+
})));
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=Lightbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createEffect","createSignal","For","onCleanup","onMount","Show","useUiMessages","Lightbox","props","messages","clampIndex","value","images","length","Math","max","min","index","setIndex","initialIndex","dialogRef","previous","currentIndex","previousImage","retained","findIndex","image","src","touchStartX","touchStartY","SWIPE_THRESHOLD","current","isMultiple","prev","i","next","close","onClose","handleKeyDown","e","key","handleTouchStart","touch","touches","clientX","clientY","handleTouchEnd","changedTouches","deltaX","deltaY","abs","handleBackdropClick","target","showModal","document","addEventListener","removeEventListener","_$ssr","_tmpl$7","_$ssrAttribute","_$escape","imageLightbox","_$createComponent","when","children","_tmpl$","alt","_tmpl$2","downloadUrl","_tmpl$3","downloadImage","download","closeLightbox","_tmpl$8","_tmpl$4","_tmpl$5","nextImage","_tmpl$6","imageNavigation","each","_","_tmpl$9","undefined","goToImage"],"sources":["content/Lightbox.tsx"],"sourcesContent":["import { createEffect, createSignal, For, onCleanup, onMount, Show } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\n\nexport type LightboxImage = {\n src: string;\n alt?: string;\n downloadUrl?: string;\n};\n\ntype LightboxProps = {\n images: LightboxImage[];\n initialIndex?: number;\n onClose: () => void;\n};\n\n/**\n * Minimal, accessible lightbox using native <dialog>.\n * Supports keyboard navigation, touch swipe gestures, and screen readers.\n */\nexport default function Lightbox(props: LightboxProps) {\n const messages = useUiMessages();\n const clampIndex = (value: number, images = props.images): number =>\n images.length === 0 ? 0 : Math.max(0, Math.min(value, images.length - 1));\n const [index, setIndex] = createSignal(clampIndex(props.initialIndex ?? 0));\n let dialogRef!: HTMLDialogElement;\n\n createEffect(\n (previous: { images: LightboxImage[]; initialIndex: number | undefined }) => {\n const images = props.images;\n const initialIndex = props.initialIndex;\n setIndex((currentIndex) => {\n if (initialIndex !== previous.initialIndex) return clampIndex(initialIndex ?? 0, images);\n const previousImage = previous.images[currentIndex];\n const retained = previousImage ? images.findIndex((image) => image === previousImage || image.src === previousImage.src) : -1;\n return retained >= 0 ? retained : clampIndex(currentIndex, images);\n });\n return { images, initialIndex };\n },\n { images: props.images, initialIndex: props.initialIndex },\n );\n\n // Touch gesture tracking\n let touchStartX = 0;\n let touchStartY = 0;\n const SWIPE_THRESHOLD = 50;\n\n const current = () => props.images[index()];\n const isMultiple = () => props.images.length > 1;\n const prev = () => {\n if (!isMultiple()) return;\n setIndex((i) => (i - 1 + props.images.length) % props.images.length);\n };\n const next = () => {\n if (!isMultiple()) return;\n setIndex((i) => (i + 1) % props.images.length);\n };\n\n const close = () => {\n dialogRef.close();\n props.onClose();\n };\n\n // Keyboard navigation\n const handleKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case \"Escape\":\n close();\n break;\n case \"ArrowLeft\":\n prev();\n break;\n case \"ArrowRight\":\n next();\n break;\n }\n };\n\n // Touch handlers for swipe gestures\n const handleTouchStart = (e: TouchEvent) => {\n const touch = e.touches[0];\n if (touch) {\n touchStartX = touch.clientX;\n touchStartY = touch.clientY;\n }\n };\n\n const handleTouchEnd = (e: TouchEvent) => {\n const touch = e.changedTouches[0];\n if (!touch) return;\n\n const deltaX = touch.clientX - touchStartX;\n const deltaY = touch.clientY - touchStartY;\n\n // Only trigger swipe if horizontal movement is dominant\n if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > SWIPE_THRESHOLD) {\n if (deltaX > 0) {\n prev();\n } else {\n next();\n }\n }\n };\n\n // Click on backdrop closes lightbox\n const handleBackdropClick = (e: MouseEvent) => {\n if (e.target === dialogRef) {\n close();\n }\n };\n\n // Registration and teardown both live in onMount: onCleanup also runs when an\n // SSR render is disposed, where `document` does not exist.\n onMount(() => {\n dialogRef.showModal();\n document.addEventListener(\"keydown\", handleKeyDown);\n onCleanup(() => document.removeEventListener(\"keydown\", handleKeyDown));\n });\n\n return (\n <dialog\n ref={dialogRef}\n class=\"k2b-content-lightbox\"\n onMouseDown={handleBackdropClick}\n onTouchStart={handleTouchStart}\n onTouchEnd={handleTouchEnd}\n aria-label={messages().imageLightbox}\n >\n {/* Top bar */}\n <div class=\"k2b-content-lightbox__bar\">\n <div class=\"k2b-content-lightbox__meta\">\n <Show when={isMultiple()}>\n <span class=\"k2b-content-lightbox__counter\" aria-live=\"polite\">\n {index() + 1} / {props.images.length}\n </span>\n </Show>\n <Show when={current()?.alt}>\n <div class=\"k2b-content-lightbox__caption\">\n <div class=\"k2b-content-lightbox__caption-text\">{current()?.alt}</div>\n </div>\n </Show>\n </div>\n\n <div class=\"k2b-content-lightbox__actions\">\n <Show when={current()?.downloadUrl}>\n <a href={current()!.downloadUrl} download=\"\" class=\"k2b-content-lightbox__button\" aria-label={messages().downloadImage}>\n <i class=\"ti ti-download\" aria-hidden=\"true\" />\n <span class=\"k2b-content-lightbox__button-label\">{messages().download}</span>\n </a>\n </Show>\n <button type=\"button\" onClick={close} class=\"k2b-content-lightbox__button\" aria-label={messages().closeLightbox}>\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n <span class=\"k2b-content-lightbox__button-label\">{messages().close}</span>\n </button>\n </div>\n </div>\n\n <div class=\"k2b-content-lightbox__stage\">\n <Show when={current()}>\n {(image) => <img src={image().src} alt={image().alt ?? \"\"} class=\"k2b-content-lightbox__image\" draggable={false} />}\n </Show>\n </div>\n\n <Show when={isMultiple()}>\n <button\n type=\"button\"\n onClick={prev}\n class=\"k2b-content-lightbox__nav\"\n data-direction=\"previous\"\n aria-label={messages().previousImage}\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </button>\n <button type=\"button\" onClick={next} class=\"k2b-content-lightbox__nav\" data-direction=\"next\" aria-label={messages().nextImage}>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n </button>\n </Show>\n\n <Show when={isMultiple() && props.images.length <= 10}>\n <div class=\"k2b-content-lightbox__dots\" role=\"group\" aria-label={messages().imageNavigation}>\n <For each={props.images}>\n {(_, i) => (\n <button\n type=\"button\"\n onClick={() => setIndex(i())}\n class=\"k2b-content-lightbox__dot\"\n aria-current={index() === i() ? \"true\" : undefined}\n aria-label={messages().goToImage({ index: i() + 1 })}\n />\n )}\n </For>\n </div>\n </Show>\n </dialog>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ssr as _$ssr } from "solid-js/web";
|
|
2
|
+
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
3
|
+
import { escape as _$escape } from "solid-js/web";
|
|
4
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
5
|
+
var _tmpl$ = ["<span class=\"k2b-log-level\"", "><i class=\"", "\" aria-hidden=\"true\"></i><span>", "</span></span>"],
|
|
6
|
+
_tmpl$2 = ["<span class=\"k2b-log-table__source\">", "</span>"],
|
|
7
|
+
_tmpl$3 = ["<span", ">", "</span>"],
|
|
8
|
+
_tmpl$4 = ["<span class=\"k2b-log-table__time\">", "</span>"];
|
|
9
|
+
import { dates } from "@k2b/stdlib";
|
|
10
|
+
import { Show } from "solid-js";
|
|
11
|
+
import { useUiMessages } from "../intl/messages";
|
|
12
|
+
import Placeholder from "../surfaces/Placeholder";
|
|
13
|
+
import DataTable from "./DataTable";
|
|
14
|
+
/**
|
|
15
|
+
* Cloud paints each level with a hardcoded Tailwind palette pair
|
|
16
|
+
* (`text-amber-500 dark:text-amber-400`, …). The package keeps the same
|
|
17
|
+
* per-level distinction but routes it through `data-level` so the semantic
|
|
18
|
+
* `--k2b-*` tokens stay the single theming contract in both schemes.
|
|
19
|
+
*/
|
|
20
|
+
const levelIcon = {
|
|
21
|
+
debug: {
|
|
22
|
+
icon: "ti ti-bug",
|
|
23
|
+
level: "debug",
|
|
24
|
+
label: "debug"
|
|
25
|
+
},
|
|
26
|
+
info: {
|
|
27
|
+
icon: "ti ti-info-circle",
|
|
28
|
+
level: "info",
|
|
29
|
+
label: "info"
|
|
30
|
+
},
|
|
31
|
+
warn: {
|
|
32
|
+
icon: "ti ti-alert-triangle",
|
|
33
|
+
level: "warn",
|
|
34
|
+
label: "warn"
|
|
35
|
+
},
|
|
36
|
+
error: {
|
|
37
|
+
icon: "ti ti-alert-circle",
|
|
38
|
+
level: "error",
|
|
39
|
+
label: "error"
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
export default function LogEntriesTable(props) {
|
|
43
|
+
const messages = useUiMessages();
|
|
44
|
+
const columns = () => [{
|
|
45
|
+
id: "level",
|
|
46
|
+
header: "Level",
|
|
47
|
+
value: entry => entry.level
|
|
48
|
+
}, {
|
|
49
|
+
id: "source",
|
|
50
|
+
header: `Source (${props.entries.length})`,
|
|
51
|
+
value: entry => entry.source
|
|
52
|
+
}, {
|
|
53
|
+
id: "message",
|
|
54
|
+
header: "Message",
|
|
55
|
+
value: entry => entry.message
|
|
56
|
+
}, {
|
|
57
|
+
id: "time",
|
|
58
|
+
header: "Time",
|
|
59
|
+
value: entry => entry.createdAt,
|
|
60
|
+
cellClass: "k2b-log-table__time-cell"
|
|
61
|
+
}];
|
|
62
|
+
return _$createComponent(Show, {
|
|
63
|
+
get when() {
|
|
64
|
+
return props.entries.length > 0;
|
|
65
|
+
},
|
|
66
|
+
get fallback() {
|
|
67
|
+
return _$createComponent(Placeholder, {
|
|
68
|
+
surface: "paper",
|
|
69
|
+
get description() {
|
|
70
|
+
return props.emptyMessage ?? messages().noLogEntries;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
get children() {
|
|
75
|
+
return _$createComponent(DataTable, {
|
|
76
|
+
get rows() {
|
|
77
|
+
return props.entries;
|
|
78
|
+
},
|
|
79
|
+
get columns() {
|
|
80
|
+
return columns();
|
|
81
|
+
},
|
|
82
|
+
getRowId: entry => String(entry.id),
|
|
83
|
+
hoverRows: true,
|
|
84
|
+
"class": "k2b-log-table",
|
|
85
|
+
renderCell: ({
|
|
86
|
+
row,
|
|
87
|
+
col
|
|
88
|
+
}) => {
|
|
89
|
+
if (col.id === "level") {
|
|
90
|
+
const level = levelIcon[row.level] ?? {
|
|
91
|
+
icon: "ti ti-circle",
|
|
92
|
+
level: "neutral",
|
|
93
|
+
label: row.level || "unknown"
|
|
94
|
+
};
|
|
95
|
+
return _$ssr(_tmpl$, _$ssrAttribute("data-level", _$escape(level.level, true), false), `k2b-log-level__icon ${_$escape(level.icon, true)}`, _$escape(level.label));
|
|
96
|
+
}
|
|
97
|
+
if (col.id === "source") return _$ssr(_tmpl$2, _$escape(row.source));
|
|
98
|
+
if (col.id === "message") return _$ssr(_tmpl$3, _$ssrAttribute("title", _$escape(row.message, true), false), _$escape(row.message));
|
|
99
|
+
if (col.id === "time") return _$ssr(_tmpl$4, _$escape(dates.formatDateTime(row.createdAt)));
|
|
100
|
+
return "";
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=LogEntriesTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["dates","Show","useUiMessages","Placeholder","DataTable","levelIcon","debug","icon","level","label","info","warn","error","LogEntriesTable","props","messages","columns","id","header","value","entry","entries","length","source","message","createdAt","cellClass","_$createComponent","when","fallback","surface","description","emptyMessage","noLogEntries","children","rows","getRowId","String","hoverRows","renderCell","row","col","_$ssr","_tmpl$","_$ssrAttribute","_$escape","_tmpl$2","_tmpl$3","_tmpl$4","formatDateTime"],"sources":["content/LogEntriesTable.tsx"],"sourcesContent":["import { dates } from \"@k2b/stdlib\";\nimport { Show } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport DataTable, { type DataTableColumn } from \"./DataTable\";\n\nexport type LogTableEntry = {\n id: number | string;\n level: string;\n source: string;\n message: string;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype Props = {\n entries: readonly LogTableEntry[];\n emptyMessage?: string;\n};\n\n/**\n * Cloud paints each level with a hardcoded Tailwind palette pair\n * (`text-amber-500 dark:text-amber-400`, …). The package keeps the same\n * per-level distinction but routes it through `data-level` so the semantic\n * `--k2b-*` tokens stay the single theming contract in both schemes.\n */\nconst levelIcon: Record<string, { icon: string; level: string; label: string }> = {\n debug: { icon: \"ti ti-bug\", level: \"debug\", label: \"debug\" },\n info: { icon: \"ti ti-info-circle\", level: \"info\", label: \"info\" },\n warn: { icon: \"ti ti-alert-triangle\", level: \"warn\", label: \"warn\" },\n error: { icon: \"ti ti-alert-circle\", level: \"error\", label: \"error\" },\n};\n\nexport default function LogEntriesTable(props: Props) {\n const messages = useUiMessages();\n const columns = (): DataTableColumn<LogTableEntry>[] => [\n { id: \"level\", header: \"Level\", value: (entry) => entry.level },\n { id: \"source\", header: `Source (${props.entries.length})`, value: (entry) => entry.source },\n { id: \"message\", header: \"Message\", value: (entry) => entry.message },\n { id: \"time\", header: \"Time\", value: (entry) => entry.createdAt, cellClass: \"k2b-log-table__time-cell\" },\n ];\n\n return (\n <Show\n when={props.entries.length > 0}\n fallback={<Placeholder surface=\"paper\" description={<>{props.emptyMessage ?? messages().noLogEntries}</>} />}\n >\n <DataTable\n rows={props.entries}\n columns={columns()}\n getRowId={(entry) => String(entry.id)}\n hoverRows\n class=\"k2b-log-table\"\n renderCell={({ row, col }) => {\n if (col.id === \"level\") {\n const level = levelIcon[row.level] ?? { icon: \"ti ti-circle\", level: \"neutral\", label: row.level || \"unknown\" };\n return (\n <span class=\"k2b-log-level\" data-level={level.level}>\n <i class={`k2b-log-level__icon ${level.icon}`} aria-hidden=\"true\" />\n <span>{level.label}</span>\n </span>\n );\n }\n if (col.id === \"source\") return <span class=\"k2b-log-table__source\">{row.source}</span>;\n if (col.id === \"message\") return <span title={row.message}>{row.message}</span>;\n if (col.id === \"time\") return <span class=\"k2b-log-table__time\">{dates.formatDateTime(row.createdAt)}</span>;\n return \"\";\n }}\n />\n </Show>\n );\n}\n"],"mappings":";;;;;;;;AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,IAAI,QAAQ,UAAU;AAC/B,SAASC,aAAa,QAAQ,kBAAkB;AAChD,OAAOC,WAAW,MAAM,yBAAyB;AACjD,OAAOC,SAAS,MAAgC,aAAa;AAgB7D;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,SAAyE,GAAG;EAChFC,KAAK,EAAE;IAAEC,IAAI,EAAE,WAAW;IAAEC,KAAK,EAAE,OAAO;IAAEC,KAAK,EAAE;EAAQ,CAAC;EAC5DC,IAAI,EAAE;IAAEH,IAAI,EAAE,mBAAmB;IAAEC,KAAK,EAAE,MAAM;IAAEC,KAAK,EAAE;EAAO,CAAC;EACjEE,IAAI,EAAE;IAAEJ,IAAI,EAAE,sBAAsB;IAAEC,KAAK,EAAE,MAAM;IAAEC,KAAK,EAAE;EAAO,CAAC;EACpEG,KAAK,EAAE;IAAEL,IAAI,EAAE,oBAAoB;IAAEC,KAAK,EAAE,OAAO;IAAEC,KAAK,EAAE;EAAQ;AACtE,CAAC;AAED,eAAe,SAASI,eAAeA,CAACC,KAAY,EAAE;EACpD,MAAMC,QAAQ,GAAGb,aAAa,CAAC,CAAC;EAChC,MAAMc,OAAO,GAAGA,CAAA,KAAwC,CACtD;IAAEC,EAAE,EAAE,OAAO;IAAEC,MAAM,EAAE,OAAO;IAAEC,KAAK,EAAGC,KAAK,IAAKA,KAAK,CAACZ;EAAM,CAAC,EAC/D;IAAES,EAAE,EAAE,QAAQ;IAAEC,MAAM,EAAE,WAAWJ,KAAK,CAACO,OAAO,CAACC,MAAM,GAAG;IAAEH,KAAK,EAAGC,KAAK,IAAKA,KAAK,CAACG;EAAO,CAAC,EAC5F;IAAEN,EAAE,EAAE,SAAS;IAAEC,MAAM,EAAE,SAAS;IAAEC,KAAK,EAAGC,KAAK,IAAKA,KAAK,CAACI;EAAQ,CAAC,EACrE;IAAEP,EAAE,EAAE,MAAM;IAAEC,MAAM,EAAE,MAAM;IAAEC,KAAK,EAAGC,KAAK,IAAKA,KAAK,CAACK,SAAS;IAAEC,SAAS,EAAE;EAA2B,CAAC,CACzG;EAED,OAAAC,iBAAA,CACG1B,IAAI;IAAA,IACH2B,IAAIA,CAAA;MAAA,OAAEd,KAAK,CAACO,OAAO,CAACC,MAAM,GAAG,CAAC;IAAA;IAAA,IAC9BO,QAAQA,CAAA;MAAA,OAAAF,iBAAA,CAAGxB,WAAW;QAAC2B,OAAO;QAAA,IAASC,WAAWA,CAAA;UAAA,OAAKjB,KAAK,CAACkB,YAAY,IAAIjB,QAAQ,CAAC,CAAC,CAACkB,YAAY;QAAA;MAAA;IAAA;IAAA,IAAAC,SAAA;MAAA,OAAAP,iBAAA,CAEnGvB,SAAS;QAAA,IACR+B,IAAIA,CAAA;UAAA,OAAErB,KAAK,CAACO,OAAO;QAAA;QAAA,IACnBL,OAAOA,CAAA;UAAA,OAAEA,OAAO,CAAC,CAAC;QAAA;QAClBoB,QAAQ,EAAGhB,KAAK,IAAKiB,MAAM,CAACjB,KAAK,CAACH,EAAE,CAAC;QACrCqB,SAAS;QAAA;QAETC,UAAU,EAAEA,CAAC;UAAEC,GAAG;UAAEC;QAAI,CAAC,KAAK;UAC5B,IAAIA,GAAG,CAACxB,EAAE,KAAK,OAAO,EAAE;YACtB,MAAMT,KAAK,GAAGH,SAAS,CAACmC,GAAG,CAAChC,KAAK,CAAC,IAAI;cAAED,IAAI,EAAE,cAAc;cAAEC,KAAK,EAAE,SAAS;cAAEC,KAAK,EAAE+B,GAAG,CAAChC,KAAK,IAAI;YAAU,CAAC;YAC/G,OAAAkC,KAAA,CAAAC,MAAA,EAAAC,cAAA,eAAAC,QAAA,CAC0CrC,KAAK,CAACA,KAAK,iBACvC,uBAAAqC,QAAA,CAAuBrC,KAAK,CAACD,IAAI,SAAE,EAAAsC,QAAA,CACtCrC,KAAK,CAACC,KAAK;UAGxB;UACA,IAAIgC,GAAG,CAACxB,EAAE,KAAK,QAAQ,EAAE,OAAAyB,KAAA,CAAAI,OAAA,EAAAD,QAAA,CAA4CL,GAAG,CAACjB,MAAM;UAC/E,IAAIkB,GAAG,CAACxB,EAAE,KAAK,SAAS,EAAE,OAAAyB,KAAA,CAAAK,OAAA,EAAAH,cAAA,UAAAC,QAAA,CAAoBL,GAAG,CAAChB,OAAO,iBAAAqB,QAAA,CAAGL,GAAG,CAAChB,OAAO;UACvE,IAAIiB,GAAG,CAACxB,EAAE,KAAK,MAAM,EAAE,OAAAyB,KAAA,CAAAM,OAAA,EAAAH,QAAA,CAA0C7C,KAAK,CAACiD,cAAc,CAACT,GAAG,CAACf,SAAS,CAAC;UACpG,OAAO,EAAE;QACX;MAAC;IAAA;EAAA;AAIT","ignoreList":[]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { ssr as _$ssr } from "solid-js/web";
|
|
2
|
+
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
3
|
+
import { escape as _$escape } from "solid-js/web";
|
|
4
|
+
var _tmpl$ = ["<div class=\"", "\"", ">", "</div>"];
|
|
5
|
+
import { marked, Renderer } from "marked";
|
|
6
|
+
const escapeHtml = value => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
7
|
+
const safeUrl = value => {
|
|
8
|
+
const normalized = value.trim().replace(/[\u0000-\u001f\u007f-\u009f\s]+/g, "");
|
|
9
|
+
if (/^(?:javascript|vbscript|data):/i.test(normalized)) return null;
|
|
10
|
+
return value;
|
|
11
|
+
};
|
|
12
|
+
const normalizeInlineTokens = tokens => [...new Set(tokens?.filter(Boolean) ?? [])].sort((left, right) => right.length - left.length);
|
|
13
|
+
const isStandaloneInlineToken = (text, start, value) => {
|
|
14
|
+
const before = text[start - 1];
|
|
15
|
+
if (before && /[a-zA-Z0-9_.%+\-]/.test(before)) return false;
|
|
16
|
+
const end = start + value.length;
|
|
17
|
+
const after = text[end];
|
|
18
|
+
if (after && /[a-zA-Z0-9_@]/.test(after)) return false;
|
|
19
|
+
return !(after === "." && /[a-zA-Z0-9_]/.test(text[end + 1] ?? ""));
|
|
20
|
+
};
|
|
21
|
+
const createSafeRenderer = (options = {}) => {
|
|
22
|
+
const renderer = new Renderer();
|
|
23
|
+
const inlineTokens = normalizeInlineTokens(options.inlineTokens);
|
|
24
|
+
const renderText = renderer.text.bind(renderer);
|
|
25
|
+
renderer.html = ({
|
|
26
|
+
text
|
|
27
|
+
}) => escapeHtml(text);
|
|
28
|
+
renderer.link = function ({
|
|
29
|
+
href,
|
|
30
|
+
title,
|
|
31
|
+
tokens
|
|
32
|
+
}) {
|
|
33
|
+
const body = this.parser.parseInline(tokens);
|
|
34
|
+
const url = safeUrl(href);
|
|
35
|
+
if (!url) return body;
|
|
36
|
+
const titleAttribute = title ? ` title="${escapeHtml(title)}"` : "";
|
|
37
|
+
return `<a href="${escapeHtml(url)}"${titleAttribute}>${body}</a>`;
|
|
38
|
+
};
|
|
39
|
+
renderer.image = ({
|
|
40
|
+
href,
|
|
41
|
+
title,
|
|
42
|
+
text
|
|
43
|
+
}) => {
|
|
44
|
+
const url = safeUrl(href);
|
|
45
|
+
if (!url) return escapeHtml(text);
|
|
46
|
+
const titleAttribute = title ? ` title="${escapeHtml(title)}"` : "";
|
|
47
|
+
return `<img src="${escapeHtml(url)}" alt="${escapeHtml(text)}"${titleAttribute}>`;
|
|
48
|
+
};
|
|
49
|
+
renderer.text = token => {
|
|
50
|
+
if (inlineTokens.length === 0 || token.type === "escape" || "tokens" in token && token.tokens) return renderText(token);
|
|
51
|
+
const parts = [];
|
|
52
|
+
let plainStart = 0;
|
|
53
|
+
let cursor = 0;
|
|
54
|
+
while (cursor < token.text.length) {
|
|
55
|
+
const inlineToken = inlineTokens.find(candidate => token.text.startsWith(candidate, cursor) && isStandaloneInlineToken(token.text, cursor, candidate));
|
|
56
|
+
if (!inlineToken) {
|
|
57
|
+
cursor += 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (plainStart < cursor) {
|
|
61
|
+
const text = token.text.slice(plainStart, cursor);
|
|
62
|
+
parts.push(renderText({
|
|
63
|
+
...token,
|
|
64
|
+
raw: text,
|
|
65
|
+
text
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
parts.push(`<span class="k2b-content-markdown__inline-token">${renderText({
|
|
69
|
+
...token,
|
|
70
|
+
raw: inlineToken,
|
|
71
|
+
text: inlineToken
|
|
72
|
+
})}</span>`);
|
|
73
|
+
cursor += inlineToken.length;
|
|
74
|
+
plainStart = cursor;
|
|
75
|
+
}
|
|
76
|
+
if (plainStart === 0) return renderText(token);
|
|
77
|
+
if (plainStart < token.text.length) {
|
|
78
|
+
const text = token.text.slice(plainStart);
|
|
79
|
+
parts.push(renderText({
|
|
80
|
+
...token,
|
|
81
|
+
raw: text,
|
|
82
|
+
text
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
return parts.join("");
|
|
86
|
+
};
|
|
87
|
+
return renderer;
|
|
88
|
+
};
|
|
89
|
+
export const renderSafeMarkdown = (markdown, options = {}) => marked.parse(markdown, {
|
|
90
|
+
async: false,
|
|
91
|
+
renderer: createSafeRenderer(options)
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Markdown View Component (SSR)
|
|
96
|
+
*
|
|
97
|
+
* Renders untrusted Markdown safely by default. Raw HTML and unsafe link
|
|
98
|
+
* protocols are escaped. Already-rendered HTML requires the deliberately named
|
|
99
|
+
* `trustedHtml` boundary; the caller owns sanitization in that mode.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```tsx
|
|
103
|
+
* import { MarkdownView } from "@k2b/ui";
|
|
104
|
+
*
|
|
105
|
+
* <MarkdownView markdown={source} />;
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* @example Compact headings, e.g. inside comments or file previews:
|
|
109
|
+
* ```tsx
|
|
110
|
+
* <MarkdownView markdown={source} headingScale="compact" />;
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export default function MarkdownView(props) {
|
|
114
|
+
const html = () => props.markdown !== undefined ? renderSafeMarkdown(props.markdown, {
|
|
115
|
+
inlineTokens: props.inlineTokens
|
|
116
|
+
}) : props.trustedHtml;
|
|
117
|
+
return _$ssr(_tmpl$, `k2b-content-markdown ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-heading-scale", props.headingScale && props.headingScale !== "normal" ? _$escape(props.headingScale, true) : _$escape(undefined, true), false), html());
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=MarkdownView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["marked","Renderer","escapeHtml","value","replaceAll","safeUrl","normalized","trim","replace","test","normalizeInlineTokens","tokens","Set","filter","Boolean","sort","left","right","length","isStandaloneInlineToken","text","start","before","end","after","createSafeRenderer","options","renderer","inlineTokens","renderText","bind","html","link","href","title","body","parser","parseInline","url","titleAttribute","image","token","type","parts","plainStart","cursor","inlineToken","find","candidate","startsWith","slice","push","raw","join","renderSafeMarkdown","markdown","parse","async","MarkdownView","props","undefined","trustedHtml","_$ssr","_tmpl$","_$escape","class","_$ssrAttribute","headingScale"],"sources":["content/MarkdownView.tsx"],"sourcesContent":["import { marked, Renderer, type Tokens } from \"marked\";\n\ntype CommonProps = {\n /** Optional additional CSS classes */\n class?: string;\n /**\n * Visual heading scale. Markdown heading levels and document structure stay\n * unchanged.\n */\n headingScale?: \"compact\" | \"normal\" | \"large\";\n};\n\nexport type MarkdownViewProps = CommonProps &\n (\n | {\n /** Untrusted Markdown. Raw HTML and unsafe link protocols are escaped. */\n markdown: string;\n /** Exact standalone text tokens to emphasize without changing Markdown parsing or trusted-HTML boundaries. */\n inlineTokens?: readonly string[];\n trustedHtml?: never;\n }\n | {\n /** Explicitly trusted, already-rendered HTML. The caller owns sanitization. */\n trustedHtml: string;\n markdown?: never;\n inlineTokens?: never;\n }\n );\n\nexport type MarkdownRenderOptions = { inlineTokens?: readonly string[] };\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\").replaceAll(\"'\", \"'\");\n\nconst safeUrl = (value: string): string | null => {\n const normalized = value.trim().replace(/[\\u0000-\\u001f\\u007f-\\u009f\\s]+/g, \"\");\n if (/^(?:javascript|vbscript|data):/i.test(normalized)) return null;\n return value;\n};\n\nconst normalizeInlineTokens = (tokens: readonly string[] | undefined): string[] =>\n [...new Set(tokens?.filter(Boolean) ?? [])].sort((left, right) => right.length - left.length);\n\nconst isStandaloneInlineToken = (text: string, start: number, value: string): boolean => {\n const before = text[start - 1];\n if (before && /[a-zA-Z0-9_.%+\\-]/.test(before)) return false;\n const end = start + value.length;\n const after = text[end];\n if (after && /[a-zA-Z0-9_@]/.test(after)) return false;\n return !(after === \".\" && /[a-zA-Z0-9_]/.test(text[end + 1] ?? \"\"));\n};\n\nconst createSafeRenderer = (options: MarkdownRenderOptions = {}): Renderer => {\n const renderer = new Renderer();\n const inlineTokens = normalizeInlineTokens(options.inlineTokens);\n const renderText = renderer.text.bind(renderer);\n renderer.html = ({ text }: Tokens.HTML | Tokens.Tag) => escapeHtml(text);\n renderer.link = function ({ href, title, tokens }: Tokens.Link) {\n const body = this.parser.parseInline(tokens);\n const url = safeUrl(href);\n if (!url) return body;\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n return `<a href=\"${escapeHtml(url)}\"${titleAttribute}>${body}</a>`;\n };\n renderer.image = ({ href, title, text }: Tokens.Image) => {\n const url = safeUrl(href);\n if (!url) return escapeHtml(text);\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n return `<img src=\"${escapeHtml(url)}\" alt=\"${escapeHtml(text)}\"${titleAttribute}>`;\n };\n renderer.text = (token) => {\n if (inlineTokens.length === 0 || token.type === \"escape\" || (\"tokens\" in token && token.tokens)) return renderText(token);\n const parts: string[] = [];\n let plainStart = 0;\n let cursor = 0;\n while (cursor < token.text.length) {\n const inlineToken = inlineTokens.find(\n (candidate) => token.text.startsWith(candidate, cursor) && isStandaloneInlineToken(token.text, cursor, candidate),\n );\n if (!inlineToken) {\n cursor += 1;\n continue;\n }\n if (plainStart < cursor) {\n const text = token.text.slice(plainStart, cursor);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n parts.push(\n `<span class=\"k2b-content-markdown__inline-token\">${renderText({ ...token, raw: inlineToken, text: inlineToken })}</span>`,\n );\n cursor += inlineToken.length;\n plainStart = cursor;\n }\n if (plainStart === 0) return renderText(token);\n if (plainStart < token.text.length) {\n const text = token.text.slice(plainStart);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n return parts.join(\"\");\n };\n return renderer;\n};\n\nexport const renderSafeMarkdown = (markdown: string, options: MarkdownRenderOptions = {}): string =>\n marked.parse(markdown, { async: false, renderer: createSafeRenderer(options) }) as string;\n\n/**\n * Markdown View Component (SSR)\n *\n * Renders untrusted Markdown safely by default. Raw HTML and unsafe link\n * protocols are escaped. Already-rendered HTML requires the deliberately named\n * `trustedHtml` boundary; the caller owns sanitization in that mode.\n *\n * @example\n * ```tsx\n * import { MarkdownView } from \"@k2b/ui\";\n *\n * <MarkdownView markdown={source} />;\n * ```\n *\n * @example Compact headings, e.g. inside comments or file previews:\n * ```tsx\n * <MarkdownView markdown={source} headingScale=\"compact\" />;\n * ```\n */\nexport default function MarkdownView(props: MarkdownViewProps) {\n const html = () =>\n props.markdown !== undefined ? renderSafeMarkdown(props.markdown, { inlineTokens: props.inlineTokens }) : props.trustedHtml;\n return (\n <div\n class={`k2b-content-markdown ${props.class ?? \"\"}`}\n data-heading-scale={props.headingScale && props.headingScale !== \"normal\" ? props.headingScale : undefined}\n innerHTML={html()}\n />\n );\n}\n"],"mappings":"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","ignoreList":[]}
|