@k2b/ui 0.33.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base.css +14 -1
- package/dist/browser/actions/ContextMenu.js +13 -0
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/Dropdown.js +16 -4
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/SelectionToolbar.js +129 -0
- package/dist/browser/actions/SelectionToolbar.js.map +1 -0
- package/dist/browser/actions/index.js +1 -0
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/charts.js +6 -0
- package/dist/browser/charts.js.map +1 -0
- package/dist/browser/chat/ChatComposer.js +525 -407
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/chat-messages.js +4 -0
- package/dist/browser/chat/chat-messages.js.map +1 -1
- package/dist/browser/chat/composer-document.js +19 -0
- package/dist/browser/chat/composer-document.js.map +1 -1
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/content/Chart.js +8 -0
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/FileGrid.js +231 -9
- package/dist/browser/content/FileGrid.js.map +1 -1
- package/dist/browser/content/FileTypeIcon.js +15 -0
- package/dist/browser/content/FileTypeIcon.js.map +1 -1
- package/dist/browser/content/FileView.js +11 -4
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/MatchText.js +61 -0
- package/dist/browser/content/MatchText.js.map +1 -0
- package/dist/browser/content/MessageRow.js +73 -53
- package/dist/browser/content/MessageRow.js.map +1 -1
- package/dist/browser/content/ReactionBar.js +3 -1
- package/dist/browser/content/ReactionBar.js.map +1 -1
- package/dist/browser/content/calendar-day-scroll.js +4 -3
- package/dist/browser/content/calendar-day-scroll.js.map +1 -1
- package/dist/browser/content/chart-bar.js +476 -0
- package/dist/browser/content/chart-bar.js.map +1 -0
- package/dist/browser/content/file-list-messages.js +52 -0
- package/dist/browser/content/file-list-messages.js.map +1 -0
- package/dist/browser/content/index.js +2 -1
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/feedback/Tooltip.js +31 -14
- package/dist/browser/feedback/Tooltip.js.map +1 -1
- package/dist/browser/inputs/ChoiceList.js +178 -0
- package/dist/browser/inputs/ChoiceList.js.map +1 -0
- package/dist/browser/inputs/ChoiceSlider.js +314 -0
- package/dist/browser/inputs/ChoiceSlider.js.map +1 -0
- package/dist/browser/inputs/ChoiceTiles.js +135 -0
- package/dist/browser/inputs/ChoiceTiles.js.map +1 -0
- package/dist/browser/inputs/ColorChoices.js +120 -0
- package/dist/browser/inputs/ColorChoices.js.map +1 -0
- package/dist/browser/inputs/QrScanner.js +95 -13
- package/dist/browser/inputs/QrScanner.js.map +1 -1
- package/dist/browser/inputs/TextInput.js +15 -13
- package/dist/browser/inputs/TextInput.js.map +1 -1
- package/dist/browser/inputs/index.js +4 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/qr-messages.js +2 -0
- package/dist/browser/inputs/qr-messages.js.map +1 -1
- package/dist/browser/internal/radio-keys.js +13 -0
- package/dist/browser/internal/radio-keys.js.map +1 -0
- package/dist/browser/layout/AnchoredPopover.js +180 -0
- package/dist/browser/layout/AnchoredPopover.js.map +1 -0
- package/dist/browser/layout/AppWorkspace.js +155 -20
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +443 -333
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/MobileShell.js +21 -7
- package/dist/browser/layout/MobileShell.js.map +1 -1
- package/dist/browser/layout/Settings.js +283 -175
- package/dist/browser/layout/Settings.js.map +1 -1
- package/dist/browser/layout/SidebarRailHint.js +79 -0
- package/dist/browser/layout/SidebarRailHint.js.map +1 -0
- package/dist/browser/layout/SidebarSwitcher.js +79 -66
- package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
- package/dist/browser/layout/TabBar.js +18 -4
- package/dist/browser/layout/TabBar.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +11 -4
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/detail-panel-messages.js +4 -2
- package/dist/browser/layout/detail-panel-messages.js.map +1 -1
- package/dist/browser/layout/index.js +2 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/settings-messages.js +26 -2
- package/dist/browser/layout/settings-messages.js.map +1 -1
- package/dist/browser/surfaces/Avatar.js +2 -14
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/DotStrip.js +70 -0
- package/dist/browser/surfaces/DotStrip.js.map +1 -0
- package/dist/browser/surfaces/ProgressRing.js +3 -0
- package/dist/browser/surfaces/ProgressRing.js.map +1 -1
- package/dist/browser/surfaces/ResourceCard.js +125 -68
- package/dist/browser/surfaces/ResourceCard.js.map +1 -1
- package/dist/browser/surfaces/index.js +2 -0
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/browser/surfaces/person-color.js +18 -0
- package/dist/browser/surfaces/person-color.js.map +1 -0
- package/dist/browser/surfaces/resource-messages.js +6 -2
- package/dist/browser/surfaces/resource-messages.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +1358 -0
- package/dist/browser/text-editor/TextEditor.js.map +1 -0
- package/dist/browser/text-editor/clipboard-html.js +152 -0
- package/dist/browser/text-editor/clipboard-html.js.map +1 -0
- package/dist/browser/text-editor/clipboard-loading.js +68 -0
- package/dist/browser/text-editor/clipboard-loading.js.map +1 -0
- package/dist/browser/text-editor/clipboard.js +51 -0
- package/dist/browser/text-editor/clipboard.js.map +1 -0
- package/dist/browser/text-editor/engine.js +125 -0
- package/dist/browser/text-editor/engine.js.map +1 -0
- package/dist/browser/text-editor/format.js +218 -0
- package/dist/browser/text-editor/format.js.map +1 -0
- package/dist/browser/text-editor/formatted.js +164 -0
- package/dist/browser/text-editor/formatted.js.map +1 -0
- package/dist/browser/text-editor/language.js +19 -0
- package/dist/browser/text-editor/language.js.map +1 -0
- package/dist/browser/text-editor/markdown-table.js +563 -0
- package/dist/browser/text-editor/markdown-table.js.map +1 -0
- package/dist/browser/text-editor/messages.js +233 -0
- package/dist/browser/text-editor/messages.js.map +1 -0
- package/dist/browser/text-editor/paste.js +115 -0
- package/dist/browser/text-editor/paste.js.map +1 -0
- package/dist/browser/text-editor/table.js +1760 -0
- package/dist/browser/text-editor/table.js.map +1 -0
- package/dist/browser/text-editor.js +5 -0
- package/dist/browser/text-editor.js.map +1 -0
- package/dist/browser/widgets/Widget.js +3 -2
- package/dist/browser/widgets/Widget.js.map +1 -1
- package/dist/ssr/actions/ContextMenu.js +9 -0
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +15 -4
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/SelectionToolbar.js +104 -0
- package/dist/ssr/actions/SelectionToolbar.js.map +1 -0
- package/dist/ssr/actions/index.js +1 -0
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/charts.js +6 -0
- package/dist/ssr/charts.js.map +1 -0
- package/dist/ssr/chat/ChatComposer.js +132 -53
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/chat-messages.js +4 -0
- package/dist/ssr/chat/chat-messages.js.map +1 -1
- package/dist/ssr/chat/composer-document.js +19 -0
- package/dist/ssr/chat/composer-document.js.map +1 -1
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/content/Chart.js +8 -0
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/FileGrid.js +132 -5
- package/dist/ssr/content/FileGrid.js.map +1 -1
- package/dist/ssr/content/FileTypeIcon.js +15 -0
- package/dist/ssr/content/FileTypeIcon.js.map +1 -1
- package/dist/ssr/content/FileView.js +11 -4
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/MatchText.js +56 -0
- package/dist/ssr/content/MatchText.js.map +1 -0
- package/dist/ssr/content/MessageRow.js +16 -6
- package/dist/ssr/content/MessageRow.js.map +1 -1
- package/dist/ssr/content/ReactionBar.js +3 -1
- package/dist/ssr/content/ReactionBar.js.map +1 -1
- package/dist/ssr/content/calendar-day-scroll.js +4 -3
- package/dist/ssr/content/calendar-day-scroll.js.map +1 -1
- package/dist/ssr/content/chart-bar.js +476 -0
- package/dist/ssr/content/chart-bar.js.map +1 -0
- package/dist/ssr/content/file-list-messages.js +52 -0
- package/dist/ssr/content/file-list-messages.js.map +1 -0
- package/dist/ssr/content/index.js +2 -1
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/feedback/Tooltip.js +31 -14
- package/dist/ssr/feedback/Tooltip.js.map +1 -1
- package/dist/ssr/inputs/ChoiceList.js +95 -0
- package/dist/ssr/inputs/ChoiceList.js.map +1 -0
- package/dist/ssr/inputs/ChoiceSlider.js +191 -0
- package/dist/ssr/inputs/ChoiceSlider.js.map +1 -0
- package/dist/ssr/inputs/ChoiceTiles.js +61 -0
- package/dist/ssr/inputs/ChoiceTiles.js.map +1 -0
- package/dist/ssr/inputs/ColorChoices.js +60 -0
- package/dist/ssr/inputs/ColorChoices.js.map +1 -0
- package/dist/ssr/inputs/QrScanner.js +89 -10
- package/dist/ssr/inputs/QrScanner.js.map +1 -1
- package/dist/ssr/inputs/TextInput.js +13 -1
- package/dist/ssr/inputs/TextInput.js.map +1 -1
- package/dist/ssr/inputs/index.js +4 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/qr-messages.js +2 -0
- package/dist/ssr/inputs/qr-messages.js.map +1 -1
- package/dist/ssr/internal/radio-keys.js +13 -0
- package/dist/ssr/internal/radio-keys.js.map +1 -0
- package/dist/ssr/layout/AnchoredPopover.js +142 -0
- package/dist/ssr/layout/AnchoredPopover.js.map +1 -0
- package/dist/ssr/layout/AppWorkspace.js +154 -20
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +181 -108
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/MobileShell.js +20 -6
- package/dist/ssr/layout/MobileShell.js.map +1 -1
- package/dist/ssr/layout/Settings.js +122 -45
- package/dist/ssr/layout/Settings.js.map +1 -1
- package/dist/ssr/layout/SidebarRailHint.js +79 -0
- package/dist/ssr/layout/SidebarRailHint.js.map +1 -0
- package/dist/ssr/layout/SidebarSwitcher.js +13 -3
- package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
- package/dist/ssr/layout/TabBar.js +11 -3
- package/dist/ssr/layout/TabBar.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +11 -4
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/detail-panel-messages.js +4 -2
- package/dist/ssr/layout/detail-panel-messages.js.map +1 -1
- package/dist/ssr/layout/index.js +2 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/settings-messages.js +26 -2
- package/dist/ssr/layout/settings-messages.js.map +1 -1
- package/dist/ssr/surfaces/Avatar.js +2 -14
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/DotStrip.js +31 -0
- package/dist/ssr/surfaces/DotStrip.js.map +1 -0
- package/dist/ssr/surfaces/ProgressRing.js +3 -0
- package/dist/ssr/surfaces/ProgressRing.js.map +1 -1
- package/dist/ssr/surfaces/ResourceCard.js +40 -15
- package/dist/ssr/surfaces/ResourceCard.js.map +1 -1
- package/dist/ssr/surfaces/index.js +2 -0
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/ssr/surfaces/person-color.js +18 -0
- package/dist/ssr/surfaces/person-color.js.map +1 -0
- package/dist/ssr/surfaces/resource-messages.js +6 -2
- package/dist/ssr/surfaces/resource-messages.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +1155 -0
- package/dist/ssr/text-editor/TextEditor.js.map +1 -0
- package/dist/ssr/text-editor/clipboard-html.js +152 -0
- package/dist/ssr/text-editor/clipboard-html.js.map +1 -0
- package/dist/ssr/text-editor/clipboard-loading.js +68 -0
- package/dist/ssr/text-editor/clipboard-loading.js.map +1 -0
- package/dist/ssr/text-editor/clipboard.js +51 -0
- package/dist/ssr/text-editor/clipboard.js.map +1 -0
- package/dist/ssr/text-editor/engine.js +125 -0
- package/dist/ssr/text-editor/engine.js.map +1 -0
- package/dist/ssr/text-editor/format.js +218 -0
- package/dist/ssr/text-editor/format.js.map +1 -0
- package/dist/ssr/text-editor/formatted.js +164 -0
- package/dist/ssr/text-editor/formatted.js.map +1 -0
- package/dist/ssr/text-editor/language.js +19 -0
- package/dist/ssr/text-editor/language.js.map +1 -0
- package/dist/ssr/text-editor/markdown-table.js +563 -0
- package/dist/ssr/text-editor/markdown-table.js.map +1 -0
- package/dist/ssr/text-editor/messages.js +233 -0
- package/dist/ssr/text-editor/messages.js.map +1 -0
- package/dist/ssr/text-editor/paste.js +115 -0
- package/dist/ssr/text-editor/paste.js.map +1 -0
- package/dist/ssr/text-editor/table.js +1760 -0
- package/dist/ssr/text-editor/table.js.map +1 -0
- package/dist/ssr/text-editor.js +5 -0
- package/dist/ssr/text-editor.js.map +1 -0
- package/dist/ssr/widgets/Widget.js +3 -2
- package/dist/ssr/widgets/Widget.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/ContextMenu.d.ts +5 -0
- package/dist/types/actions/Dropdown.d.ts +7 -0
- package/dist/types/actions/SelectionToolbar.d.ts +38 -0
- package/dist/types/actions/index.d.ts +2 -0
- package/dist/types/charts.d.ts +5 -0
- package/dist/types/chat/ChatComposer.d.ts +15 -0
- package/dist/types/chat/chat-messages.d.ts +2 -0
- package/dist/types/chat/composer-document.d.ts +5 -0
- package/dist/types/chat/index.d.ts +1 -1
- package/dist/types/content/Chart.d.ts +2 -1
- package/dist/types/content/FileGrid.d.ts +43 -3
- package/dist/types/content/FileTypeIcon.d.ts +10 -0
- package/dist/types/content/FileView.d.ts +5 -1
- package/dist/types/content/MatchText.d.ts +21 -0
- package/dist/types/content/MessageRow.d.ts +2 -0
- package/dist/types/content/calendar-day-scroll.d.ts +2 -1
- package/dist/types/content/chart-bar.d.ts +60 -0
- package/dist/types/content/file-list-messages.d.ts +24 -0
- package/dist/types/content/index.d.ts +3 -2
- package/dist/types/feedback/Tooltip.d.ts +8 -2
- package/dist/types/inputs/ChoiceList.d.ts +28 -0
- package/dist/types/inputs/ChoiceSlider.d.ts +36 -0
- package/dist/types/inputs/ChoiceTiles.d.ts +25 -0
- package/dist/types/inputs/ColorChoices.d.ts +19 -0
- package/dist/types/inputs/index.d.ts +8 -0
- package/dist/types/inputs/qr-messages.d.ts +1 -0
- package/dist/types/internal/radio-keys.d.ts +5 -0
- package/dist/types/layout/AnchoredPopover.d.ts +31 -0
- package/dist/types/layout/AppWorkspace.d.ts +10 -0
- package/dist/types/layout/DetailPanel.d.ts +17 -0
- package/dist/types/layout/MobileShell.d.ts +5 -2
- package/dist/types/layout/Settings.d.ts +22 -0
- package/dist/types/layout/SidebarRailHint.d.ts +26 -0
- package/dist/types/layout/TabBar.d.ts +5 -0
- package/dist/types/layout/detail-panel-messages.d.ts +1 -0
- package/dist/types/layout/index.d.ts +3 -2
- package/dist/types/layout/settings-messages.d.ts +12 -0
- package/dist/types/surfaces/DotStrip.d.ts +22 -0
- package/dist/types/surfaces/ProgressRing.d.ts +2 -1
- package/dist/types/surfaces/ResourceCard.d.ts +9 -0
- package/dist/types/surfaces/index.d.ts +4 -1
- package/dist/types/surfaces/person-color.d.ts +10 -0
- package/dist/types/surfaces/resource-messages.d.ts +2 -0
- package/dist/types/text-editor/TextEditor.d.ts +69 -0
- package/dist/types/text-editor/clipboard-html.d.ts +9 -0
- package/dist/types/text-editor/clipboard-loading.d.ts +8 -0
- package/dist/types/text-editor/clipboard.d.ts +20 -0
- package/dist/types/text-editor/engine.d.ts +34 -0
- package/dist/types/text-editor/format.d.ts +34 -0
- package/dist/types/text-editor/formatted.d.ts +1 -0
- package/dist/types/text-editor/language.d.ts +8 -0
- package/dist/types/text-editor/markdown-table.d.ts +105 -0
- package/dist/types/text-editor/messages.d.ts +113 -0
- package/dist/types/text-editor/paste.d.ts +6 -0
- package/dist/types/text-editor/table.d.ts +81 -0
- package/dist/types/text-editor.d.ts +4 -0
- package/dist/types/widgets/Widget.d.ts +3 -2
- package/package.json +28 -3
|
@@ -0,0 +1,1155 @@
|
|
|
1
|
+
import { ssrStyleProperty as _$ssrStyleProperty } from "solid-js/web";
|
|
2
|
+
import { ssrStyle as _$ssrStyle } from "solid-js/web";
|
|
3
|
+
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
4
|
+
import { memo as _$memo } from "solid-js/web";
|
|
5
|
+
import { ssr as _$ssr } from "solid-js/web";
|
|
6
|
+
import { escape as _$escape } from "solid-js/web";
|
|
7
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
8
|
+
var _tmpl$ = ["<div class=\"k2b-ste-size-picker\">", "", "</div>"],
|
|
9
|
+
_tmpl$2 = "<i class=\"ti ti-table\" aria-hidden=\"true\"></i>",
|
|
10
|
+
_tmpl$3 = ["<div", " popover=\"auto\" class=\"k2b-ste-size-popover\" role=\"dialog\"", " tabindex=\"-1\"><div class=\"k2b-ste-size-grid\" role=\"group\"", ">", "</div><div class=\"k2b-ste-size-caption\" role=\"status\">", "</div></div>"],
|
|
11
|
+
_tmpl$4 = ["<div class=\"k2b-ste-size-row\">", "</div>"],
|
|
12
|
+
_tmpl$5 = ["<button type=\"button\" tabindex=\"-1\"", "></button>"],
|
|
13
|
+
_tmpl$6 = ["<label class=\"k2b-ste-recovery-label\">", "<textarea class=\"k2b-ste-recovery\" readonly", "></textarea></label>"],
|
|
14
|
+
_tmpl$7 = ["<i", " aria-hidden=\"true\"></i>"],
|
|
15
|
+
_tmpl$8 = "<i class=\"ti ti-chevron-down\" aria-hidden=\"true\"></i>",
|
|
16
|
+
_tmpl$9 = ["<div class=\"k2b-ste-table-sheet-heading\"><span", ">", "</span>", "</div>"],
|
|
17
|
+
_tmpl$0 = ["<i class=\"", "\" aria-hidden=\"true\"></i>"],
|
|
18
|
+
_tmpl$1 = ["<span class=\"k2b-ste-check\"", "><i class=\"ti ti-alert-triangle\" aria-hidden=\"true\"></i>", "</span>"],
|
|
19
|
+
_tmpl$10 = ["<div class=\"k2b-ste-status\" role=\"status\"><span>", "</span>", "</div>"],
|
|
20
|
+
_tmpl$11 = ["<div class=\"k2b-ste-toolbar-slot\">", "</div>"],
|
|
21
|
+
_tmpl$12 = ["<div class=\"k2b-ste-loading\" role=\"status\"", ">", "</div>"],
|
|
22
|
+
_tmpl$13 = ["<div class=\"k2b-ste-floating-menu\"", " style=\"", "\">", "</div>"],
|
|
23
|
+
_tmpl$14 = "<i class=\"ti ti-x\" aria-hidden=\"true\"></i>",
|
|
24
|
+
_tmpl$15 = ["<div class=\"k2b-ste-notice\"><div class=\"k2b-ste-notice-content\">", "", "</div>", "</div>"],
|
|
25
|
+
_tmpl$16 = ["<div class=\"", "\"", "><span class=\"k2b-ste-announcement\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">", "</span>", "", "", "<div", "", "></div>", "<div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">", "</div></div>"],
|
|
26
|
+
_tmpl$17 = ["<div><span style=\"", "\"></span></div>"],
|
|
27
|
+
_tmpl$18 = ["<span>", "</span>"];
|
|
28
|
+
import { history, historyKeymap, redo, undo } from "@codemirror/commands";
|
|
29
|
+
import { EditorView, keymap } from "@codemirror/view";
|
|
30
|
+
import { clipboard } from "@k2b/stdlib/solid";
|
|
31
|
+
import { createEffect, createSignal, createUniqueId, For, onCleanup, onMount, Show, untrack } from "solid-js";
|
|
32
|
+
import { Button, IconButton } from "../actions/Button";
|
|
33
|
+
import { Dropdown } from "../actions/Dropdown";
|
|
34
|
+
import { SegmentedControl } from "../actions/SegmentedControl";
|
|
35
|
+
import { Toolbar } from "../actions/Toolbar";
|
|
36
|
+
import { Kbd } from "../content/Kbd";
|
|
37
|
+
import { dialogCore } from "../feedback/dialog-core";
|
|
38
|
+
import { NumberInput } from "../inputs/NumberInput";
|
|
39
|
+
import { LocaleProvider, useLocale } from "../intl/locale";
|
|
40
|
+
import { formatShortcut, keyboardPlatform } from "../intl/shortcut";
|
|
41
|
+
import BottomSheet, { bottomSheetAdaptiveOptions } from "../layout/BottomSheet";
|
|
42
|
+
import { createTextEditor } from "./engine";
|
|
43
|
+
import { commands, formatLabels } from "./format";
|
|
44
|
+
import { findTables, inspectTableStructure } from "./markdown-table";
|
|
45
|
+
import { textEditorMessages } from "./messages";
|
|
46
|
+
import { copyTable, editTableSource, formatActiveCell, runMenuAction, runTableAction, tableActionEnabled } from "./table";
|
|
47
|
+
/** Shared table-size control: pointer grid on desktop, large fields in a phone sheet. */
|
|
48
|
+
export function TableSizePicker(props) {
|
|
49
|
+
const locale = useLocale();
|
|
50
|
+
const t = () => textEditorMessages.resolve([locale()]).t;
|
|
51
|
+
const [rows, setRows] = createSignal(3);
|
|
52
|
+
const [columns, setColumns] = createSignal(3);
|
|
53
|
+
const [expanded, setExpanded] = createSignal(false);
|
|
54
|
+
const id = createUniqueId();
|
|
55
|
+
const abort = new AbortController();
|
|
56
|
+
let disposed = false;
|
|
57
|
+
onCleanup(() => {
|
|
58
|
+
disposed = true;
|
|
59
|
+
abort.abort();
|
|
60
|
+
});
|
|
61
|
+
let trigger;
|
|
62
|
+
let popup;
|
|
63
|
+
const reset = () => {
|
|
64
|
+
setRows(Math.min(3, props.maxRows));
|
|
65
|
+
setColumns(Math.min(3, props.maxColumns));
|
|
66
|
+
};
|
|
67
|
+
const choose = (r, c) => {
|
|
68
|
+
popup.hidePopover();
|
|
69
|
+
if (!disposed && !props.disabled) props.onPick({
|
|
70
|
+
rows: r,
|
|
71
|
+
columns: c
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
const open = async () => {
|
|
75
|
+
if (disposed || props.disabled || expanded()) return;
|
|
76
|
+
reset();
|
|
77
|
+
if (!window.matchMedia("(max-width: 47.999rem)").matches) {
|
|
78
|
+
popup.showPopover();
|
|
79
|
+
const anchor = trigger.getBoundingClientRect(),
|
|
80
|
+
box = popup.getBoundingClientRect();
|
|
81
|
+
popup.style.left = `${Math.max(8, Math.min(anchor.left, innerWidth - box.width - 8))}px`;
|
|
82
|
+
popup.style.top = `${Math.max(8, anchor.top > box.height + 8 ? anchor.top - box.height - 8 : Math.min(anchor.bottom + 8, innerHeight - box.height - 8))}px`;
|
|
83
|
+
popup.focus();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setExpanded(true);
|
|
87
|
+
const chosen = await dialogCore.open((close, context) => _$createComponent(LocaleProvider, {
|
|
88
|
+
get locale() {
|
|
89
|
+
return locale();
|
|
90
|
+
},
|
|
91
|
+
get children() {
|
|
92
|
+
return _$createComponent(BottomSheet, {
|
|
93
|
+
get onDismiss() {
|
|
94
|
+
return context.requestDismiss;
|
|
95
|
+
},
|
|
96
|
+
get children() {
|
|
97
|
+
return [_$createComponent(BottomSheet.Header, {
|
|
98
|
+
get title() {
|
|
99
|
+
return t().insertTable;
|
|
100
|
+
},
|
|
101
|
+
get close() {
|
|
102
|
+
return context.requestDismiss;
|
|
103
|
+
}
|
|
104
|
+
}), _$createComponent(BottomSheet.Body, {
|
|
105
|
+
get children() {
|
|
106
|
+
return _$ssr(_tmpl$, _$escape(_$createComponent(NumberInput, {
|
|
107
|
+
get label() {
|
|
108
|
+
return t().rows;
|
|
109
|
+
},
|
|
110
|
+
get value() {
|
|
111
|
+
return rows();
|
|
112
|
+
},
|
|
113
|
+
onValueChange: setRows,
|
|
114
|
+
min: 1,
|
|
115
|
+
get max() {
|
|
116
|
+
return props.maxRows;
|
|
117
|
+
},
|
|
118
|
+
step: 1
|
|
119
|
+
})), _$escape(_$createComponent(NumberInput, {
|
|
120
|
+
get label() {
|
|
121
|
+
return t().columns;
|
|
122
|
+
},
|
|
123
|
+
get value() {
|
|
124
|
+
return columns();
|
|
125
|
+
},
|
|
126
|
+
onValueChange: setColumns,
|
|
127
|
+
min: 1,
|
|
128
|
+
get max() {
|
|
129
|
+
return props.maxColumns;
|
|
130
|
+
},
|
|
131
|
+
step: 1
|
|
132
|
+
})));
|
|
133
|
+
}
|
|
134
|
+
}), _$createComponent(BottomSheet.Footer, {
|
|
135
|
+
get children() {
|
|
136
|
+
return _$createComponent(Button, {
|
|
137
|
+
get disabled() {
|
|
138
|
+
return !rows() || !columns();
|
|
139
|
+
},
|
|
140
|
+
onClick: () => {
|
|
141
|
+
const r = rows(),
|
|
142
|
+
c = columns();
|
|
143
|
+
if (r && c) close({
|
|
144
|
+
rows: r,
|
|
145
|
+
columns: c
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
get children() {
|
|
149
|
+
return t().insertSize({
|
|
150
|
+
rows: rows() ?? 0,
|
|
151
|
+
columns: columns() ?? 0
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
})];
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}), {
|
|
161
|
+
...bottomSheetAdaptiveOptions,
|
|
162
|
+
ariaLabel: t().insertTable,
|
|
163
|
+
history: true,
|
|
164
|
+
signal: abort.signal
|
|
165
|
+
});
|
|
166
|
+
setExpanded(false);
|
|
167
|
+
if (chosen && !disposed && !props.disabled) props.onPick(chosen);
|
|
168
|
+
};
|
|
169
|
+
onMount(() => props.onReady?.(() => void open()));
|
|
170
|
+
const keyboard = event => {
|
|
171
|
+
const directions = {
|
|
172
|
+
ArrowUp: [-1, 0],
|
|
173
|
+
ArrowDown: [1, 0],
|
|
174
|
+
ArrowLeft: [0, -1],
|
|
175
|
+
ArrowRight: [0, 1]
|
|
176
|
+
};
|
|
177
|
+
const direction = directions[event.key];
|
|
178
|
+
if (direction) {
|
|
179
|
+
event.preventDefault();
|
|
180
|
+
setRows(Math.max(1, Math.min(Math.min(9, props.maxRows), (rows() ?? 1) + direction[0])));
|
|
181
|
+
setColumns(Math.max(1, Math.min(Math.min(10, props.maxColumns), (columns() ?? 1) + direction[1])));
|
|
182
|
+
} else if (event.key === "Enter" || event.key === " ") {
|
|
183
|
+
event.preventDefault();
|
|
184
|
+
choose(rows() ?? 1, columns() ?? 1);
|
|
185
|
+
} else if (event.key === "Escape") trigger.focus();
|
|
186
|
+
};
|
|
187
|
+
return [_$createComponent(IconButton, {
|
|
188
|
+
variant: "ghost",
|
|
189
|
+
get ["class"]() {
|
|
190
|
+
return props.class;
|
|
191
|
+
},
|
|
192
|
+
get size() {
|
|
193
|
+
return props.size ?? "sm";
|
|
194
|
+
},
|
|
195
|
+
get disabled() {
|
|
196
|
+
return props.disabled;
|
|
197
|
+
},
|
|
198
|
+
get label() {
|
|
199
|
+
return t().insertTable;
|
|
200
|
+
},
|
|
201
|
+
"aria-haspopup": "dialog",
|
|
202
|
+
"aria-controls": id,
|
|
203
|
+
get ["aria-expanded"]() {
|
|
204
|
+
return expanded();
|
|
205
|
+
},
|
|
206
|
+
get tooltip() {
|
|
207
|
+
return t().insertTable;
|
|
208
|
+
},
|
|
209
|
+
onMouseDown: event => event.preventDefault(),
|
|
210
|
+
onClick: () => void open(),
|
|
211
|
+
get children() {
|
|
212
|
+
return _$ssr(_tmpl$2);
|
|
213
|
+
}
|
|
214
|
+
}), _$ssr(_tmpl$3, _$ssrAttribute("id", _$escape(id, true), false), _$ssrAttribute("aria-label", _$escape(t().insertTable, true), false), _$ssrAttribute("aria-label", _$escape(t().insertTable, true), false), _$escape(_$createComponent(For, {
|
|
215
|
+
get each() {
|
|
216
|
+
return Array.from({
|
|
217
|
+
length: Math.min(9, props.maxRows)
|
|
218
|
+
}, (_, index) => index + 1);
|
|
219
|
+
},
|
|
220
|
+
children: r => _$ssr(_tmpl$4, _$escape(_$createComponent(For, {
|
|
221
|
+
get each() {
|
|
222
|
+
return Array.from({
|
|
223
|
+
length: Math.min(10, props.maxColumns)
|
|
224
|
+
}, (_, index) => index + 1);
|
|
225
|
+
},
|
|
226
|
+
children: c => _$ssr(_tmpl$5, _$ssrAttribute("aria-label", _$escape(t().insertSize({
|
|
227
|
+
rows: r,
|
|
228
|
+
columns: c
|
|
229
|
+
}), true), false) + _$ssrAttribute("data-selected", r <= (rows() ?? 0) && c <= (columns() ?? 0) ? "true" : _$escape(undefined, true), false))
|
|
230
|
+
})))
|
|
231
|
+
})), _$escape(t().insertSize({
|
|
232
|
+
rows: rows() ?? 0,
|
|
233
|
+
columns: columns() ?? 0
|
|
234
|
+
})))];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Shared table controls for a host-owned toolbar (`toolbar={false}`). */
|
|
238
|
+
|
|
239
|
+
const toolbar = [["bold", "bold"], ["italic", "italic"], ["heading", "heading"], ["bulletList", "list"], ["orderedList", "list-numbers"], ["quote", "quote"], ["link", "link"], ["code", "code"], ["table", "table"], ["rule", "separator"]];
|
|
240
|
+
const actionIcons = {
|
|
241
|
+
rowAbove: "row-insert-top",
|
|
242
|
+
rowBelow: "row-insert-bottom",
|
|
243
|
+
colLeft: "column-insert-left",
|
|
244
|
+
colRight: "column-insert-right",
|
|
245
|
+
alignLeft: "align-left",
|
|
246
|
+
alignCenter: "align-center",
|
|
247
|
+
alignRight: "align-right",
|
|
248
|
+
deleteRow: "row-remove",
|
|
249
|
+
deleteCol: "column-remove",
|
|
250
|
+
moveRowUp: "arrow-up",
|
|
251
|
+
moveRowDown: "arrow-down",
|
|
252
|
+
moveColLeft: "arrow-left",
|
|
253
|
+
moveColRight: "arrow-right",
|
|
254
|
+
toggleHeader: "table-row",
|
|
255
|
+
deleteTable: "trash"
|
|
256
|
+
};
|
|
257
|
+
const isInlineCommand = command => inlineCommands.has(command);
|
|
258
|
+
const shortcuts = {
|
|
259
|
+
bold: "mod+b",
|
|
260
|
+
italic: "mod+i",
|
|
261
|
+
link: "mod+k"
|
|
262
|
+
};
|
|
263
|
+
const inlineCommands = new Set(["bold", "italic", "code", "link", "strike"]);
|
|
264
|
+
|
|
265
|
+
/** A Markdown text field with app-injected collaboration and a directly editable table view. */
|
|
266
|
+
export function TextEditor(props) {
|
|
267
|
+
const locale = useLocale();
|
|
268
|
+
const t = () => textEditorMessages.resolve([locale()]).t;
|
|
269
|
+
const [mode, setMode] = createSignal(props.mode ?? "formatted");
|
|
270
|
+
const [ready, setReady] = createSignal(false);
|
|
271
|
+
const [recovery, setRecovery] = createSignal();
|
|
272
|
+
const [notice, setNotice] = createSignal();
|
|
273
|
+
const [cell, setCell] = createSignal();
|
|
274
|
+
const [localSource, setLocalSource] = createSignal(false);
|
|
275
|
+
const [announcement, setAnnouncement] = createSignal("");
|
|
276
|
+
const [check, setCheck] = createSignal(false);
|
|
277
|
+
const [missingSeparator, setMissingSeparator] = createSignal(false);
|
|
278
|
+
const [active, setActive] = createSignal(false);
|
|
279
|
+
const [documentRevision, setDocumentRevision] = createSignal(0);
|
|
280
|
+
const [phoneMenu, setPhoneMenu] = createSignal(false);
|
|
281
|
+
const [platform, setPlatform] = createSignal("other");
|
|
282
|
+
createEffect(() => {
|
|
283
|
+
const target = cell();
|
|
284
|
+
target?.setAttribute("data-active", "");
|
|
285
|
+
onCleanup(() => target?.removeAttribute("data-active"));
|
|
286
|
+
});
|
|
287
|
+
let disposed = false;
|
|
288
|
+
onCleanup(() => {
|
|
289
|
+
disposed = true;
|
|
290
|
+
const text = recovery();
|
|
291
|
+
if (text !== undefined) detachedRecovery(text);
|
|
292
|
+
});
|
|
293
|
+
// A local draft can outlive an island during navigation. Keep its recovery
|
|
294
|
+
// surface in the shared dialog root so disposal never silently drops it.
|
|
295
|
+
const detachedRecovery = text => {
|
|
296
|
+
const language = locale();
|
|
297
|
+
const labels = t();
|
|
298
|
+
const beforeUnload = event => {
|
|
299
|
+
event.preventDefault();
|
|
300
|
+
event.returnValue = "";
|
|
301
|
+
};
|
|
302
|
+
window.addEventListener("beforeunload", beforeUnload);
|
|
303
|
+
const show = () => void dialogCore.open((close, context) => {
|
|
304
|
+
context.setDismissHandler(() => {});
|
|
305
|
+
return _$createComponent(LocaleProvider, {
|
|
306
|
+
locale: language,
|
|
307
|
+
get children() {
|
|
308
|
+
return _$createComponent(BottomSheet, {
|
|
309
|
+
handle: false,
|
|
310
|
+
onDismiss: () => {},
|
|
311
|
+
get children() {
|
|
312
|
+
return [_$createComponent(BottomSheet.Header, {
|
|
313
|
+
get title() {
|
|
314
|
+
return labels.recoveredInput;
|
|
315
|
+
}
|
|
316
|
+
}), _$createComponent(BottomSheet.Body, {
|
|
317
|
+
get children() {
|
|
318
|
+
return _$ssr(_tmpl$6, _$escape(labels.recoveredInput), _$ssrAttribute("value", _$escape(text, true), false));
|
|
319
|
+
}
|
|
320
|
+
}), _$createComponent(BottomSheet.Footer, {
|
|
321
|
+
get children() {
|
|
322
|
+
return _$createComponent(Button, {
|
|
323
|
+
variant: "ghost",
|
|
324
|
+
onClick: () => close("discard"),
|
|
325
|
+
get children() {
|
|
326
|
+
return labels.discardRecovery;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
})];
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}, {
|
|
336
|
+
...bottomSheetAdaptiveOptions,
|
|
337
|
+
ariaLabel: labels.recoveredInput
|
|
338
|
+
}).then(result => {
|
|
339
|
+
if (result === "discard") window.removeEventListener("beforeunload", beforeUnload);
|
|
340
|
+
// The shared dialog root closes on each island disposal. Retain the
|
|
341
|
+
// draft across subsequent navigation until the person explicitly discards it.
|
|
342
|
+
else queueMicrotask(show);
|
|
343
|
+
});
|
|
344
|
+
show();
|
|
345
|
+
};
|
|
346
|
+
let menuOpen = false;
|
|
347
|
+
let pointerAnchor;
|
|
348
|
+
let floatingTrigger;
|
|
349
|
+
const tableTriggers = new Set();
|
|
350
|
+
let frame = 0;
|
|
351
|
+
const [menuPosition, setMenuPosition] = createSignal({
|
|
352
|
+
left: "0px",
|
|
353
|
+
top: "0px"
|
|
354
|
+
});
|
|
355
|
+
let root;
|
|
356
|
+
let mount;
|
|
357
|
+
let editor;
|
|
358
|
+
const menuBlocked = () => !!props.loading || !ready() || recovery() !== undefined;
|
|
359
|
+
const blocked = () => !!props.readOnly || menuBlocked();
|
|
360
|
+
const updateCheck = () => {
|
|
361
|
+
const issue = mode() === "plain" ? {
|
|
362
|
+
extraCells: false,
|
|
363
|
+
missingSeparator: false
|
|
364
|
+
} : inspectTableStructure(editor?.view.state.doc.toString() ?? props.initialValue ?? "");
|
|
365
|
+
const needsCheck = issue.extraCells || issue.missingSeparator;
|
|
366
|
+
setMissingSeparator(issue.missingSeparator);
|
|
367
|
+
setCheck(needsCheck);
|
|
368
|
+
props.onTableCheck?.(needsCheck);
|
|
369
|
+
};
|
|
370
|
+
const positionMenu = () => {
|
|
371
|
+
const target = cell();
|
|
372
|
+
if (!target) return;
|
|
373
|
+
const wrap = target.closest(".k2b-ste-table");
|
|
374
|
+
const table = wrap?.querySelector("table");
|
|
375
|
+
if (!target.isConnected || !wrap || !table || mode() !== "formatted") {
|
|
376
|
+
menuOpen = false;
|
|
377
|
+
setCell(undefined);
|
|
378
|
+
checkFocus();
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const rect = target.getBoundingClientRect();
|
|
382
|
+
const bounds = root.getBoundingClientRect();
|
|
383
|
+
const right = Math.min(table.getBoundingClientRect().right, wrap.getBoundingClientRect().right);
|
|
384
|
+
const position = props.readOnly ? {
|
|
385
|
+
left: `${wrap.getBoundingClientRect().left - bounds.left}px`,
|
|
386
|
+
top: `${wrap.getBoundingClientRect().bottom - bounds.top - (window.matchMedia("(max-width: 47.999rem)").matches ? 44 : 0)}px`
|
|
387
|
+
} : {
|
|
388
|
+
left: `${right - bounds.left - 24}px`,
|
|
389
|
+
top: `${rect.top - bounds.top + (rect.height - 24) / 2}px`
|
|
390
|
+
};
|
|
391
|
+
setMenuPosition(pointerAnchor ?? position);
|
|
392
|
+
};
|
|
393
|
+
const schedulePosition = () => {
|
|
394
|
+
if (!frame) frame = requestAnimationFrame(() => {
|
|
395
|
+
frame = 0;
|
|
396
|
+
positionMenu();
|
|
397
|
+
});
|
|
398
|
+
};
|
|
399
|
+
const unavailable = () => !!props.host?.structure && !props.host.structure.available();
|
|
400
|
+
const actionDisabled = action => {
|
|
401
|
+
documentRevision();
|
|
402
|
+
const wrap = cell()?.closest(".k2b-ste-table");
|
|
403
|
+
return blocked() || !editor || !wrap || !tableActionEnabled(editor.view, wrap, action);
|
|
404
|
+
};
|
|
405
|
+
const isMove = action => action.startsWith("move");
|
|
406
|
+
const runAction = action => {
|
|
407
|
+
const wrap = cell()?.closest(".k2b-ste-table");
|
|
408
|
+
const focused = document.activeElement;
|
|
409
|
+
const menuElement = focused instanceof HTMLElement ? focused.closest('[role="menu"]') : null;
|
|
410
|
+
if (editor && wrap && !actionDisabled(action)) runMenuAction(editor.view, wrap, action);
|
|
411
|
+
// The phone move sheet remains usable for another move. Local structural
|
|
412
|
+
// focus belongs to the cell only after the menu has closed.
|
|
413
|
+
if (isMove(action) && focused instanceof HTMLElement && menuElement) {
|
|
414
|
+
const restore = () => {
|
|
415
|
+
if (disposed || !menuElement.isConnected) return;
|
|
416
|
+
const target = focused.isConnected && !focused.matches(":disabled") ? focused : menuElement.querySelector('[role^="menuitem"]:not(:disabled)');
|
|
417
|
+
target?.focus({
|
|
418
|
+
preventScroll: true
|
|
419
|
+
});
|
|
420
|
+
};
|
|
421
|
+
restore();
|
|
422
|
+
queueMicrotask(restore);
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
const moveKeys = {
|
|
426
|
+
moveRowUp: "alt+arrowup",
|
|
427
|
+
moveRowDown: "alt+arrowdown",
|
|
428
|
+
moveColLeft: "alt+arrowleft",
|
|
429
|
+
moveColRight: "alt+arrowright"
|
|
430
|
+
};
|
|
431
|
+
const shortActionLabels = {
|
|
432
|
+
rowAbove: "menuAbove",
|
|
433
|
+
rowBelow: "menuBelow",
|
|
434
|
+
moveRowUp: "menuUp",
|
|
435
|
+
moveRowDown: "menuDown",
|
|
436
|
+
deleteRow: "menuDelete",
|
|
437
|
+
colLeft: "menuInsertLeft",
|
|
438
|
+
colRight: "menuInsertRight",
|
|
439
|
+
moveColLeft: "menuMoveLeft",
|
|
440
|
+
moveColRight: "menuMoveRight",
|
|
441
|
+
deleteCol: "menuDelete"
|
|
442
|
+
};
|
|
443
|
+
const menuRow = () => {
|
|
444
|
+
documentRevision();
|
|
445
|
+
return t().menuRow(Number(cell()?.dataset.r ?? 0));
|
|
446
|
+
};
|
|
447
|
+
const menuColumn = () => {
|
|
448
|
+
documentRevision();
|
|
449
|
+
const column = Number(cell()?.dataset.c ?? 0);
|
|
450
|
+
const header = cell()?.closest(".k2b-ste-table")?.querySelector(`.k2b-ste-cell[data-r="0"][data-c="${column}"]`);
|
|
451
|
+
return t().menuColumn(header?.dataset.raw || t().column(column + 1));
|
|
452
|
+
};
|
|
453
|
+
const menuHeading = () => `${menuRow()} · ${menuColumn()}`;
|
|
454
|
+
const actionItem = (action, choice) => ({
|
|
455
|
+
get label() {
|
|
456
|
+
return phoneMenu() && action in shortActionLabels ? t()[shortActionLabels[action]] : t()[action];
|
|
457
|
+
},
|
|
458
|
+
icon: `ti ti-${actionIcons[action]}`,
|
|
459
|
+
get disabled() {
|
|
460
|
+
return actionDisabled(action);
|
|
461
|
+
},
|
|
462
|
+
immediate: true,
|
|
463
|
+
trailing: moveKeys[action] ? _$createComponent(Kbd, {
|
|
464
|
+
get keys() {
|
|
465
|
+
return moveKeys[action];
|
|
466
|
+
}
|
|
467
|
+
}) : action === "rowBelow" ? _$createComponent(Kbd, {
|
|
468
|
+
keys: "enter"
|
|
469
|
+
}) : undefined,
|
|
470
|
+
variant: action === "deleteRow" || action === "deleteCol" || action === "deleteTable" ? "danger" : undefined,
|
|
471
|
+
closeOnSelect: !isMove(action),
|
|
472
|
+
action: () => runAction(action),
|
|
473
|
+
...choice
|
|
474
|
+
});
|
|
475
|
+
const [copying, setCopying] = createSignal(false);
|
|
476
|
+
const tableCopy = clipboard.createWriter({
|
|
477
|
+
write: ({
|
|
478
|
+
view,
|
|
479
|
+
wrap,
|
|
480
|
+
format
|
|
481
|
+
}) => copyTable(view, wrap, format)
|
|
482
|
+
});
|
|
483
|
+
const copy = async format => {
|
|
484
|
+
const wrap = cell()?.closest(".k2b-ste-table");
|
|
485
|
+
if (!editor || !wrap || copying()) return;
|
|
486
|
+
setCopying(true);
|
|
487
|
+
setNotice({
|
|
488
|
+
message: t().copyingTable
|
|
489
|
+
});
|
|
490
|
+
const success = await tableCopy.copy({
|
|
491
|
+
view: editor.view,
|
|
492
|
+
wrap,
|
|
493
|
+
format
|
|
494
|
+
});
|
|
495
|
+
if (disposed) return;
|
|
496
|
+
setCopying(false);
|
|
497
|
+
setNotice({
|
|
498
|
+
message: success ? format === "table" ? t().copiedTable : t().copiedMarkdown : t().copyFailed
|
|
499
|
+
});
|
|
500
|
+
};
|
|
501
|
+
const copyItems = () => [{
|
|
502
|
+
get label() {
|
|
503
|
+
return phoneMenu() && !props.readOnly ? t().menuCopy : t().copyTable;
|
|
504
|
+
},
|
|
505
|
+
icon: "ti ti-copy",
|
|
506
|
+
get disabled() {
|
|
507
|
+
return copying();
|
|
508
|
+
},
|
|
509
|
+
immediate: true,
|
|
510
|
+
action: () => {
|
|
511
|
+
void copy("table");
|
|
512
|
+
}
|
|
513
|
+
}, {
|
|
514
|
+
get label() {
|
|
515
|
+
return phoneMenu() && !props.readOnly ? t().menuMarkdown : t().copyMarkdown;
|
|
516
|
+
},
|
|
517
|
+
icon: "ti ti-markdown",
|
|
518
|
+
get disabled() {
|
|
519
|
+
return copying();
|
|
520
|
+
},
|
|
521
|
+
immediate: true,
|
|
522
|
+
action: () => {
|
|
523
|
+
void copy("markdown");
|
|
524
|
+
}
|
|
525
|
+
}];
|
|
526
|
+
const items = () => {
|
|
527
|
+
if (props.readOnly) return copyItems();
|
|
528
|
+
const align = () => {
|
|
529
|
+
documentRevision();
|
|
530
|
+
return cell()?.parentElement?.style.textAlign || "left";
|
|
531
|
+
};
|
|
532
|
+
return [{
|
|
533
|
+
get sectionLabel() {
|
|
534
|
+
return menuHeading();
|
|
535
|
+
},
|
|
536
|
+
items: []
|
|
537
|
+
}, {
|
|
538
|
+
get sectionLabel() {
|
|
539
|
+
return menuRow();
|
|
540
|
+
},
|
|
541
|
+
items: ["rowAbove", "rowBelow", "moveRowUp", "moveRowDown", "deleteRow"].map(action => actionItem(action))
|
|
542
|
+
}, {
|
|
543
|
+
get sectionLabel() {
|
|
544
|
+
return menuColumn();
|
|
545
|
+
},
|
|
546
|
+
items: ["colLeft", "colRight", "moveColLeft", "moveColRight"].map(action => actionItem(action))
|
|
547
|
+
}, {
|
|
548
|
+
sectionLabel: t().alignment,
|
|
549
|
+
layout: "row",
|
|
550
|
+
items: ["alignLeft", "alignCenter", "alignRight"].map((action, index) => actionItem(action, {
|
|
551
|
+
choice: "radio",
|
|
552
|
+
class: "k2b-ste-align-choice",
|
|
553
|
+
ariaLabel: t()[action],
|
|
554
|
+
checked: () => align() === ["left", "center", "right"][index]
|
|
555
|
+
}))
|
|
556
|
+
}, {
|
|
557
|
+
items: [actionItem("deleteCol")]
|
|
558
|
+
}, {
|
|
559
|
+
sectionLabel: t().table,
|
|
560
|
+
items: [actionItem("toggleHeader", {
|
|
561
|
+
choice: "checkbox",
|
|
562
|
+
class: "k2b-ste-header-choice",
|
|
563
|
+
checked: () => {
|
|
564
|
+
documentRevision();
|
|
565
|
+
return cell()?.closest(".k2b-ste-table")?.dataset.header === "true";
|
|
566
|
+
}
|
|
567
|
+
}), {
|
|
568
|
+
label: t().editMarkdown,
|
|
569
|
+
icon: "ti ti-markdown",
|
|
570
|
+
action: () => {
|
|
571
|
+
const wrap = cell()?.closest(".k2b-ste-table");
|
|
572
|
+
if (editor && wrap) editTableSource(editor.view, wrap);
|
|
573
|
+
}
|
|
574
|
+
}, ...copyItems(), actionItem("deleteTable"), ...(unavailable() ? [{
|
|
575
|
+
label: t().structureUnavailable,
|
|
576
|
+
disabled: true
|
|
577
|
+
}] : [])]
|
|
578
|
+
}];
|
|
579
|
+
};
|
|
580
|
+
const preserveSelection = event => event.preventDefault();
|
|
581
|
+
const menuChange = open => {
|
|
582
|
+
menuOpen = open;
|
|
583
|
+
};
|
|
584
|
+
const menuClose = () => {
|
|
585
|
+
menuOpen = false;
|
|
586
|
+
pointerAnchor = undefined;
|
|
587
|
+
schedulePosition();
|
|
588
|
+
queueMicrotask(() => {
|
|
589
|
+
if (disposed) return;
|
|
590
|
+
const focused = document.activeElement;
|
|
591
|
+
if (focused instanceof HTMLElement && focused.matches(".k2b-ste-cell-menu, .k2b-ste-table-tool")) cell()?.focus();
|
|
592
|
+
checkFocus();
|
|
593
|
+
});
|
|
594
|
+
};
|
|
595
|
+
const menu = (floating, trigger) => // A sheet owns its item inventory until it closes. Replace that owner when
|
|
596
|
+
// edit access changes so an already open sheet cannot retain edit entries.
|
|
597
|
+
_$createComponent(Show, {
|
|
598
|
+
get when() {
|
|
599
|
+
return props.readOnly ? "read" : "write";
|
|
600
|
+
},
|
|
601
|
+
keyed: true,
|
|
602
|
+
children: _access => _$createComponent(Dropdown, {
|
|
603
|
+
get items() {
|
|
604
|
+
return items();
|
|
605
|
+
},
|
|
606
|
+
phone: "sheet",
|
|
607
|
+
get sheetTop() {
|
|
608
|
+
return props.readOnly ? undefined : close => _$ssr(_tmpl$9, _$ssrAttribute("title", _$escape(menuHeading(), true), false), _$escape(menuHeading()), _$escape(_$createComponent(Button, {
|
|
609
|
+
variant: "ghost",
|
|
610
|
+
onClick: close,
|
|
611
|
+
get children() {
|
|
612
|
+
return t().done;
|
|
613
|
+
}
|
|
614
|
+
})));
|
|
615
|
+
},
|
|
616
|
+
menuClass: "k2b-ste-table-menu",
|
|
617
|
+
get position() {
|
|
618
|
+
return floating ? "right-start" : trigger?.position ?? "bottom-right";
|
|
619
|
+
},
|
|
620
|
+
width: "18rem",
|
|
621
|
+
get label() {
|
|
622
|
+
return _$memo(() => !!props.readOnly)() ? t().copyTable : t().tableMenu;
|
|
623
|
+
},
|
|
624
|
+
get disabled() {
|
|
625
|
+
return menuBlocked() || localSource() || !cell()?.isConnected;
|
|
626
|
+
},
|
|
627
|
+
onOpenChange: menuChange,
|
|
628
|
+
onClose: menuClose,
|
|
629
|
+
get children() {
|
|
630
|
+
return _$createComponent(Dropdown.Trigger, {
|
|
631
|
+
get ["class"]() {
|
|
632
|
+
return floating ? props.readOnly ? "k2b-ste-cell-menu k2b-ste-copy-menu" : "k2b-ste-cell-menu" : `k2b-ste-tool k2b-ste-table-tool ${trigger?.class ?? ""}`;
|
|
633
|
+
},
|
|
634
|
+
variant: "ghost",
|
|
635
|
+
get size() {
|
|
636
|
+
return trigger?.size ?? "sm";
|
|
637
|
+
},
|
|
638
|
+
get iconOnly() {
|
|
639
|
+
return _$memo(() => !!!trigger?.text)() && !props.readOnly;
|
|
640
|
+
},
|
|
641
|
+
get label() {
|
|
642
|
+
return trigger?.text ?? (props.readOnly ? t().copyTable : t().tableMenu);
|
|
643
|
+
},
|
|
644
|
+
"aria-pressed": !floating ? true : undefined,
|
|
645
|
+
onMouseDown: preserveSelection,
|
|
646
|
+
get children() {
|
|
647
|
+
return [_$ssr(_tmpl$7, _$ssrAttribute("class", props.readOnly ? "ti ti-copy" : floating ? "ti ti-dots" : "ti ti-table", false)), trigger?.text ?? (props.readOnly ? t().copyTable : undefined), _$createComponent(Show, {
|
|
648
|
+
get when() {
|
|
649
|
+
return trigger?.text;
|
|
650
|
+
},
|
|
651
|
+
get children() {
|
|
652
|
+
return _$ssr(_tmpl$8);
|
|
653
|
+
}
|
|
654
|
+
})];
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
})
|
|
659
|
+
});
|
|
660
|
+
const runFormat = command => {
|
|
661
|
+
if (!editor || blocked()) return;
|
|
662
|
+
if (cell()?.isConnected && isInlineCommand(command) && formatActiveCell(editor.view, command)) return;
|
|
663
|
+
commands[command](editor.view);
|
|
664
|
+
};
|
|
665
|
+
const checkFocus = () => {
|
|
666
|
+
if (disposed) return;
|
|
667
|
+
// A host toolbar sits outside this root. Native popover focus moves before
|
|
668
|
+
// its toggle callback, but Dropdown already exposes its synchronous state.
|
|
669
|
+
if (menuOpen || [...tableTriggers, floatingTrigger].some(trigger => trigger?.isConnected && trigger.getAttribute("aria-expanded") === "true")) return;
|
|
670
|
+
const focused = document.activeElement;
|
|
671
|
+
setLocalSource(focused instanceof HTMLElement && !!focused.closest(".k2b-ste-table-source"));
|
|
672
|
+
const inside = focused instanceof Node && root.contains(focused);
|
|
673
|
+
setActive(inside);
|
|
674
|
+
if (!inside || focused === editor?.view.contentDOM) setCell(undefined);else if (!cell()?.isConnected) setCell(undefined);
|
|
675
|
+
};
|
|
676
|
+
const formatMenu = command => _$createComponent(Dropdown, {
|
|
677
|
+
phone: "sheet",
|
|
678
|
+
get label() {
|
|
679
|
+
return t()[command];
|
|
680
|
+
},
|
|
681
|
+
get disabled() {
|
|
682
|
+
return blocked() || command === "heading" && !!cell();
|
|
683
|
+
},
|
|
684
|
+
onOpenChange: menuChange,
|
|
685
|
+
onClose: menuClose,
|
|
686
|
+
get items() {
|
|
687
|
+
return command === "heading" ? [{
|
|
688
|
+
items: ["heading1", "heading2", "heading3"].map((name, index) => ({
|
|
689
|
+
label: t()[name],
|
|
690
|
+
icon: `ti ti-h-${index + 1}`,
|
|
691
|
+
action: () => runFormat(name)
|
|
692
|
+
}))
|
|
693
|
+
}] : [{
|
|
694
|
+
label: t().inlineCode,
|
|
695
|
+
icon: "ti ti-code",
|
|
696
|
+
action: () => runFormat("code")
|
|
697
|
+
}, {
|
|
698
|
+
label: t().codeBlock,
|
|
699
|
+
icon: "ti ti-source-code",
|
|
700
|
+
disabled: !!cell(),
|
|
701
|
+
action: () => runFormat("codeBlock")
|
|
702
|
+
}, {
|
|
703
|
+
label: t().strike,
|
|
704
|
+
icon: "ti ti-strikethrough",
|
|
705
|
+
trailing: _$createComponent(Kbd, {
|
|
706
|
+
keys: "mod+shift+x"
|
|
707
|
+
}),
|
|
708
|
+
action: () => runFormat("strike")
|
|
709
|
+
}];
|
|
710
|
+
},
|
|
711
|
+
get children() {
|
|
712
|
+
return _$createComponent(Dropdown.Trigger, {
|
|
713
|
+
"class": "k2b-ste-tool",
|
|
714
|
+
variant: "ghost",
|
|
715
|
+
size: "sm",
|
|
716
|
+
iconOnly: true,
|
|
717
|
+
get label() {
|
|
718
|
+
return t()[command];
|
|
719
|
+
},
|
|
720
|
+
onMouseDown: preserveSelection,
|
|
721
|
+
get children() {
|
|
722
|
+
return _$ssr(_tmpl$0, `ti ti-${_$escape(command, true)}`);
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
const selectMode = next => {
|
|
728
|
+
const restoreEditorFocus = !!editor?.view.contentDOM.contains(document.activeElement);
|
|
729
|
+
menuOpen = false;
|
|
730
|
+
setCell(undefined);
|
|
731
|
+
setMode(next);
|
|
732
|
+
props.onModeChange?.(next);
|
|
733
|
+
if (restoreEditorFocus) queueMicrotask(() => editor?.view.focus());
|
|
734
|
+
};
|
|
735
|
+
onMount(() => {
|
|
736
|
+
setPlatform(keyboardPlatform());
|
|
737
|
+
const menuMedia = window.matchMedia("(max-width: 47.999rem)");
|
|
738
|
+
const menuViewport = () => setPhoneMenu(menuMedia.matches);
|
|
739
|
+
menuViewport();
|
|
740
|
+
menuMedia.addEventListener("change", menuViewport);
|
|
741
|
+
onCleanup(() => menuMedia.removeEventListener("change", menuViewport));
|
|
742
|
+
// A standalone editor has no binding history; collaboration supplies its own instead.
|
|
743
|
+
const nativeHistory = !props.host?.undo;
|
|
744
|
+
editor = createTextEditor({
|
|
745
|
+
parent: mount,
|
|
746
|
+
doc: props.initialValue,
|
|
747
|
+
mode: mode(),
|
|
748
|
+
label: props.label,
|
|
749
|
+
readOnly: props.readOnly,
|
|
750
|
+
placeholder: props.placeholder,
|
|
751
|
+
presentation: props.presentation,
|
|
752
|
+
extensions: [nativeHistory ? [history(), keymap.of(historyKeymap)] : [], formatLabels.of({
|
|
753
|
+
get link() {
|
|
754
|
+
return t().link;
|
|
755
|
+
},
|
|
756
|
+
column: column => t().column(column)
|
|
757
|
+
}), EditorView.updateListener.of(update => {
|
|
758
|
+
schedulePosition();
|
|
759
|
+
if (update.docChanged) queueMicrotask(() => setDocumentRevision(revision => revision + 1));
|
|
760
|
+
}), props.extensions ?? []],
|
|
761
|
+
host: {
|
|
762
|
+
...props.host,
|
|
763
|
+
undo: props.host?.undo ?? (() => editor && undo(editor.view)),
|
|
764
|
+
redo: props.host?.redo ?? (() => editor && redo(editor.view)),
|
|
765
|
+
boundary: props.host?.boundary ?? (() => {}),
|
|
766
|
+
cellLabel: (row, column, name) => t().cellLabel({
|
|
767
|
+
row,
|
|
768
|
+
column,
|
|
769
|
+
name
|
|
770
|
+
}),
|
|
771
|
+
actionLabel: name => t()[name],
|
|
772
|
+
sourceLabels: () => ({
|
|
773
|
+
edit: t().editMarkdown,
|
|
774
|
+
valid: t().markdownValid,
|
|
775
|
+
invalid: t().markdownInvalid,
|
|
776
|
+
changed: t().markdownChanged,
|
|
777
|
+
structural: t().markdownStructural,
|
|
778
|
+
applying: t().applyingTable,
|
|
779
|
+
applyFailed: t().markdownApplyFailed,
|
|
780
|
+
done: phoneMenu() ? t().done : t().showTable,
|
|
781
|
+
discard: t().discardMarkdown,
|
|
782
|
+
continue: t().continueMarkdown,
|
|
783
|
+
line: t().markdownLine,
|
|
784
|
+
separator: (header, separator) => t().markdownSeparator({
|
|
785
|
+
header,
|
|
786
|
+
separator
|
|
787
|
+
}),
|
|
788
|
+
extra: t().markdownExtra,
|
|
789
|
+
complete: t().completeColumns
|
|
790
|
+
}),
|
|
791
|
+
maxLength: props.maxLength,
|
|
792
|
+
maxPasteCells: props.maxPasteCells ?? 2000,
|
|
793
|
+
onRecovery: text => {
|
|
794
|
+
if (disposed) detachedRecovery(text);else setRecovery(previous => previous === undefined ? text : `${previous}\n\n${text}`);
|
|
795
|
+
},
|
|
796
|
+
onError: code => setNotice({
|
|
797
|
+
message: t()[code]
|
|
798
|
+
})
|
|
799
|
+
},
|
|
800
|
+
onChange: text => {
|
|
801
|
+
props.onChange?.(text);
|
|
802
|
+
queueMicrotask(updateCheck);
|
|
803
|
+
},
|
|
804
|
+
onDroppedImages: (count, files) => {
|
|
805
|
+
if (props.onDroppedImages?.(count, files) !== true) setNotice({
|
|
806
|
+
message: t().imageHint,
|
|
807
|
+
images: true
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
const focus = event => {
|
|
812
|
+
if (!(event instanceof CustomEvent) || !(event.detail.cell instanceof HTMLElement)) return;
|
|
813
|
+
setActive(true);
|
|
814
|
+
if (!menuOpen) pointerAnchor = undefined;
|
|
815
|
+
setCell(event.detail.cell);
|
|
816
|
+
positionMenu();
|
|
817
|
+
};
|
|
818
|
+
const structureAnnouncement = event => {
|
|
819
|
+
if (!(event instanceof CustomEvent)) return;
|
|
820
|
+
const detail = event.detail;
|
|
821
|
+
if (detail && typeof detail === "object" && "rows" in detail && "columns" in detail && typeof detail.rows === "number" && typeof detail.columns === "number") setAnnouncement(t().tableChanged({
|
|
822
|
+
rows: detail.rows,
|
|
823
|
+
columns: detail.columns
|
|
824
|
+
}));
|
|
825
|
+
};
|
|
826
|
+
const focusChange = () => queueMicrotask(checkFocus);
|
|
827
|
+
let pointerCheck;
|
|
828
|
+
const pointer = event => {
|
|
829
|
+
if (event.target instanceof Node && root.contains(event.target)) setActive(true);
|
|
830
|
+
// After the press moved focus: a host toolbar control that keeps focus in the cell keeps it active.
|
|
831
|
+
else if (!menuOpen) {
|
|
832
|
+
clearTimeout(pointerCheck);
|
|
833
|
+
pointerCheck = setTimeout(checkFocus);
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
const keyboardMenu = event => {
|
|
837
|
+
if (menuBlocked()) return;
|
|
838
|
+
focus(event);
|
|
839
|
+
if (event instanceof CustomEvent) {
|
|
840
|
+
const bounds = root.getBoundingClientRect();
|
|
841
|
+
const anchor = event.detail.anchor instanceof HTMLElement ? event.detail.anchor.getBoundingClientRect() : undefined;
|
|
842
|
+
if (anchor || typeof event.detail.x === "number") {
|
|
843
|
+
pointerAnchor = {
|
|
844
|
+
left: `${(anchor?.left ?? event.detail.x) - bounds.left}px`,
|
|
845
|
+
top: `${(anchor?.bottom ?? event.detail.y) - bounds.top}px`
|
|
846
|
+
};
|
|
847
|
+
positionMenu();
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
queueMicrotask(() => {
|
|
851
|
+
if (disposed || !cell()?.isConnected) return;
|
|
852
|
+
const tableTrigger = [...tableTriggers].find(trigger => trigger.isConnected);
|
|
853
|
+
const trigger = (window.matchMedia("(max-width: 47.999rem)").matches && tableTrigger?.isConnected ? tableTrigger : undefined) ?? floatingTrigger;
|
|
854
|
+
trigger?.click();
|
|
855
|
+
});
|
|
856
|
+
};
|
|
857
|
+
const mutations = new MutationObserver(schedulePosition);
|
|
858
|
+
mutations.observe(mount, {
|
|
859
|
+
childList: true,
|
|
860
|
+
subtree: true,
|
|
861
|
+
characterData: true
|
|
862
|
+
});
|
|
863
|
+
const resize = new ResizeObserver(schedulePosition);
|
|
864
|
+
resize.observe(mount);
|
|
865
|
+
// Safari blurs a contenteditable on mouse-down without focusing the radio.
|
|
866
|
+
// Keep the caret and phone toolbar stationary until the view switch runs.
|
|
867
|
+
const viewMouseDown = event => {
|
|
868
|
+
if (event.target instanceof Element && event.target.closest(".k2b-ste-views")) event.preventDefault();
|
|
869
|
+
};
|
|
870
|
+
root.addEventListener("mousedown", viewMouseDown);
|
|
871
|
+
document.addEventListener("focusin", focusChange);
|
|
872
|
+
document.addEventListener("pointerdown", pointer);
|
|
873
|
+
root.addEventListener("k2b-ste-table-structure", structureAnnouncement);
|
|
874
|
+
root.addEventListener("k2b-ste-cell-focus", focus);
|
|
875
|
+
root.addEventListener("k2b-ste-cell-blur", focusChange);
|
|
876
|
+
root.addEventListener("k2b-ste-cell-menu", keyboardMenu);
|
|
877
|
+
const tableScroll = event => {
|
|
878
|
+
if (menuOpen && event.target instanceof HTMLElement && event.target.classList.contains("k2b-ste-table") && floatingTrigger?.getAttribute("aria-expanded") === "true") floatingTrigger.click();
|
|
879
|
+
schedulePosition();
|
|
880
|
+
};
|
|
881
|
+
window.addEventListener("scroll", tableScroll, true);
|
|
882
|
+
window.addEventListener("resize", schedulePosition);
|
|
883
|
+
const viewport = window.visualViewport;
|
|
884
|
+
const keyboard = () => root.style.setProperty("--k2b-ste-keyboard", `${Math.max(0, window.innerHeight - (viewport?.height ?? window.innerHeight) - (viewport?.offsetTop ?? 0))}px`);
|
|
885
|
+
viewport?.addEventListener("resize", keyboard);
|
|
886
|
+
viewport?.addEventListener("scroll", keyboard);
|
|
887
|
+
keyboard();
|
|
888
|
+
setReady(true);
|
|
889
|
+
updateCheck();
|
|
890
|
+
props.onReady?.(editor, {
|
|
891
|
+
tableActive: () => mode() === "formatted" && !!cell()?.isConnected,
|
|
892
|
+
TableMenu: trigger => menu(false, trigger),
|
|
893
|
+
formatCell: format => !!editor && !blocked() && !!cell()?.isConnected && formatActiveCell(editor.view, format),
|
|
894
|
+
notify: message => setNotice({
|
|
895
|
+
message
|
|
896
|
+
})
|
|
897
|
+
});
|
|
898
|
+
onCleanup(() => {
|
|
899
|
+
clearTimeout(pointerCheck);
|
|
900
|
+
mutations.disconnect();
|
|
901
|
+
resize.disconnect();
|
|
902
|
+
cancelAnimationFrame(frame);
|
|
903
|
+
root.removeEventListener("mousedown", viewMouseDown);
|
|
904
|
+
document.removeEventListener("focusin", focusChange);
|
|
905
|
+
document.removeEventListener("pointerdown", pointer);
|
|
906
|
+
root.removeEventListener("k2b-ste-table-structure", structureAnnouncement);
|
|
907
|
+
root.removeEventListener("k2b-ste-cell-focus", focus);
|
|
908
|
+
root.removeEventListener("k2b-ste-cell-blur", focusChange);
|
|
909
|
+
root.removeEventListener("k2b-ste-cell-menu", keyboardMenu);
|
|
910
|
+
window.removeEventListener("scroll", tableScroll, true);
|
|
911
|
+
window.removeEventListener("resize", schedulePosition);
|
|
912
|
+
viewport?.removeEventListener("resize", keyboard);
|
|
913
|
+
viewport?.removeEventListener("scroll", keyboard);
|
|
914
|
+
editor?.destroy();
|
|
915
|
+
});
|
|
916
|
+
});
|
|
917
|
+
createEffect(() => {
|
|
918
|
+
if (props.mode !== undefined) setMode(props.mode);
|
|
919
|
+
});
|
|
920
|
+
createEffect(() => {
|
|
921
|
+
if (ready()) {
|
|
922
|
+
const next = mode();
|
|
923
|
+
// Rendering the grid consults reactive host availability. Those reads
|
|
924
|
+
// must not turn a history notification into a nested mode reconfigure.
|
|
925
|
+
untrack(() => {
|
|
926
|
+
menuOpen = false;
|
|
927
|
+
setCell(undefined);
|
|
928
|
+
editor?.setMode(next);
|
|
929
|
+
updateCheck();
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
createEffect(() => {
|
|
934
|
+
const label = props.label;
|
|
935
|
+
if (ready()) untrack(() => editor?.setLabel(label));
|
|
936
|
+
});
|
|
937
|
+
createEffect(() => {
|
|
938
|
+
const readOnly = !!props.readOnly || !!props.loading || recovery() !== undefined;
|
|
939
|
+
if (ready()) untrack(() => editor?.setReadOnly(readOnly));
|
|
940
|
+
});
|
|
941
|
+
createEffect(() => {
|
|
942
|
+
documentRevision();
|
|
943
|
+
const disabled = blocked() || unavailable();
|
|
944
|
+
if (ready()) root.querySelectorAll(".k2b-ste-addColumn").forEach(button => {
|
|
945
|
+
button.disabled = disabled;
|
|
946
|
+
});
|
|
947
|
+
});
|
|
948
|
+
return _$ssr(_tmpl$16, `k2b-text-editor ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-mode", _$escape(mode(), true), false) + _$ssrAttribute("data-readonly", props.readOnly ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-active", active() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("aria-busy", _$escape(props.loading || !ready(), true), false), _$escape(announcement()), _$escape(_$createComponent(Show, {
|
|
949
|
+
get when() {
|
|
950
|
+
return !props.presentation || "status" in props || check();
|
|
951
|
+
},
|
|
952
|
+
get children() {
|
|
953
|
+
return _$ssr(_tmpl$10, _$escape(props.status), _$escape(_$createComponent(Show, {
|
|
954
|
+
get when() {
|
|
955
|
+
return check();
|
|
956
|
+
},
|
|
957
|
+
get children() {
|
|
958
|
+
return [_$ssr(_tmpl$1, _$ssrAttribute("title", missingSeparator() ? _$escape(t().checkSeparatorDetail, true) : _$escape(t().checkTableDetail, true), false), _$escape(t().checkTable)), _$createComponent(Button, {
|
|
959
|
+
size: "sm",
|
|
960
|
+
variant: "ghost",
|
|
961
|
+
get disabled() {
|
|
962
|
+
return blocked() || !missingSeparator() && unavailable();
|
|
963
|
+
},
|
|
964
|
+
get hidden() {
|
|
965
|
+
return props.readOnly;
|
|
966
|
+
},
|
|
967
|
+
get tooltip() {
|
|
968
|
+
return _$memo(() => !!missingSeparator())() ? t().checkSeparatorDetail : _$memo(() => !!unavailable())() ? t().structureUnavailable : t().checkTableDetail;
|
|
969
|
+
},
|
|
970
|
+
onMouseDown: preserveSelection,
|
|
971
|
+
onClick: () => {
|
|
972
|
+
if (!editor) return;
|
|
973
|
+
if (missingSeparator()) {
|
|
974
|
+
selectMode("source");
|
|
975
|
+
queueMicrotask(() => editor?.view.focus());
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
const table = findTables(editor.view.state.doc.toString()).find(table => table.lines.some(row => row.cells.length > table.columns));
|
|
979
|
+
if (table) runTableAction(editor.view, table.from, 0, 0, "completeColumns");
|
|
980
|
+
},
|
|
981
|
+
get children() {
|
|
982
|
+
return missingSeparator() ? t().reviewMarkdown : t().completeColumns;
|
|
983
|
+
}
|
|
984
|
+
})];
|
|
985
|
+
}
|
|
986
|
+
})));
|
|
987
|
+
}
|
|
988
|
+
})), _$escape(_$createComponent(Show, {
|
|
989
|
+
get when() {
|
|
990
|
+
return _$memo(() => !!(!props.readOnly && mode() !== "plain"))() && props.toolbar !== false;
|
|
991
|
+
},
|
|
992
|
+
get children() {
|
|
993
|
+
return _$ssr(_tmpl$11, _$escape(_$createComponent(Toolbar, {
|
|
994
|
+
"class": "k2b-ste-toolbar",
|
|
995
|
+
get label() {
|
|
996
|
+
return t().formatting;
|
|
997
|
+
},
|
|
998
|
+
get children() {
|
|
999
|
+
return [_$createComponent(For, {
|
|
1000
|
+
get each() {
|
|
1001
|
+
return [toolbar.slice(0, 3), toolbar.slice(3, 6), toolbar.slice(6)];
|
|
1002
|
+
},
|
|
1003
|
+
children: group => _$createComponent(Toolbar.Group, {
|
|
1004
|
+
"class": "k2b-ste-tool-group",
|
|
1005
|
+
get children() {
|
|
1006
|
+
return _$createComponent(For, {
|
|
1007
|
+
each: group,
|
|
1008
|
+
children: ([command, icon]) => command === "heading" || command === "code" ? formatMenu(command) : _$createComponent(Show, {
|
|
1009
|
+
get when() {
|
|
1010
|
+
return _$memo(() => !!(command === "table" && mode() === "formatted"))() && cell()?.isConnected;
|
|
1011
|
+
},
|
|
1012
|
+
get fallback() {
|
|
1013
|
+
return _$createComponent(IconButton, {
|
|
1014
|
+
"class": "k2b-ste-tool",
|
|
1015
|
+
variant: "ghost",
|
|
1016
|
+
size: "sm",
|
|
1017
|
+
get label() {
|
|
1018
|
+
return t()[command];
|
|
1019
|
+
},
|
|
1020
|
+
get tooltip() {
|
|
1021
|
+
return _$memo(() => !!shortcuts[command])() ? `${t()[command]} (${formatShortcut(shortcuts[command] ?? "", {
|
|
1022
|
+
platform: platform(),
|
|
1023
|
+
locale: locale()
|
|
1024
|
+
}).label})` : t()[command];
|
|
1025
|
+
},
|
|
1026
|
+
get disabled() {
|
|
1027
|
+
return blocked() || !!cell() && !inlineCommands.has(command) && command !== "table";
|
|
1028
|
+
},
|
|
1029
|
+
onMouseDown: preserveSelection,
|
|
1030
|
+
onClick: () => runFormat(command),
|
|
1031
|
+
get children() {
|
|
1032
|
+
return _$ssr(_tmpl$0, `ti ti-${_$escape(icon, true)}`);
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
},
|
|
1036
|
+
get children() {
|
|
1037
|
+
return menu(false);
|
|
1038
|
+
}
|
|
1039
|
+
})
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
})
|
|
1043
|
+
}), _$createComponent(SegmentedControl, {
|
|
1044
|
+
"class": "k2b-ste-views",
|
|
1045
|
+
size: "sm",
|
|
1046
|
+
get ariaLabel() {
|
|
1047
|
+
return t().view;
|
|
1048
|
+
},
|
|
1049
|
+
get value() {
|
|
1050
|
+
return mode() === "source" ? "source" : "formatted";
|
|
1051
|
+
},
|
|
1052
|
+
get options() {
|
|
1053
|
+
return [{
|
|
1054
|
+
value: "formatted",
|
|
1055
|
+
label: t().formatted,
|
|
1056
|
+
icon: "ti ti-typography"
|
|
1057
|
+
}, {
|
|
1058
|
+
value: "source",
|
|
1059
|
+
label: t().source,
|
|
1060
|
+
icon: "ti ti-markdown"
|
|
1061
|
+
}];
|
|
1062
|
+
},
|
|
1063
|
+
onValueChange: selectMode
|
|
1064
|
+
})];
|
|
1065
|
+
}
|
|
1066
|
+
})));
|
|
1067
|
+
}
|
|
1068
|
+
})), _$escape(_$createComponent(Show, {
|
|
1069
|
+
get when() {
|
|
1070
|
+
return props.loading || !ready();
|
|
1071
|
+
},
|
|
1072
|
+
get children() {
|
|
1073
|
+
return _$ssr(_tmpl$12, _$ssrAttribute("aria-label", _$escape(t().loading, true), false), _$escape(_$createComponent(For, {
|
|
1074
|
+
each: [82, 100, 68, 0, 96, 74],
|
|
1075
|
+
children: width => _$ssr(_tmpl$17, _$ssrStyleProperty("width:", `${_$escape(width, true)}%`))
|
|
1076
|
+
})));
|
|
1077
|
+
}
|
|
1078
|
+
})), _$ssrAttribute("class", props.presentation ? "k2b-ste-app-host" : "k2b-ste-host", false), _$ssrAttribute("hidden", props.loading || !ready(), true), _$escape(_$createComponent(Show, {
|
|
1079
|
+
get when() {
|
|
1080
|
+
return _$memo(() => !!(cell() && mode() === "formatted"))() && !menuBlocked();
|
|
1081
|
+
},
|
|
1082
|
+
get children() {
|
|
1083
|
+
return _$ssr(_tmpl$13, _$ssrAttribute("data-readonly", props.readOnly ? "true" : _$escape(undefined, true), false), _$ssrStyle(menuPosition()), _$escape(menu(true)));
|
|
1084
|
+
}
|
|
1085
|
+
})), _$escape(_$createComponent(Show, {
|
|
1086
|
+
get when() {
|
|
1087
|
+
return notice() || recovery() !== undefined;
|
|
1088
|
+
},
|
|
1089
|
+
get children() {
|
|
1090
|
+
return _$ssr(_tmpl$15, _$escape(_$createComponent(Show, {
|
|
1091
|
+
get when() {
|
|
1092
|
+
return notice();
|
|
1093
|
+
},
|
|
1094
|
+
get children() {
|
|
1095
|
+
return _$createComponent(Show, {
|
|
1096
|
+
get when() {
|
|
1097
|
+
return _$memo(() => !!notice()?.images)() && props.onAttachImages;
|
|
1098
|
+
},
|
|
1099
|
+
get fallback() {
|
|
1100
|
+
return _$ssr(_tmpl$18, _$escape(notice()?.message));
|
|
1101
|
+
},
|
|
1102
|
+
get children() {
|
|
1103
|
+
return _$createComponent(Button, {
|
|
1104
|
+
size: "sm",
|
|
1105
|
+
variant: "ghost",
|
|
1106
|
+
get disabled() {
|
|
1107
|
+
return blocked();
|
|
1108
|
+
},
|
|
1109
|
+
onClick: () => props.onAttachImages?.(),
|
|
1110
|
+
get children() {
|
|
1111
|
+
return notice()?.message;
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
})), _$escape(_$createComponent(Show, {
|
|
1118
|
+
get when() {
|
|
1119
|
+
return recovery() !== undefined;
|
|
1120
|
+
},
|
|
1121
|
+
get children() {
|
|
1122
|
+
return [_$ssr(_tmpl$6, _$escape(t().recoveredInput), _$ssrAttribute("value", _$escape(recovery(), true), false)), _$createComponent(Button, {
|
|
1123
|
+
size: "sm",
|
|
1124
|
+
variant: "ghost",
|
|
1125
|
+
onClick: () => {
|
|
1126
|
+
setRecovery(undefined);
|
|
1127
|
+
if (notice()?.message === t().cellRemoved) setNotice(undefined);
|
|
1128
|
+
},
|
|
1129
|
+
get children() {
|
|
1130
|
+
return t().discardRecovery;
|
|
1131
|
+
}
|
|
1132
|
+
})];
|
|
1133
|
+
}
|
|
1134
|
+
})), _$escape(_$createComponent(Show, {
|
|
1135
|
+
get when() {
|
|
1136
|
+
return notice();
|
|
1137
|
+
},
|
|
1138
|
+
get children() {
|
|
1139
|
+
return _$createComponent(IconButton, {
|
|
1140
|
+
size: "sm",
|
|
1141
|
+
variant: "ghost",
|
|
1142
|
+
get label() {
|
|
1143
|
+
return t().dismiss;
|
|
1144
|
+
},
|
|
1145
|
+
onClick: () => setNotice(undefined),
|
|
1146
|
+
get children() {
|
|
1147
|
+
return _$ssr(_tmpl$14);
|
|
1148
|
+
}
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
})));
|
|
1152
|
+
}
|
|
1153
|
+
})));
|
|
1154
|
+
}
|
|
1155
|
+
//# sourceMappingURL=TextEditor.js.map
|