@k2b/ui 0.17.0 → 0.19.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/README.md +3 -2
- package/dist/browser/actions/ContextMenu.js +3 -1
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/Dropdown.js +91 -46
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +4 -1
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/chat/ChatComposer.js +1311 -565
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/ChatPrimitives.js +9 -6
- package/dist/browser/chat/ChatPrimitives.js.map +1 -1
- package/dist/browser/chat/chat-behavior.js +9 -0
- package/dist/browser/chat/chat-behavior.js.map +1 -1
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/chat/types.js.map +1 -1
- package/dist/browser/content/Calendar.js +579 -533
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/FileView.js +62 -36
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/Lightbox.js +76 -40
- package/dist/browser/content/Lightbox.js.map +1 -1
- package/dist/browser/content/MarkdownView.js +9 -3
- package/dist/browser/content/MarkdownView.js.map +1 -1
- package/dist/browser/content/PdfPreview.js +146 -79
- package/dist/browser/content/PdfPreview.js.map +1 -1
- package/dist/browser/content/Timeline.js +1038 -0
- package/dist/browser/content/Timeline.js.map +1 -0
- package/dist/browser/content/VideoPlayer.js +299 -0
- package/dist/browser/content/VideoPlayer.js.map +1 -0
- package/dist/browser/content/chart-inspection.js +7 -2
- package/dist/browser/content/chart-inspection.js.map +1 -1
- package/dist/browser/content/file-view-preview.js +2 -2
- package/dist/browser/content/file-view-preview.js.map +1 -1
- package/dist/browser/content/index.js +3 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/markdown-links.js +178 -0
- package/dist/browser/content/markdown-links.js.map +1 -0
- package/dist/browser/content/timeline-model.js +579 -0
- package/dist/browser/content/timeline-model.js.map +1 -0
- package/dist/browser/feedback/dialog-core.js +26 -14
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/inputs/ChoiceChips.js +66 -0
- package/dist/browser/inputs/ChoiceChips.js.map +1 -0
- package/dist/browser/inputs/ChoiceGroups.js +53 -12
- package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
- package/dist/browser/inputs/FileDropTarget.js +129 -0
- package/dist/browser/inputs/FileDropTarget.js.map +1 -0
- package/dist/browser/inputs/FileInputs.js +84 -43
- package/dist/browser/inputs/FileInputs.js.map +1 -1
- package/dist/browser/inputs/SignatureInput.js +558 -0
- package/dist/browser/inputs/SignatureInput.js.map +1 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js +841 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-data.js +1903 -0
- package/dist/browser/inputs/emoji/emoji-data.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-index.js +209 -0
- package/dist/browser/inputs/emoji/emoji-index.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-messages.js +64 -0
- package/dist/browser/inputs/emoji/emoji-messages.js.map +1 -0
- package/dist/browser/inputs/file-drop.js +338 -0
- package/dist/browser/inputs/file-drop.js.map +1 -0
- package/dist/browser/inputs/index.js +6 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/markdown/MarkdownEditor.js +72 -78
- package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/browser/inputs/markdown/actions.js +48 -2
- package/dist/browser/inputs/markdown/actions.js.map +1 -1
- package/dist/browser/inputs/markdown/code-zone.js +38 -2
- package/dist/browser/inputs/markdown/code-zone.js.map +1 -1
- package/dist/browser/inputs/signature-messages.js +39 -0
- package/dist/browser/inputs/signature-messages.js.map +1 -0
- package/dist/browser/inputs/signature.js +208 -0
- package/dist/browser/inputs/signature.js.map +1 -0
- package/dist/browser/internal/render-error.js +49 -0
- package/dist/browser/internal/render-error.js.map +1 -0
- package/dist/browser/intl/messages.js +205 -4
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +483 -218
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/FloatingWindow.js +4 -1
- package/dist/browser/layout/FloatingWindow.js.map +1 -1
- package/dist/browser/layout/Navigation.js +274 -197
- package/dist/browser/layout/Navigation.js.map +1 -1
- package/dist/browser/layout/SidebarItemPreview.js +5 -1
- package/dist/browser/layout/SidebarItemPreview.js.map +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/navigation-model.js +2 -0
- package/dist/browser/layout/navigation-model.js.map +1 -1
- package/dist/browser/surfaces/NoticeCard.js +47 -44
- package/dist/browser/surfaces/NoticeCard.js.map +1 -1
- package/dist/browser/surfaces/ResourceCard.js +212 -0
- package/dist/browser/surfaces/ResourceCard.js.map +1 -0
- package/dist/browser/surfaces/index.js +1 -0
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/licenses/emojibase-data.txt +21 -0
- package/dist/ssr/actions/ContextMenu.js +3 -1
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +49 -12
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +4 -1
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +823 -221
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/ChatPrimitives.js +9 -6
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
- package/dist/ssr/chat/chat-behavior.js +9 -0
- package/dist/ssr/chat/chat-behavior.js.map +1 -1
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/chat/types.js.map +1 -1
- package/dist/ssr/content/Calendar.js +183 -142
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/FileView.js +30 -6
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/Lightbox.js +19 -5
- package/dist/ssr/content/Lightbox.js.map +1 -1
- package/dist/ssr/content/MarkdownView.js +9 -3
- package/dist/ssr/content/MarkdownView.js.map +1 -1
- package/dist/ssr/content/PdfPreview.js +77 -36
- package/dist/ssr/content/PdfPreview.js.map +1 -1
- package/dist/ssr/content/Timeline.js +804 -0
- package/dist/ssr/content/Timeline.js.map +1 -0
- package/dist/ssr/content/VideoPlayer.js +228 -0
- package/dist/ssr/content/VideoPlayer.js.map +1 -0
- package/dist/ssr/content/chart-inspection.js +7 -2
- package/dist/ssr/content/chart-inspection.js.map +1 -1
- package/dist/ssr/content/file-view-preview.js +2 -2
- package/dist/ssr/content/file-view-preview.js.map +1 -1
- package/dist/ssr/content/index.js +3 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/markdown-links.js +178 -0
- package/dist/ssr/content/markdown-links.js.map +1 -0
- package/dist/ssr/content/timeline-model.js +579 -0
- package/dist/ssr/content/timeline-model.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +26 -14
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/inputs/ChoiceChips.js +66 -0
- package/dist/ssr/inputs/ChoiceChips.js.map +1 -0
- package/dist/ssr/inputs/ChoiceGroups.js +12 -4
- package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
- package/dist/ssr/inputs/FileDropTarget.js +103 -0
- package/dist/ssr/inputs/FileDropTarget.js.map +1 -0
- package/dist/ssr/inputs/FileInputs.js +49 -12
- package/dist/ssr/inputs/FileInputs.js.map +1 -1
- package/dist/ssr/inputs/SignatureInput.js +404 -0
- package/dist/ssr/inputs/SignatureInput.js.map +1 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js +551 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-data.js +1903 -0
- package/dist/ssr/inputs/emoji/emoji-data.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-index.js +209 -0
- package/dist/ssr/inputs/emoji/emoji-index.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-messages.js +64 -0
- package/dist/ssr/inputs/emoji/emoji-messages.js.map +1 -0
- package/dist/ssr/inputs/file-drop.js +338 -0
- package/dist/ssr/inputs/file-drop.js.map +1 -0
- package/dist/ssr/inputs/index.js +6 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/markdown/MarkdownEditor.js +14 -2
- package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/ssr/inputs/markdown/actions.js +48 -2
- package/dist/ssr/inputs/markdown/actions.js.map +1 -1
- package/dist/ssr/inputs/markdown/code-zone.js +38 -2
- package/dist/ssr/inputs/markdown/code-zone.js.map +1 -1
- package/dist/ssr/inputs/signature-messages.js +39 -0
- package/dist/ssr/inputs/signature-messages.js.map +1 -0
- package/dist/ssr/inputs/signature.js +208 -0
- package/dist/ssr/inputs/signature.js.map +1 -0
- package/dist/ssr/internal/render-error.js +49 -0
- package/dist/ssr/internal/render-error.js.map +1 -0
- package/dist/ssr/intl/messages.js +205 -4
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +264 -47
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/FloatingWindow.js +4 -1
- package/dist/ssr/layout/FloatingWindow.js.map +1 -1
- package/dist/ssr/layout/Navigation.js +169 -122
- package/dist/ssr/layout/Navigation.js.map +1 -1
- package/dist/ssr/layout/SidebarItemPreview.js +5 -1
- package/dist/ssr/layout/SidebarItemPreview.js.map +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/navigation-model.js +2 -0
- package/dist/ssr/layout/navigation-model.js.map +1 -1
- package/dist/ssr/surfaces/NoticeCard.js +17 -12
- package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
- package/dist/ssr/surfaces/ResourceCard.js +115 -0
- package/dist/ssr/surfaces/ResourceCard.js.map +1 -0
- package/dist/ssr/surfaces/index.js +1 -0
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Dropdown.d.ts +13 -1
- package/dist/types/actions/FilterChip.d.ts +5 -0
- package/dist/types/chat/ChatComposer.d.ts +24 -1
- package/dist/types/chat/ChatPrimitives.d.ts +1 -1
- package/dist/types/chat/chat-behavior.d.ts +15 -0
- package/dist/types/chat/index.d.ts +1 -1
- package/dist/types/chat/types.d.ts +34 -0
- package/dist/types/content/Calendar.d.ts +28 -8
- package/dist/types/content/Lightbox.d.ts +8 -0
- package/dist/types/content/Timeline.d.ts +49 -0
- package/dist/types/content/VideoPlayer.d.ts +41 -0
- package/dist/types/content/index.d.ts +6 -2
- package/dist/types/content/markdown-links.d.ts +66 -0
- package/dist/types/content/timeline-model.d.ts +148 -0
- package/dist/types/feedback/dialog-core.d.ts +1 -1
- package/dist/types/inputs/ChoiceChips.d.ts +20 -0
- package/dist/types/inputs/ChoiceGroups.d.ts +11 -2
- package/dist/types/inputs/FileDropTarget.d.ts +23 -0
- package/dist/types/inputs/FileInputs.d.ts +8 -0
- package/dist/types/inputs/SignatureInput.d.ts +22 -0
- package/dist/types/inputs/emoji/EmojiPicker.d.ts +42 -0
- package/dist/types/inputs/emoji/emoji-data.d.ts +2 -0
- package/dist/types/inputs/emoji/emoji-index.d.ts +109 -0
- package/dist/types/inputs/emoji/emoji-messages.d.ts +30 -0
- package/dist/types/inputs/file-drop.d.ts +80 -0
- package/dist/types/inputs/index.d.ts +12 -0
- package/dist/types/inputs/markdown/actions.d.ts +4 -0
- package/dist/types/inputs/markdown/code-zone.d.ts +7 -0
- package/dist/types/inputs/signature-messages.d.ts +11 -0
- package/dist/types/inputs/signature.d.ts +72 -0
- package/dist/types/internal/render-error.d.ts +13 -0
- package/dist/types/intl/messages.d.ts +101 -0
- package/dist/types/layout/AppWorkspace.d.ts +38 -0
- package/dist/types/layout/SidebarItemPreview.d.ts +2 -0
- package/dist/types/layout/index.d.ts +2 -2
- package/dist/types/layout/navigation-model.d.ts +18 -0
- package/dist/types/surfaces/ResourceCard.d.ts +31 -0
- package/dist/types/surfaces/index.d.ts +2 -0
- package/package.json +5 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/file-drop.ts"],"sourcesContent":["import { text } from \"@k2b/stdlib\";\nimport { checkMimeType } from \"@k2b/stdlib/browser\";\nimport { type Accessor, createSignal } from \"solid-js\";\nimport { announce } from \"../feedback/announce\";\nimport { toast } from \"../feedback/toast\";\nimport type { UiMessages } from \"../intl/messages\";\n\nexport type FileDropRejection = {\n file: File;\n /** `type` misses `accept`, `size` exceeds `maxSize`, `count` is past `maxFiles` or the single file of `multiple={false}`. */\n reason: \"type\" | \"size\" | \"count\";\n};\n\nexport type FileDropDetails = {\n /** The drop's data, readable only while `onDrop` runs synchronously; read folder entries before the first `await`. */\n dataTransfer: DataTransfer;\n /** Files left out by `accept`, `maxSize`, or the file count; the user has already been told. */\n rejected: readonly FileDropRejection[];\n};\n\nexport type FileDropOptions = {\n /** One sentence that says what dropping does here, such as \"Drop to attach to the message\". */\n label: string;\n /** `<input accept>` syntax, such as `\"image/*,.pdf\"`. */\n accept?: string;\n /** Defaults to `true`; `false` takes the first fitting file. */\n multiple?: boolean;\n /** The most files one drop hands over. */\n maxFiles?: number;\n /** The largest file in bytes. */\n maxSize?: number;\n disabled?: boolean;\n /**\n * Called synchronously in the drop with the files that fit. `files` is empty only when the drop carried no file\n * objects at all, as some engines hand over dropped folders; `details.dataTransfer.items` still has their entries.\n */\n onDrop: (files: File[], details: FileDropDetails) => void | Promise<void>;\n};\n\nexport type FileDropTargetEntry = {\n options: FileDropOptions;\n messages: () => UiMessages;\n locale: () => string;\n /** Set for regions: the area the overlay covers. Specific targets are keyed by their element. */\n region?: () => Element | undefined;\n /** Set for regions: where the target itself is rendered; a region whose host is hidden takes no drops. */\n host?: () => Element | undefined;\n};\n\nexport type FileDropHover = { entry: FileDropTargetEntry; element: Element; invalid: boolean };\n\nexport type FileDropSession = {\n /** Regions that show their overlay during this drag: eligible, visible, and not inside another shown region. */\n shown: readonly FileDropTargetEntry[];\n hover: FileDropHover | null;\n};\n\nexport type FileDropEngine = {\n session: Accessor<FileDropSession | null>;\n /** Changes on every drag movement, so overlays can follow a region that moved or resized. */\n frame: Accessor<number>;\n addRegion: (entry: FileDropTargetEntry) => () => void;\n setTarget: (element: Element, entry: FileDropTargetEntry) => void;\n};\n\n/** The marker a hovered specific target carries for its ring; regions show their own overlay instead. */\nexport const FILE_DROP_ATTRIBUTE = \"data-file-drop\";\n\n/** Where a region without `for` looks for its area: the nearest dialog, workspace detail, or workspace main area. */\nexport const FILE_DROP_DEFAULT_REGION = \"dialog, .k2b-app-workspace__detail, .k2b-app-workspace__main\";\n\n/**\n * The type every drag that starts in a page carries. Such a drag holds page content, never files from outside, even\n * an image that carries one. Marking the drag itself leaves nothing behind when it never reports its end, as when its\n * start is cancelled or its source is removed.\n */\nconst PAGE_DRAG_TYPE = \"application/x-k2b-page-drag\";\n\n/** How long after the last drag event a pointer move means the drag ended; a drag over the page repeats them sooner. */\nconst DRAG_SILENCE_MS = 600;\n\nconst engines = new WeakMap<Document, FileDropEngine>();\n\nconst isFileDrag = (event: DragEvent) => {\n const types = Array.from(event.dataTransfer?.types ?? []);\n return types.includes(\"Files\") && !types.includes(PAGE_DRAG_TYPE);\n};\n\nconst elementOf = (target: EventTarget | null): Element | null =>\n target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n\nconst isModal = (dialog: Element) => {\n try {\n return dialog.matches(\":modal\");\n } catch {\n // An engine without `:modal` has no modal dialogs to defer to.\n return false;\n }\n};\n\n/**\n * The topmost modal dialog. Everything outside of it is inert, so a drag over the page lands inside it; only a drag\n * over other top-layer content falls back to the last modal dialog in the document.\n */\nconst topModal = (doc: Document, target: EventTarget | null): Element | null => {\n for (let dialog = elementOf(target)?.closest(\"dialog\"); dialog; dialog = dialog.parentElement?.closest(\"dialog\"))\n if (isModal(dialog)) return dialog;\n return Array.from(doc.querySelectorAll(\"dialog[open]\")).filter(isModal).at(-1) ?? null;\n};\n\n/** Sorts dropped files into the ones a target takes and the ones it leaves out, in drop order. */\nexport const partitionDroppedFiles = (\n files: readonly File[],\n options: Pick<FileDropOptions, \"accept\" | \"multiple\" | \"maxFiles\" | \"maxSize\">,\n): { accepted: File[]; rejected: FileDropRejection[] } => {\n const limit = options.multiple === false ? 1 : (options.maxFiles ?? Number.POSITIVE_INFINITY);\n const accepted: File[] = [];\n const rejected: FileDropRejection[] = [];\n for (const file of files) {\n if (options.accept && !checkMimeType(file, options.accept)) rejected.push({ file, reason: \"type\" });\n else if (options.maxSize !== undefined && file.size > options.maxSize) rejected.push({ file, reason: \"size\" });\n else if (accepted.length >= limit) rejected.push({ file, reason: \"count\" });\n else accepted.push(file);\n }\n return { accepted, rejected };\n};\n\n/**\n * During a drag only the types are readable, and only in some engines. A drag is refused when none of them can fit.\n * An extension in `accept` matches by file name, and systems report differing types for one extension (a `.csv` may be\n * `application/vnd.ms-excel`), so with one the drop decides.\n */\nexport const refusesDraggedTypes = (types: readonly string[], accept: string | undefined): boolean => {\n if (!accept || accept.split(\",\").some((entry) => entry.trim().startsWith(\".\"))) return false;\n return types.length > 0 && types.every((type) => type !== \"\" && !checkMimeType(type, accept));\n};\n\nconst invalidDrag = (event: DragEvent, options: FileDropOptions) =>\n refusesDraggedTypes(\n Array.from(event.dataTransfer?.items ?? [])\n .filter((item) => item.kind === \"file\")\n .map((item) => item.type),\n options.accept,\n );\n\nconst MAX_NAMES = 3;\nconst nameList = (files: readonly File[], messages: UiMessages) => {\n const names = files.slice(0, MAX_NAMES).map((file) => file.name);\n return files.length > MAX_NAMES ? `${names.join(\", \")} ${messages.fileDropMore({ count: files.length - MAX_NAMES })}` : names.join(\", \");\n};\n\nexport const fileDropRejectionMessage = (\n rejected: readonly FileDropRejection[],\n options: Pick<FileDropOptions, \"multiple\" | \"maxFiles\" | \"maxSize\">,\n messages: UiMessages,\n locale: string,\n): string => {\n const lines: string[] = [];\n const of = (reason: FileDropRejection[\"reason\"]) => rejected.filter((entry) => entry.reason === reason).map((entry) => entry.file);\n const type = of(\"type\");\n const size = of(\"size\");\n const count = of(\"count\");\n if (type.length) lines.push(messages.fileDropRejectedType({ names: nameList(type, messages) }));\n if (size.length)\n lines.push(\n messages.fileDropRejectedSize({ names: nameList(size, messages), limit: text.pprintBytes(options.maxSize ?? 0, { locale }) }),\n );\n if (count.length)\n lines.push(\n messages.fileDropRejectedCount({ names: nameList(count, messages), max: options.multiple === false ? 1 : (options.maxFiles ?? 1) }),\n );\n return lines.join(\"\\n\");\n};\n\nconst createEngine = (doc: Document): FileDropEngine => {\n const view = doc.defaultView;\n const regions = new Set<FileDropTargetEntry>();\n const targets = new WeakMap<Element, FileDropTargetEntry>();\n const [session, setSession] = createSignal<FileDropSession | null>(null);\n const [frame, setFrame] = createSignal(0);\n /** Elements the drag has entered and not yet left; the drag is over the window while any remains. */\n const entered = new Set<EventTarget>();\n let lastDragEvent = 0;\n let marked: Element | null = null;\n let frameRequest = 0;\n\n const mark = (hover: FileDropHover | null) => {\n if (marked && marked !== hover?.element) marked.removeAttribute(FILE_DROP_ATTRIBUTE);\n marked = null;\n if (!hover || hover.entry.region) return;\n marked = hover.element;\n marked.setAttribute(FILE_DROP_ATTRIBUTE, hover.invalid ? \"invalid\" : \"over\");\n };\n\n const regionElement = (entry: FileDropTargetEntry) => {\n const element = entry.region?.();\n return element?.isConnected ? element : undefined;\n };\n\n /** Whether nothing between the target's host and its area hides it, as a dialog stack hides its lower levels. */\n const displayed = (host: Element | undefined, area: Element) => {\n for (let element: Element | null | undefined = host; element && element !== area; element = element.parentElement)\n if (view?.getComputedStyle(element).display === \"none\") return false;\n return true;\n };\n\n /** A region takes part when it is enabled, displayed, and not behind a modal dialog it is not inside of. */\n const eligible = (entry: FileDropTargetEntry, modal: Element | null) => {\n const element = regionElement(entry);\n if (!element || entry.options.disabled) return false;\n return (!modal || modal.contains(element)) && displayed(entry.host?.(), element);\n };\n const rendered = (element: Element) => element === doc.documentElement || element.getClientRects().length > 0;\n\n const begin = (target: EventTarget | null) => {\n const modal = topModal(doc, target);\n const candidates = [...regions].filter((entry) => eligible(entry, modal) && rendered(regionElement(entry)!));\n // The latest region on an element replaces earlier ones; a region inside another shown one acts as a specific target.\n const byElement = new Map<Element, FileDropTargetEntry>();\n for (const entry of candidates) byElement.set(regionElement(entry)!, entry);\n const shown = [...byElement].filter(\n ([element]) => ![...byElement.keys()].some((other) => other !== element && other.contains(element)),\n );\n setSession({ shown: shown.map(([, entry]) => entry), hover: null });\n const first = shown[0]?.[1];\n if (first) announce(first.options.label);\n };\n\n const end = () => {\n entered.clear();\n mark(null);\n if (session()) setSession(null);\n };\n\n const resolve = (target: EventTarget | null): { entry: FileDropTargetEntry; element: Element } | null => {\n const modal = topModal(doc, target);\n for (let element = elementOf(target); element; element = element.parentElement) {\n const specific = targets.get(element);\n if (specific && !specific.options.disabled) return { entry: specific, element };\n let region: FileDropTargetEntry | undefined;\n for (const entry of regions) if (regionElement(entry) === element && eligible(entry, modal)) region = entry;\n if (region) return { entry: region, element };\n }\n return null;\n };\n\n const hoverFrom = (event: DragEvent) => {\n const current = session();\n if (!current) return null;\n const found = resolve(event.target);\n const hover = found ? { ...found, invalid: invalidDrag(event, found.entry.options) } : null;\n const previous = current.hover;\n if (previous?.entry !== hover?.entry || previous?.element !== hover?.element || previous?.invalid !== hover?.invalid) {\n mark(hover);\n setSession({ ...current, hover });\n }\n return hover;\n };\n\n /** Over a page with a region, a file never falls through to the browser, which would open it and leave the page. */\n const guarding = () => [...regions].some((entry) => regionElement(entry));\n\n const accept = (event: DragEvent, hover: FileDropHover | null) => {\n if (!hover && !guarding()) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = hover && !hover.invalid ? \"copy\" : \"none\";\n };\n\n const requestFrame = () => {\n if (frameRequest || !view) return;\n frameRequest = view.requestAnimationFrame(() => {\n frameRequest = 0;\n setFrame((value) => value + 1);\n });\n };\n\n const deliver = (entry: FileDropTargetEntry, dataTransfer: DataTransfer) => {\n const { options } = entry;\n const files = Array.from(dataTransfer.files);\n const { accepted, rejected } = partitionDroppedFiles(files, options);\n const messages = entry.messages();\n if (rejected.length) toast.error(fileDropRejectionMessage(rejected, options, messages, entry.locale()));\n if (!accepted.length && files.length) return;\n if (accepted.length)\n announce(\n accepted.length === 1\n ? messages.fileDropDroppedOne({ name: accepted[0]!.name })\n : messages.fileDropDropped({ count: accepted.length }),\n );\n void options.onDrop(accepted, { dataTransfer, rejected });\n };\n\n const listeners: Record<string, (event: Event) => void> = {\n dragstart: (event) => {\n (event as DragEvent).dataTransfer?.setData(PAGE_DRAG_TYPE, \"\");\n },\n dragenter: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n if (event.target) entered.add(event.target);\n if (!session()) begin(event.target);\n accept(drag, hoverFrom(drag));\n },\n dragover: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n // An engine may skip the first dragenter; the drag still counts as over the window.\n if (!session()) {\n if (event.target) entered.add(event.target);\n begin(event.target);\n }\n accept(drag, hoverFrom(drag));\n requestFrame();\n },\n dragleave: (event) => {\n if (!session()) return;\n if (event.target) entered.delete(event.target);\n // An element removed during the drag never reports leaving.\n for (const target of entered) if (target instanceof Node && !target.isConnected) entered.delete(target);\n if (entered.size === 0) end();\n },\n drop: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n const found = resolve(event.target);\n end();\n if (!found) {\n if (guarding()) event.preventDefault();\n return;\n }\n // The most specific target owns the drop; editors and other handlers below it never see the files.\n event.preventDefault();\n event.stopPropagation();\n if (drag.dataTransfer) deliver(found.entry, drag.dataTransfer);\n },\n keydown: (event) => {\n if ((event as KeyboardEvent).key === \"Escape\" && session()) end();\n },\n // Engines send no pointer moves during a drag: one long after the last drag event means the drag ended somewhere the\n // page did not see. One right after it belongs to another pointer, such as a second finger on a touch screen.\n pointermove: (event) => {\n if (session() && event.timeStamp - lastDragEvent > DRAG_SILENCE_MS) end();\n },\n visibilitychange: () => {\n if (doc.visibilityState === \"hidden\") end();\n },\n };\n\n let installed = false;\n const install = () => {\n if (installed || !view) return;\n installed = true;\n for (const [type, listener] of Object.entries(listeners))\n (type === \"visibilitychange\" ? doc : view).addEventListener(type, listener, { capture: true });\n };\n\n return {\n session,\n frame,\n addRegion: (entry) => {\n install();\n regions.add(entry);\n return () => {\n regions.delete(entry);\n const current = session();\n if (current?.hover?.entry === entry) {\n mark(null);\n setSession({ ...current, hover: null });\n }\n };\n },\n setTarget: (element, entry) => {\n install();\n targets.set(element, entry);\n },\n };\n};\n\n/**\n * The document an element lives in. A freshly rendered element still belongs to the inert document of the template it\n * was cloned from; until it is inserted, that is the page's document.\n */\nexport const liveDocument = (element: Element): Document => (element.ownerDocument.defaultView ? element.ownerDocument : document);\n\n/** The one drag tracker of a document, shared by every drop target in it. */\nexport const fileDropEngine = (doc: Document): FileDropEngine => {\n let engine = engines.get(doc);\n if (!engine) {\n engine = createEngine(doc);\n engines.set(doc, engine);\n }\n return engine;\n};\n"],"mappings":"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","ignoreList":[]}
|
package/dist/ssr/inputs/index.js
CHANGED
|
@@ -2,10 +2,14 @@ export { AutocompleteEditor } from "./AutocompleteEditor";
|
|
|
2
2
|
export { AutocompleteSelect } from "./AutocompleteSelect";
|
|
3
3
|
export { Checkbox } from "./Checkbox";
|
|
4
4
|
export { CheckboxCard } from "./CheckboxCard";
|
|
5
|
+
export { ChoiceChips } from "./ChoiceChips";
|
|
5
6
|
export { ColorInput, PinInput, Slider } from "./ChoiceInputs";
|
|
6
7
|
export { Combobox } from "./Combobox";
|
|
7
8
|
export { abbreviations } from "./completion";
|
|
8
9
|
export { DatePicker, DateRangePicker, DateTimePicker } from "./DatePicker";
|
|
10
|
+
export { EmojiPicker } from "./emoji/EmojiPicker";
|
|
11
|
+
export { rememberEmoji } from "./emoji/emoji-index";
|
|
12
|
+
export { FileDropTarget, fileDropTarget } from "./FileDropTarget";
|
|
9
13
|
export { FileDropzone, ImageCropper, ImageInput } from "./FileInputs";
|
|
10
14
|
export { DEFAULT_ICON_GROUPS, DEFAULT_ICON_OPTIONS } from "./icon-options";
|
|
11
15
|
export { clampImageCropRect, createCroppedImageCanvas, createCroppedImageDataUrl, getInitialImageCropRect, imageCropRectToPixels, normalizeImageCropRotation, resizeImageCropAroundCenter, rotateImageCropRight } from "./image-crop";
|
|
@@ -15,8 +19,10 @@ export { NumberInput } from "./NumberInput";
|
|
|
15
19
|
export { QrScanner } from "./QrScanner";
|
|
16
20
|
export { Select } from "./Select";
|
|
17
21
|
export { SelectChip } from "./SelectChip";
|
|
22
|
+
export { SignatureInput } from "./SignatureInput";
|
|
18
23
|
export { IconInput } from "./SpecialInputs";
|
|
19
24
|
export { Switch } from "./Switch";
|
|
25
|
+
export { parseSignature, signatureToPng } from "./signature";
|
|
20
26
|
export { TagEditor } from "./TagEditor";
|
|
21
27
|
export { TagsInput } from "./TagsInput";
|
|
22
28
|
export { createTemplateEditorPanesLayout, TemplateEditor, TemplatePreview, TemplateSampleData } from "./TemplateEditor";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["inputs/index.ts"],"sourcesContent":["export type { AutocompleteEditorProps } from \"./AutocompleteEditor\";\nexport { AutocompleteEditor } from \"./AutocompleteEditor\";\nexport type {\n AutocompleteSelectOption,\n AutocompleteSelectProps,\n AutocompleteSelectSearchResult,\n} from \"./AutocompleteSelect\";\nexport { AutocompleteSelect } from \"./AutocompleteSelect\";\nexport type { CheckboxProps } from \"./Checkbox\";\nexport { Checkbox } from \"./Checkbox\";\nexport type { CheckboxCardProps } from \"./CheckboxCard\";\nexport { CheckboxCard } from \"./CheckboxCard\";\nexport type {\n ColorInputProps,\n PinInputProps,\n SliderProps,\n} from \"./ChoiceInputs\";\nexport { ColorInput, PinInput, Slider } from \"./ChoiceInputs\";\nexport type { ComboboxOption, ComboboxProps } from \"./Combobox\";\nexport { Combobox } from \"./Combobox\";\nexport type { ChoiceOption, ChoiceOptionsLoader } from \"./choice\";\nexport type {\n Completion,\n QueryContext,\n SuggestContext,\n Suggestion,\n} from \"./completion\";\nexport { abbreviations } from \"./completion\";\nexport type {\n DatePickerBaseProps,\n DatePickerProps,\n DatePreset,\n DateRangePickerProps,\n DateRangeValue,\n DateTimePickerProps,\n DurationPreset,\n} from \"./DatePicker\";\nexport { DatePicker, DateRangePicker, DateTimePicker } from \"./DatePicker\";\nexport type { FileDropzoneProps, ImageCropperProps, ImageInputProps } from \"./FileInputs\";\nexport { FileDropzone, ImageCropper, ImageInput } from \"./FileInputs\";\nexport type { DateContext, FieldProps, MaybeAccessor, ValueFieldProps } from \"./field-contract\";\nexport { DEFAULT_ICON_GROUPS, DEFAULT_ICON_OPTIONS } from \"./icon-options\";\nexport type {\n ImageCropAspect,\n ImageCropOutput,\n ImageCropRect,\n ImageCropRotation,\n ImageCropSize,\n ImageCropSource,\n ImageCropState,\n} from \"./image-crop\";\nexport {\n clampImageCropRect,\n createCroppedImageCanvas,\n createCroppedImageDataUrl,\n getInitialImageCropRect,\n imageCropRectToPixels,\n normalizeImageCropRotation,\n resizeImageCropAroundCenter,\n rotateImageCropRight,\n} from \"./image-crop\";\nexport type {\n MultiSelectFetchDataFn,\n MultiSelectInputProps,\n MultiSelectOption,\n} from \"./MultiSelectInput\";\nexport { MultiSelectInput } from \"./MultiSelectInput\";\nexport type { MarkdownEditorProps } from \"./markdown/MarkdownEditor\";\nexport { MarkdownEditor } from \"./markdown/MarkdownEditor\";\nexport type { NumberInputProps } from \"./NumberInput\";\nexport { NumberInput } from \"./NumberInput\";\nexport type { QrScannerError, QrScannerProps } from \"./QrScanner\";\nexport { QrScanner } from \"./QrScanner\";\nexport type { ChoiceAppearance, SelectGridSize, SelectGroup, SelectOption, SelectProps, SelectSourceOption, SelectView } from \"./Select\";\nexport { Select } from \"./Select\";\nexport type { SelectChipOption, SelectChipProps } from \"./SelectChip\";\nexport { SelectChip } from \"./SelectChip\";\nexport type { IconInputProps, IconOption } from \"./SpecialInputs\";\nexport { IconInput } from \"./SpecialInputs\";\nexport type { SwitchProps } from \"./Switch\";\nexport { Switch } from \"./Switch\";\nexport type { TagEditorItem, TagEditorLabels, TagEditorProps, TagEditorValue } from \"./TagEditor\";\nexport { TagEditor } from \"./TagEditor\";\nexport type { TagsInputProps } from \"./TagsInput\";\nexport { TagsInput } from \"./TagsInput\";\nexport type {\n TemplateEditorLayout,\n TemplateEditorProps,\n TemplatePreviewProps,\n TemplateSampleDataProps,\n TemplateVariable,\n TemplateVariableKind,\n} from \"./TemplateEditor\";\nexport {\n createTemplateEditorPanesLayout,\n TemplateEditor,\n TemplatePreview,\n TemplateSampleData,\n} from \"./TemplateEditor\";\nexport type { TextInputProps } from \"./TextInput\";\nexport { TextInput } from \"./TextInput\";\n"],"mappings":"AACA,SAAS,kBAAkB,QAAQ,sBAAsB;AAMzD,SAAS,kBAAkB,QAAQ,sBAAsB;AAEzD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,YAAY,QAAQ,gBAAgB;
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/index.ts"],"sourcesContent":["export type { AutocompleteEditorProps } from \"./AutocompleteEditor\";\nexport { AutocompleteEditor } from \"./AutocompleteEditor\";\nexport type {\n AutocompleteSelectOption,\n AutocompleteSelectProps,\n AutocompleteSelectSearchResult,\n} from \"./AutocompleteSelect\";\nexport { AutocompleteSelect } from \"./AutocompleteSelect\";\nexport type { CheckboxProps } from \"./Checkbox\";\nexport { Checkbox } from \"./Checkbox\";\nexport type { CheckboxCardProps } from \"./CheckboxCard\";\nexport { CheckboxCard } from \"./CheckboxCard\";\nexport type { ChoiceChipOption, ChoiceChipsProps } from \"./ChoiceChips\";\nexport { ChoiceChips } from \"./ChoiceChips\";\nexport type {\n ColorInputProps,\n PinInputProps,\n SliderProps,\n} from \"./ChoiceInputs\";\nexport { ColorInput, PinInput, Slider } from \"./ChoiceInputs\";\nexport type { ComboboxOption, ComboboxProps } from \"./Combobox\";\nexport { Combobox } from \"./Combobox\";\nexport type { ChoiceOption, ChoiceOptionsLoader } from \"./choice\";\nexport type {\n Completion,\n QueryContext,\n SuggestContext,\n Suggestion,\n} from \"./completion\";\nexport { abbreviations } from \"./completion\";\nexport type {\n DatePickerBaseProps,\n DatePickerProps,\n DatePreset,\n DateRangePickerProps,\n DateRangeValue,\n DateTimePickerProps,\n DurationPreset,\n} from \"./DatePicker\";\nexport { DatePicker, DateRangePicker, DateTimePicker } from \"./DatePicker\";\nexport type { EmojiPickerPopoverProps, EmojiPickerProps } from \"./emoji/EmojiPicker\";\nexport { EmojiPicker } from \"./emoji/EmojiPicker\";\nexport type { EmojiSkinTone } from \"./emoji/emoji-index\";\nexport { rememberEmoji } from \"./emoji/emoji-index\";\nexport type { FileDropDetails, FileDropOptions, FileDropRejection, FileDropTargetProps } from \"./FileDropTarget\";\nexport { FileDropTarget, fileDropTarget } from \"./FileDropTarget\";\nexport type { FileDropzoneProps, ImageCropperProps, ImageInputProps } from \"./FileInputs\";\nexport { FileDropzone, ImageCropper, ImageInput } from \"./FileInputs\";\nexport type { DateContext, FieldProps, MaybeAccessor, ValueFieldProps } from \"./field-contract\";\nexport { DEFAULT_ICON_GROUPS, DEFAULT_ICON_OPTIONS } from \"./icon-options\";\nexport type {\n ImageCropAspect,\n ImageCropOutput,\n ImageCropRect,\n ImageCropRotation,\n ImageCropSize,\n ImageCropSource,\n ImageCropState,\n} from \"./image-crop\";\nexport {\n clampImageCropRect,\n createCroppedImageCanvas,\n createCroppedImageDataUrl,\n getInitialImageCropRect,\n imageCropRectToPixels,\n normalizeImageCropRotation,\n resizeImageCropAroundCenter,\n rotateImageCropRight,\n} from \"./image-crop\";\nexport type {\n MultiSelectFetchDataFn,\n MultiSelectInputProps,\n MultiSelectOption,\n} from \"./MultiSelectInput\";\nexport { MultiSelectInput } from \"./MultiSelectInput\";\nexport type { MarkdownEditorProps } from \"./markdown/MarkdownEditor\";\nexport { MarkdownEditor } from \"./markdown/MarkdownEditor\";\nexport type { NumberInputProps } from \"./NumberInput\";\nexport { NumberInput } from \"./NumberInput\";\nexport type { QrScannerError, QrScannerProps } from \"./QrScanner\";\nexport { QrScanner } from \"./QrScanner\";\nexport type { ChoiceAppearance, SelectGridSize, SelectGroup, SelectOption, SelectProps, SelectSourceOption, SelectView } from \"./Select\";\nexport { Select } from \"./Select\";\nexport type { SelectChipOption, SelectChipProps } from \"./SelectChip\";\nexport { SelectChip } from \"./SelectChip\";\nexport type { SignatureInputProps } from \"./SignatureInput\";\nexport { SignatureInput } from \"./SignatureInput\";\nexport type { IconInputProps, IconOption } from \"./SpecialInputs\";\nexport { IconInput } from \"./SpecialInputs\";\nexport type { SwitchProps } from \"./Switch\";\nexport { Switch } from \"./Switch\";\nexport type { SignaturePngOptions, SignatureValue } from \"./signature\";\nexport { parseSignature, signatureToPng } from \"./signature\";\nexport type { TagEditorItem, TagEditorLabels, TagEditorProps, TagEditorValue } from \"./TagEditor\";\nexport { TagEditor } from \"./TagEditor\";\nexport type { TagsInputProps } from \"./TagsInput\";\nexport { TagsInput } from \"./TagsInput\";\nexport type {\n TemplateEditorLayout,\n TemplateEditorProps,\n TemplatePreviewProps,\n TemplateSampleDataProps,\n TemplateVariable,\n TemplateVariableKind,\n} from \"./TemplateEditor\";\nexport {\n createTemplateEditorPanesLayout,\n TemplateEditor,\n TemplatePreview,\n TemplateSampleData,\n} from \"./TemplateEditor\";\nexport type { TextInputProps } from \"./TextInput\";\nexport { TextInput } from \"./TextInput\";\n"],"mappings":"AACA,SAAS,kBAAkB,QAAQ,sBAAsB;AAMzD,SAAS,kBAAkB,QAAQ,sBAAsB;AAEzD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,YAAY,QAAQ,gBAAgB;AAE7C,SAAS,WAAW,QAAQ,eAAe;AAM3C,SAAS,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,gBAAgB;AAE7D,SAAS,QAAQ,QAAQ,YAAY;AAQrC,SAAS,aAAa,QAAQ,cAAc;AAU5C,SAAS,UAAU,EAAE,eAAe,EAAE,cAAc,QAAQ,cAAc;AAE1E,SAAS,WAAW,QAAQ,qBAAqB;AAEjD,SAAS,aAAa,QAAQ,qBAAqB;AAEnD,SAAS,cAAc,EAAE,cAAc,QAAQ,kBAAkB;AAEjE,SAAS,YAAY,EAAE,YAAY,EAAE,UAAU,QAAQ,cAAc;AAErE,SAAS,mBAAmB,EAAE,oBAAoB,QAAQ,gBAAgB;AAU1E,SACE,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,QACf,cAAc;AAMrB,SAAS,gBAAgB,QAAQ,oBAAoB;AAErD,SAAS,cAAc,QAAQ,2BAA2B;AAE1D,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,SAAS,QAAQ,aAAa;AAEvC,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,UAAU,QAAQ,cAAc;AAEzC,SAAS,cAAc,QAAQ,kBAAkB;AAEjD,SAAS,SAAS,QAAQ,iBAAiB;AAE3C,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,cAAc,EAAE,cAAc,QAAQ,aAAa;AAE5D,SAAS,SAAS,QAAQ,aAAa;AAEvC,SAAS,SAAS,QAAQ,aAAa;AASvC,SACE,+BAA+B,EAC/B,cAAc,EACd,eAAe,EACf,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,SAAS,QAAQ,aAAa","ignoreList":[]}
|
|
@@ -8,7 +8,7 @@ import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
|
8
8
|
import { memo as _$memo } from "solid-js/web";
|
|
9
9
|
var _tmpl$ = ["<i", " aria-hidden=\"true\"></i>"],
|
|
10
10
|
_tmpl$2 = ["<div class=\"k2b-markdown-editor__placeholder\" aria-hidden=\"true\">", "</div>"],
|
|
11
|
-
_tmpl$3 = ["<div class=\"k2b-markdown-editor__stats\" aria-hidden=\"true\"", "><span>", "
|
|
11
|
+
_tmpl$3 = ["<div class=\"k2b-markdown-editor__stats\" aria-hidden=\"true\"", "><span>", "</span><span>", "</span><span>", "</span></div>"],
|
|
12
12
|
_tmpl$4 = "<div class=\"k2b-autocomplete__status\" role=\"status\"><i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\"></i>Loading suggestions</div>",
|
|
13
13
|
_tmpl$5 = ["<div popover=\"manual\" class=\"k2b-autocomplete__options\" role=\"presentation\"", "><div", " class=\"k2b-autocomplete__listbox\" role=\"listbox\"", ">", "", "", "</div></div>"],
|
|
14
14
|
_tmpl$6 = ["<div class=\"k2b-markdown-editor\" role=\"group\"", " style=\"", "\">", "<div class=\"k2b-markdown-editor__surface\">", "<div class=\"k2b-markdown-editor__preview\" aria-hidden=\"true\"></div>", "</div>", "", "</div>"],
|
|
@@ -20,6 +20,7 @@ import { highlight } from "@k2b/stdlib";
|
|
|
20
20
|
import { createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, untrack } from "solid-js";
|
|
21
21
|
import { Tooltip } from "../../feedback/Tooltip";
|
|
22
22
|
import { createFieldMeta, Field, fieldControlAria } from "../../internal/field";
|
|
23
|
+
import { useLocale } from "../../intl/locale";
|
|
23
24
|
import { useUiMessages } from "../../intl/messages";
|
|
24
25
|
import { abbreviations as abbreviationsCompletion, buildSuggestContext, collectKnownLabels, createCompletionBehaviorState, detectQuery, displayLabel, renderWithOverlay, resolveSuggestions } from "../completion";
|
|
25
26
|
import { resolveMaybeAccessor } from "../field-contract";
|
|
@@ -29,6 +30,8 @@ import { isInCodeZone } from "./code-zone";
|
|
|
29
30
|
import Toolbar from "./Toolbar";
|
|
30
31
|
export function MarkdownEditor(props) {
|
|
31
32
|
const messages = useUiMessages();
|
|
33
|
+
const locale = useLocale();
|
|
34
|
+
const formatCount = value => new Intl.NumberFormat(locale()).format(value);
|
|
32
35
|
const meta = createFieldMeta(props.id);
|
|
33
36
|
let textarea;
|
|
34
37
|
let preview;
|
|
@@ -521,7 +524,16 @@ export function MarkdownEditor(props) {
|
|
|
521
524
|
return _$memo(() => !!(props.showStats ?? true))() && !props.disabled;
|
|
522
525
|
},
|
|
523
526
|
get children() {
|
|
524
|
-
return _$ssr(_tmpl$3, _$ssrAttribute("data-empty", stats().chars === 0 ? "true" : _$escape(undefined, true), false), _$escape(
|
|
527
|
+
return _$ssr(_tmpl$3, _$ssrAttribute("data-empty", stats().chars === 0 ? "true" : _$escape(undefined, true), false), _$escape(messages().editorLines({
|
|
528
|
+
count: stats().lines,
|
|
529
|
+
value: formatCount(stats().lines)
|
|
530
|
+
})), _$escape(messages().editorWords({
|
|
531
|
+
count: stats().words,
|
|
532
|
+
value: formatCount(stats().words)
|
|
533
|
+
})), _$escape(messages().editorCharacters({
|
|
534
|
+
count: stats().chars,
|
|
535
|
+
value: formatCount(stats().chars)
|
|
536
|
+
})));
|
|
525
537
|
}
|
|
526
538
|
})), _$escape(_$createComponent(Show, {
|
|
527
539
|
get when() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["inputs/markdown/MarkdownEditor.tsx"],"sourcesContent":["import { highlight } from \"@k2b/stdlib\";\nimport { createEffect, createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { Tooltip } from \"../../feedback/Tooltip\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../../internal/field\";\nimport { useUiMessages } from \"../../intl/messages\";\nimport {\n abbreviations as abbreviationsCompletion,\n buildSuggestContext,\n type Completion,\n collectKnownLabels,\n createCompletionBehaviorState,\n detectQuery,\n displayLabel,\n type QueryContext,\n renderWithOverlay,\n resolveSuggestions,\n type Suggestion,\n} from \"../completion\";\nimport type { ValueFieldProps } from \"../field-contract\";\nimport { resolveMaybeAccessor } from \"../field-contract\";\nimport { computeActiveFormats } from \"./active-formats\";\nimport { handleListContinuation, handleShortcut, handleSmartPaste } from \"./behaviors\";\nimport { isInCodeZone } from \"./code-zone\";\nimport Toolbar from \"./Toolbar\";\n\nexport type MarkdownEditorProps = ValueFieldProps<string> & {\n onSubmit?: () => void;\n placeholder?: string;\n lines?: number;\n noToolbar?: boolean;\n spellcheck?: boolean;\n name?: string;\n maxLength?: number;\n textareaRef?: (element: HTMLTextAreaElement) => void;\n abbreviations?: Record<string, string>;\n completions?: readonly Completion[];\n showStats?: boolean;\n variant?: \"default\" | \"paper\" | \"embedded\";\n fill?: boolean;\n /** Groups save and close at the end of the toolbar. The caller owns navigation and unsaved-change confirmation. */\n onClose?: () => void;\n onSave?: () => void;\n saveDisabled?: boolean;\n saving?: boolean;\n /** Shows a successful-save check. The caller clears it after a brief delay or the next edit. */\n saved?: boolean;\n toolbarTrailing?: JSX.Element;\n};\n\ntype CompletionState = {\n context: QueryContext;\n suggestions: readonly Suggestion[];\n selectedIndex: number;\n};\n\nexport function MarkdownEditor(props: MarkdownEditorProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n let textarea: HTMLTextAreaElement | undefined;\n let preview: HTMLDivElement | undefined;\n let dropdown: HTMLDivElement | undefined;\n let completionAbort: AbortController | null = null;\n let completionTimer: ReturnType<typeof setTimeout> | null = null;\n let overlayFrame: number | undefined;\n let overlayInitialized = false;\n let renderPendingOverlay: (() => void) | undefined;\n const completionBehavior = createCompletionBehaviorState();\n\n const [textareaSignal, setTextareaSignal] = createSignal<HTMLTextAreaElement | null>(null);\n const [activeFormats, setActiveFormats] = createSignal<Set<string>>(new Set());\n const [composing, setComposing] = createSignal(false);\n const [localValue, setLocalValue] = createSignal(resolveMaybeAccessor(props.value) ?? \"\");\n const error = () => resolveMaybeAccessor(props.error);\n const [state, setState] = createSignal<CompletionState | null>(null);\n const [loading, setLoading] = createSignal(false);\n const [completionError, setCompletionError] = createSignal<string | null>(null);\n const [dropdownOpen, setDropdownOpen] = createSignal(false);\n const completionId = createUniqueId();\n const listboxId = `${meta.controlId}-${completionId}-suggestions`;\n const optionId = (index: number): string => `${listboxId}-${index}`;\n const activeSuggestion = (): Suggestion | null => {\n const current = state();\n return current?.suggestions[current.selectedIndex] ?? null;\n };\n\n const mergedCompletions = createMemo<readonly Completion[] | undefined>(() => {\n const merged: Completion[] = [];\n if (props.abbreviations && Object.keys(props.abbreviations).length > 0) {\n merged.push(abbreviationsCompletion(props.abbreviations));\n }\n if (props.completions) merged.push(...props.completions);\n return merged.length > 0 ? merged : undefined;\n });\n const knownLabels = createMemo(() => collectKnownLabels(mergedCompletions()));\n\n createEffect(() => {\n const incoming = resolveMaybeAccessor(props.value);\n if (incoming !== undefined && incoming !== null && incoming !== untrack(localValue)) {\n setLocalValue(incoming);\n }\n });\n\n createEffect(() => {\n const target = localValue();\n if (!composing() && textarea && textarea.value !== target) {\n textarea.value = target;\n }\n });\n\n createEffect(() => {\n if (!preview) return;\n const value = localValue();\n const labels = knownLabels();\n const current = state();\n const active = activeSuggestion();\n const ghost =\n current && active\n ? {\n at: current.context.end,\n text: active.text.slice(current.context.text.length),\n }\n : undefined;\n const anchor = current && !ghost ? { at: current.context.end } : undefined;\n renderPendingOverlay = () => {\n if (!preview) return;\n preview.innerHTML = renderWithOverlay(value, (text) => highlight.markdown(text, { knownLabels: labels }), { ghost, anchor });\n if (textarea) {\n preview.scrollTop = textarea.scrollTop;\n preview.scrollLeft = textarea.scrollLeft;\n }\n if (dropdown?.matches(\":popover-open\")) positionDropdown();\n };\n if (!overlayInitialized) {\n overlayInitialized = true;\n renderPendingOverlay();\n renderPendingOverlay = undefined;\n return;\n }\n if (overlayFrame !== undefined) return;\n overlayFrame = requestAnimationFrame(() => {\n overlayFrame = undefined;\n const render = renderPendingOverlay;\n renderPendingOverlay = undefined;\n render?.();\n });\n });\n\n const updateActiveFormats = (): void => {\n if (textarea) setActiveFormats(computeActiveFormats(textarea));\n };\n\n const closeDropdown = (): void => {\n if (dropdown?.matches(\":popover-open\")) dropdown.hidePopover();\n setDropdownOpen(false);\n };\n\n const clearCompletion = (): void => {\n completionAbort?.abort();\n completionAbort = null;\n if (completionTimer) clearTimeout(completionTimer);\n completionTimer = null;\n setState(null);\n setLoading(false);\n setCompletionError(null);\n closeDropdown();\n };\n\n const positionDropdown = (): void => {\n if (!dropdown?.isConnected || !preview?.isConnected || !textarea?.isConnected) {\n return;\n }\n const anchor = preview.querySelector<HTMLElement>(\"[data-completion-anchor]\");\n const rect = anchor?.getBoundingClientRect() ?? textarea.getBoundingClientRect();\n const maxHeight = 260;\n const spaceBelow = window.innerHeight - rect.bottom;\n const openAbove = spaceBelow < maxHeight && rect.top > spaceBelow;\n if (openAbove) {\n dropdown.style.setProperty(\"top\", \"auto\", \"important\");\n dropdown.style.setProperty(\"bottom\", `${window.innerHeight - rect.top + 4}px`, \"important\");\n } else {\n dropdown.style.setProperty(\"top\", `${rect.bottom + 4}px`, \"important\");\n dropdown.style.setProperty(\"bottom\", \"auto\", \"important\");\n }\n if (!dropdown.matches(\":popover-open\")) dropdown.showPopover();\n // The list sizes to its suggestions in CSS; measured once shown, it is\n // clamped into the viewport before the next paint.\n const width = dropdown.getBoundingClientRect().width;\n const left = Math.min(rect.left, window.innerWidth - width - 8);\n dropdown.style.setProperty(\"left\", `${Math.max(8, left)}px`, \"important\");\n };\n\n const isAbortError = (error: unknown): boolean =>\n error instanceof DOMException\n ? error.name === \"AbortError\"\n : Boolean(error && typeof error === \"object\" && \"name\" in error && (error as { name: string }).name === \"AbortError\");\n\n const applySuggestionList = (context: QueryContext, suggestions: readonly Suggestion[]): void => {\n const value = localValue();\n const normalized = context.text.toLowerCase();\n const usable = suggestions.filter((suggestion) => {\n if (suggestion.textEdit) {\n const { start, end, text } = suggestion.textEdit;\n return (\n Number.isInteger(start) &&\n Number.isInteger(end) &&\n start >= 0 &&\n end >= start &&\n end <= value.length &&\n value.slice(start, end) !== text\n );\n }\n return suggestion.text.toLowerCase().startsWith(normalized) && suggestion.text.length > context.text.length;\n });\n if (usable.length === 0) {\n setState(null);\n closeDropdown();\n return;\n }\n const previous = activeSuggestion()?.text;\n const retained = previous ? usable.findIndex((suggestion) => suggestion.text === previous) : -1;\n setState({\n context,\n suggestions: usable,\n selectedIndex: retained >= 0 ? retained : 0,\n });\n if (context.completion.dropdown) {\n setDropdownOpen(true);\n queueMicrotask(positionDropdown);\n } else {\n closeDropdown();\n }\n };\n\n const runAsyncCompletion = async (context: QueryContext, promise: Promise<readonly Suggestion[]>, signal: AbortSignal): Promise<void> => {\n try {\n const suggestions = await promise;\n if (signal.aborted) return;\n setLoading(false);\n applySuggestionList(context, suggestions);\n } catch (error) {\n if (signal.aborted || isAbortError(error)) return;\n setLoading(false);\n setState(null);\n setCompletionError(error instanceof Error ? error.message : \"Suggestions could not be loaded\");\n setDropdownOpen(true);\n queueMicrotask(positionDropdown);\n }\n };\n\n const startCompletionResolution = (context: QueryContext, signal: AbortSignal): void => {\n if (signal.aborted || !textarea) return;\n setLoading(true);\n setCompletionError(null);\n setDropdownOpen(true);\n queueMicrotask(positionDropdown);\n try {\n const result = resolveSuggestions(context.completion, context.query, buildSuggestContext(textarea, context), signal);\n if (result.kind === \"sync\") {\n setLoading(false);\n applySuggestionList(context, result.data);\n } else {\n void runAsyncCompletion(context, result.promise, signal);\n }\n } catch (error) {\n if (signal.aborted || isAbortError(error)) return;\n setLoading(false);\n setState(null);\n setCompletionError(error instanceof Error ? error.message : \"Suggestions could not be loaded\");\n queueMicrotask(positionDropdown);\n }\n };\n\n const recomputeCompletion = (): void => {\n if (!textarea) return;\n const context = detectQuery(textarea, mergedCompletions(), {\n isExcluded: isInCodeZone,\n });\n if (!context) {\n clearCompletion();\n return;\n }\n completionAbort?.abort();\n if (completionTimer) clearTimeout(completionTimer);\n completionTimer = null;\n completionAbort = new AbortController();\n const current = state();\n if (\n current &&\n (current.context.start !== context.start ||\n current.context.end !== context.end ||\n current.context.text !== context.text ||\n current.context.completion !== context.completion)\n ) {\n setState(null);\n closeDropdown();\n }\n setCompletionError(null);\n const delay = Math.max(0, context.completion.debounceMs ?? 0);\n if (delay === 0) {\n startCompletionResolution(context, completionAbort.signal);\n } else {\n setLoading(false);\n if (!state()) closeDropdown();\n const signal = completionAbort.signal;\n completionTimer = setTimeout(() => {\n completionTimer = null;\n startCompletionResolution(context, signal);\n }, delay);\n }\n };\n\n const retryCompletion = (): void => {\n if (!textarea) return;\n const context = detectQuery(textarea, mergedCompletions(), {\n isExcluded: isInCodeZone,\n });\n if (!context) return clearCompletion();\n completionAbort?.abort();\n if (completionTimer) clearTimeout(completionTimer);\n completionTimer = null;\n completionAbort = new AbortController();\n startCompletionResolution(context, completionAbort.signal);\n };\n\n const activateSuggestion = (index = state()?.selectedIndex ?? -1): boolean => {\n const current = state();\n const active = current?.suggestions[index];\n if (!textarea || !current || !active) return false;\n if (!active.textEdit && active.text === current.context.text) {\n closeDropdown();\n setState(null);\n return false;\n }\n const applied = completionBehavior.applySuggestion(textarea, current.context, active);\n closeDropdown();\n setState(null);\n return applied;\n };\n\n const moveSelection = (direction: 1 | -1): void => {\n const current = state();\n if (!current || current.suggestions.length === 0) return;\n setState({\n ...current,\n selectedIndex: (current.selectedIndex + direction + current.suggestions.length) % current.suggestions.length,\n });\n };\n\n const stats = createMemo(() => {\n const value = localValue();\n return {\n lines: value.length === 0 ? 0 : value.split(\"\\n\").length,\n words: value.match(/\\S+/g)?.length ?? 0,\n chars: value.length,\n };\n });\n\n onMount(() => {\n if (textarea) setTextareaSignal(textarea);\n updateActiveFormats();\n const selectionChange = (): void => {\n if (document.activeElement === textarea) {\n updateActiveFormats();\n recomputeCompletion();\n }\n };\n // Reposition an OPEN popover only. Calling `positionDropdown` blindly\n // would `showPopover()` a dropdown that is deliberately closed (a\n // ghost-only completion keeps state without a dropdown).\n const reposition = (): void => {\n if (dropdown?.matches(\":popover-open\")) positionDropdown();\n };\n document.addEventListener(\"selectionchange\", selectionChange);\n window.addEventListener(\"resize\", reposition);\n onCleanup(() => {\n document.removeEventListener(\"selectionchange\", selectionChange);\n window.removeEventListener(\"resize\", reposition);\n if (dropdown?.matches(\":popover-open\")) dropdown.hidePopover();\n completionAbort?.abort();\n if (completionTimer) clearTimeout(completionTimer);\n if (overlayFrame !== undefined) cancelAnimationFrame(overlayFrame);\n overlayFrame = undefined;\n renderPendingOverlay = undefined;\n completionBehavior.reset();\n });\n });\n\n const onInput = (event: InputEvent & { currentTarget: HTMLTextAreaElement }): void => {\n if (\n completionBehavior.tryExpand(event.currentTarget, mergedCompletions(), {\n isExcluded: isInCodeZone,\n })\n ) {\n return;\n }\n setLocalValue(event.currentTarget.value);\n props.onValueChange?.(event.currentTarget.value);\n updateActiveFormats();\n recomputeCompletion();\n };\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (!textarea || event.isComposing) return;\n if (\n event.key === \"Backspace\" &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey &&\n !event.shiftKey &&\n completionBehavior.tryRestore(textarea)\n ) {\n event.preventDefault();\n return;\n }\n const current = state();\n const dropdownCompletion = current?.context.completion.dropdown === true;\n if (current && dropdownCompletion && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\")) {\n event.preventDefault();\n moveSelection(event.key === \"ArrowDown\" ? 1 : -1);\n return;\n }\n if (\n event.key === \"Enter\" &&\n !event.shiftKey &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey &&\n current &&\n dropdownCompletion &&\n dropdownOpen()\n ) {\n event.preventDefault();\n activateSuggestion();\n return;\n }\n if (event.key === \"Tab\" && !event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey && current) {\n event.preventDefault();\n activateSuggestion();\n return;\n }\n if (event.key === \"Escape\") {\n if (current) {\n event.preventDefault();\n closeDropdown();\n setState(null);\n return;\n }\n if ((mergedCompletions()?.length ?? 0) > 0) {\n event.preventDefault();\n textarea.blur();\n return;\n }\n }\n if (event.key === \"Enter\" && (event.metaKey || event.ctrlKey) && props.onSubmit) {\n event.preventDefault();\n props.onSubmit();\n return;\n }\n if (handleShortcut(event, textarea)) {\n event.preventDefault();\n return;\n }\n if (event.key === \"Enter\" && !event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey && handleListContinuation(textarea)) {\n event.preventDefault();\n }\n };\n\n const saveControls = (): JSX.Element => (\n <>\n <Show when={props.onSave}>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-markdown-editor__tool\"\n content={messages().saveShortcut}\n aria-label={messages().save}\n tabIndex={-1}\n disabled={props.disabled || props.saveDisabled || props.saving}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => props.onSave?.()}\n >\n <i class={props.saving ? \"ti ti-loader-2 k2b-spin\" : props.saved ? \"ti ti-check\" : \"ti ti-device-floppy\"} aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </Show>\n </>\n );\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={props.error}\n fill={props.fill}\n meta={meta}\n required={props.required}\n disabled={props.disabled}\n >\n <div\n class=\"k2b-markdown-editor\"\n role=\"group\"\n aria-labelledby={props.label ? meta.labelId : undefined}\n aria-label={!props.label ? props[\"aria-label\"] : undefined}\n data-disabled={props.disabled ? \"true\" : undefined}\n data-invalid={error() ? \"true\" : undefined}\n data-variant={props.variant === \"default\" ? undefined : props.variant}\n data-fill={props.fill ? \"true\" : undefined}\n style={{\n \"--k2b-editor-lines\": String(props.lines ?? 6),\n }}\n onKeyDown={(event) => {\n if (props.onSave && (event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"s\") {\n event.preventDefault();\n if (!props.disabled && !props.saveDisabled && !props.saving) props.onSave();\n }\n }}\n >\n <Show when={!props.noToolbar}>\n <Toolbar\n textarea={textareaSignal}\n activeFormats={activeFormats}\n disabled={props.disabled}\n trailing={\n <>\n {props.toolbarTrailing}\n {saveControls()}\n <Show when={props.onClose}>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-markdown-editor__tool\"\n content={messages().close}\n aria-label={messages().close}\n tabIndex={props.disabled ? 0 : -1}\n onClick={() => props.onClose?.()}\n >\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </Show>\n </>\n }\n />\n </Show>\n <div class=\"k2b-markdown-editor__surface\">\n <Show when={!localValue() && props.placeholder}>\n <div class=\"k2b-markdown-editor__placeholder\" aria-hidden=\"true\">\n {props.placeholder}\n </div>\n </Show>\n <div ref={preview} class=\"k2b-markdown-editor__preview\" aria-hidden=\"true\" />\n <textarea\n ref={(element) => {\n textarea = element;\n props.textareaRef?.(element);\n }}\n id={meta.controlId}\n name={props.name}\n class=\"k2b-markdown-editor__input\"\n onInput={onInput}\n onChange={(event) => props.onValueCommit?.(event.currentTarget.value)}\n onKeyDown={onKeyDown}\n onPaste={(event) => {\n if (textarea && handleSmartPaste(event, textarea)) {\n event.preventDefault();\n }\n }}\n onScroll={(event) => {\n if (preview) {\n preview.scrollTop = event.currentTarget.scrollTop;\n preview.scrollLeft = event.currentTarget.scrollLeft;\n }\n }}\n onCompositionStart={() => setComposing(true)}\n onCompositionEnd={() => setComposing(false)}\n onBlur={(event) => {\n const next = event.relatedTarget as HTMLElement | null;\n if (next && dropdown?.contains(next)) return;\n completionBehavior.reset();\n clearCompletion();\n }}\n disabled={props.disabled}\n required={props.required}\n spellcheck={props.spellcheck ?? true}\n maxLength={props.maxLength}\n {...fieldControlAria(meta, props)}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n aria-controls={dropdownOpen() ? listboxId : undefined}\n aria-activedescendant={dropdownOpen() && state() ? optionId(state()!.selectedIndex) : undefined}\n />\n </div>\n <Show when={(props.showStats ?? true) && !props.disabled}>\n <div class=\"k2b-markdown-editor__stats\" aria-hidden=\"true\" data-empty={stats().chars === 0 ? \"true\" : undefined}>\n <span>\n {stats().lines} {stats().lines === 1 ? \"line\" : \"lines\"}\n </span>\n <span>\n {stats().words} {stats().words === 1 ? \"word\" : \"words\"}\n </span>\n <span>\n {stats().chars} {stats().chars === 1 ? \"char\" : \"chars\"}\n </span>\n </div>\n </Show>\n <Show when={state() || loading() || completionError()}>\n <div\n ref={dropdown}\n popover=\"manual\"\n class=\"k2b-autocomplete__options\"\n role=\"presentation\"\n aria-label={messages().completionSuggestions}\n >\n <div id={listboxId} class=\"k2b-autocomplete__listbox\" role=\"listbox\" aria-label={messages().suggestions}>\n <Show when={loading()}>\n <div class=\"k2b-autocomplete__status\" role=\"status\">\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n Loading suggestions\n </div>\n </Show>\n <Show when={completionError()}>\n {(message) => (\n <div class=\"k2b-autocomplete__status\" data-error=\"true\" role=\"alert\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n <span>{message()}</span>\n <button type=\"button\" onMouseDown={(event) => event.preventDefault()} onClick={retryCompletion}>\n {messages().retry}\n </button>\n </div>\n )}\n </Show>\n <For each={state()?.suggestions ?? []}>\n {(suggestion, index) => (\n // biome-ignore lint/a11y/useKeyWithClickEvents: the owning textarea handles keyboard activation through aria-activedescendant.\n <div\n id={optionId(index())}\n class=\"k2b-autocomplete__option\"\n role=\"option\"\n aria-selected={index() === state()?.selectedIndex}\n onMouseEnter={() => {\n const current = state();\n if (current) {\n setState({ ...current, selectedIndex: index() });\n }\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n }}\n onClick={() => {\n activateSuggestion(index());\n textarea?.focus();\n }}\n >\n <span>{displayLabel(suggestion, state()!.context.completion)}</span>\n <Show when={suggestion.hint}>{(hint) => <small>{hint()}</small>}</Show>\n </div>\n )}\n </For>\n </div>\n </div>\n </Show>\n </div>\n </Field>\n );\n}\n\nexport type { Completion, SuggestContext, Suggestion } from \"../completion\";\nexport { abbreviations } from \"../completion\";\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/markdown/MarkdownEditor.tsx"],"sourcesContent":["import { highlight } from \"@k2b/stdlib\";\nimport { createEffect, createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { Tooltip } from \"../../feedback/Tooltip\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../../internal/field\";\nimport { useLocale } from \"../../intl/locale\";\nimport { useUiMessages } from \"../../intl/messages\";\nimport {\n abbreviations as abbreviationsCompletion,\n buildSuggestContext,\n type Completion,\n collectKnownLabels,\n createCompletionBehaviorState,\n detectQuery,\n displayLabel,\n type QueryContext,\n renderWithOverlay,\n resolveSuggestions,\n type Suggestion,\n} from \"../completion\";\nimport type { ValueFieldProps } from \"../field-contract\";\nimport { resolveMaybeAccessor } from \"../field-contract\";\nimport { computeActiveFormats } from \"./active-formats\";\nimport { handleListContinuation, handleShortcut, handleSmartPaste } from \"./behaviors\";\nimport { isInCodeZone } from \"./code-zone\";\nimport Toolbar from \"./Toolbar\";\n\nexport type MarkdownEditorProps = ValueFieldProps<string> & {\n onSubmit?: () => void;\n placeholder?: string;\n lines?: number;\n noToolbar?: boolean;\n spellcheck?: boolean;\n name?: string;\n maxLength?: number;\n textareaRef?: (element: HTMLTextAreaElement) => void;\n abbreviations?: Record<string, string>;\n completions?: readonly Completion[];\n showStats?: boolean;\n variant?: \"default\" | \"paper\" | \"embedded\";\n fill?: boolean;\n /** Groups save and close at the end of the toolbar. The caller owns navigation and unsaved-change confirmation. */\n onClose?: () => void;\n onSave?: () => void;\n saveDisabled?: boolean;\n saving?: boolean;\n /** Shows a successful-save check. The caller clears it after a brief delay or the next edit. */\n saved?: boolean;\n toolbarTrailing?: JSX.Element;\n};\n\ntype CompletionState = {\n context: QueryContext;\n suggestions: readonly Suggestion[];\n selectedIndex: number;\n};\n\nexport function MarkdownEditor(props: MarkdownEditorProps): JSX.Element {\n const messages = useUiMessages();\n const locale = useLocale();\n const formatCount = (value: number) => new Intl.NumberFormat(locale()).format(value);\n const meta = createFieldMeta(props.id);\n let textarea: HTMLTextAreaElement | undefined;\n let preview: HTMLDivElement | undefined;\n let dropdown: HTMLDivElement | undefined;\n let completionAbort: AbortController | null = null;\n let completionTimer: ReturnType<typeof setTimeout> | null = null;\n let overlayFrame: number | undefined;\n let overlayInitialized = false;\n let renderPendingOverlay: (() => void) | undefined;\n const completionBehavior = createCompletionBehaviorState();\n\n const [textareaSignal, setTextareaSignal] = createSignal<HTMLTextAreaElement | null>(null);\n const [activeFormats, setActiveFormats] = createSignal<Set<string>>(new Set());\n const [composing, setComposing] = createSignal(false);\n const [localValue, setLocalValue] = createSignal(resolveMaybeAccessor(props.value) ?? \"\");\n const error = () => resolveMaybeAccessor(props.error);\n const [state, setState] = createSignal<CompletionState | null>(null);\n const [loading, setLoading] = createSignal(false);\n const [completionError, setCompletionError] = createSignal<string | null>(null);\n const [dropdownOpen, setDropdownOpen] = createSignal(false);\n const completionId = createUniqueId();\n const listboxId = `${meta.controlId}-${completionId}-suggestions`;\n const optionId = (index: number): string => `${listboxId}-${index}`;\n const activeSuggestion = (): Suggestion | null => {\n const current = state();\n return current?.suggestions[current.selectedIndex] ?? null;\n };\n\n const mergedCompletions = createMemo<readonly Completion[] | undefined>(() => {\n const merged: Completion[] = [];\n if (props.abbreviations && Object.keys(props.abbreviations).length > 0) {\n merged.push(abbreviationsCompletion(props.abbreviations));\n }\n if (props.completions) merged.push(...props.completions);\n return merged.length > 0 ? merged : undefined;\n });\n const knownLabels = createMemo(() => collectKnownLabels(mergedCompletions()));\n\n createEffect(() => {\n const incoming = resolveMaybeAccessor(props.value);\n if (incoming !== undefined && incoming !== null && incoming !== untrack(localValue)) {\n setLocalValue(incoming);\n }\n });\n\n createEffect(() => {\n const target = localValue();\n if (!composing() && textarea && textarea.value !== target) {\n textarea.value = target;\n }\n });\n\n createEffect(() => {\n if (!preview) return;\n const value = localValue();\n const labels = knownLabels();\n const current = state();\n const active = activeSuggestion();\n const ghost =\n current && active\n ? {\n at: current.context.end,\n text: active.text.slice(current.context.text.length),\n }\n : undefined;\n const anchor = current && !ghost ? { at: current.context.end } : undefined;\n renderPendingOverlay = () => {\n if (!preview) return;\n preview.innerHTML = renderWithOverlay(value, (text) => highlight.markdown(text, { knownLabels: labels }), { ghost, anchor });\n if (textarea) {\n preview.scrollTop = textarea.scrollTop;\n preview.scrollLeft = textarea.scrollLeft;\n }\n if (dropdown?.matches(\":popover-open\")) positionDropdown();\n };\n if (!overlayInitialized) {\n overlayInitialized = true;\n renderPendingOverlay();\n renderPendingOverlay = undefined;\n return;\n }\n if (overlayFrame !== undefined) return;\n overlayFrame = requestAnimationFrame(() => {\n overlayFrame = undefined;\n const render = renderPendingOverlay;\n renderPendingOverlay = undefined;\n render?.();\n });\n });\n\n const updateActiveFormats = (): void => {\n if (textarea) setActiveFormats(computeActiveFormats(textarea));\n };\n\n const closeDropdown = (): void => {\n if (dropdown?.matches(\":popover-open\")) dropdown.hidePopover();\n setDropdownOpen(false);\n };\n\n const clearCompletion = (): void => {\n completionAbort?.abort();\n completionAbort = null;\n if (completionTimer) clearTimeout(completionTimer);\n completionTimer = null;\n setState(null);\n setLoading(false);\n setCompletionError(null);\n closeDropdown();\n };\n\n const positionDropdown = (): void => {\n if (!dropdown?.isConnected || !preview?.isConnected || !textarea?.isConnected) {\n return;\n }\n const anchor = preview.querySelector<HTMLElement>(\"[data-completion-anchor]\");\n const rect = anchor?.getBoundingClientRect() ?? textarea.getBoundingClientRect();\n const maxHeight = 260;\n const spaceBelow = window.innerHeight - rect.bottom;\n const openAbove = spaceBelow < maxHeight && rect.top > spaceBelow;\n if (openAbove) {\n dropdown.style.setProperty(\"top\", \"auto\", \"important\");\n dropdown.style.setProperty(\"bottom\", `${window.innerHeight - rect.top + 4}px`, \"important\");\n } else {\n dropdown.style.setProperty(\"top\", `${rect.bottom + 4}px`, \"important\");\n dropdown.style.setProperty(\"bottom\", \"auto\", \"important\");\n }\n if (!dropdown.matches(\":popover-open\")) dropdown.showPopover();\n // The list sizes to its suggestions in CSS; measured once shown, it is\n // clamped into the viewport before the next paint.\n const width = dropdown.getBoundingClientRect().width;\n const left = Math.min(rect.left, window.innerWidth - width - 8);\n dropdown.style.setProperty(\"left\", `${Math.max(8, left)}px`, \"important\");\n };\n\n const isAbortError = (error: unknown): boolean =>\n error instanceof DOMException\n ? error.name === \"AbortError\"\n : Boolean(error && typeof error === \"object\" && \"name\" in error && (error as { name: string }).name === \"AbortError\");\n\n const applySuggestionList = (context: QueryContext, suggestions: readonly Suggestion[]): void => {\n const value = localValue();\n const normalized = context.text.toLowerCase();\n const usable = suggestions.filter((suggestion) => {\n if (suggestion.textEdit) {\n const { start, end, text } = suggestion.textEdit;\n return (\n Number.isInteger(start) &&\n Number.isInteger(end) &&\n start >= 0 &&\n end >= start &&\n end <= value.length &&\n value.slice(start, end) !== text\n );\n }\n return suggestion.text.toLowerCase().startsWith(normalized) && suggestion.text.length > context.text.length;\n });\n if (usable.length === 0) {\n setState(null);\n closeDropdown();\n return;\n }\n const previous = activeSuggestion()?.text;\n const retained = previous ? usable.findIndex((suggestion) => suggestion.text === previous) : -1;\n setState({\n context,\n suggestions: usable,\n selectedIndex: retained >= 0 ? retained : 0,\n });\n if (context.completion.dropdown) {\n setDropdownOpen(true);\n queueMicrotask(positionDropdown);\n } else {\n closeDropdown();\n }\n };\n\n const runAsyncCompletion = async (context: QueryContext, promise: Promise<readonly Suggestion[]>, signal: AbortSignal): Promise<void> => {\n try {\n const suggestions = await promise;\n if (signal.aborted) return;\n setLoading(false);\n applySuggestionList(context, suggestions);\n } catch (error) {\n if (signal.aborted || isAbortError(error)) return;\n setLoading(false);\n setState(null);\n setCompletionError(error instanceof Error ? error.message : \"Suggestions could not be loaded\");\n setDropdownOpen(true);\n queueMicrotask(positionDropdown);\n }\n };\n\n const startCompletionResolution = (context: QueryContext, signal: AbortSignal): void => {\n if (signal.aborted || !textarea) return;\n setLoading(true);\n setCompletionError(null);\n setDropdownOpen(true);\n queueMicrotask(positionDropdown);\n try {\n const result = resolveSuggestions(context.completion, context.query, buildSuggestContext(textarea, context), signal);\n if (result.kind === \"sync\") {\n setLoading(false);\n applySuggestionList(context, result.data);\n } else {\n void runAsyncCompletion(context, result.promise, signal);\n }\n } catch (error) {\n if (signal.aborted || isAbortError(error)) return;\n setLoading(false);\n setState(null);\n setCompletionError(error instanceof Error ? error.message : \"Suggestions could not be loaded\");\n queueMicrotask(positionDropdown);\n }\n };\n\n const recomputeCompletion = (): void => {\n if (!textarea) return;\n const context = detectQuery(textarea, mergedCompletions(), {\n isExcluded: isInCodeZone,\n });\n if (!context) {\n clearCompletion();\n return;\n }\n completionAbort?.abort();\n if (completionTimer) clearTimeout(completionTimer);\n completionTimer = null;\n completionAbort = new AbortController();\n const current = state();\n if (\n current &&\n (current.context.start !== context.start ||\n current.context.end !== context.end ||\n current.context.text !== context.text ||\n current.context.completion !== context.completion)\n ) {\n setState(null);\n closeDropdown();\n }\n setCompletionError(null);\n const delay = Math.max(0, context.completion.debounceMs ?? 0);\n if (delay === 0) {\n startCompletionResolution(context, completionAbort.signal);\n } else {\n setLoading(false);\n if (!state()) closeDropdown();\n const signal = completionAbort.signal;\n completionTimer = setTimeout(() => {\n completionTimer = null;\n startCompletionResolution(context, signal);\n }, delay);\n }\n };\n\n const retryCompletion = (): void => {\n if (!textarea) return;\n const context = detectQuery(textarea, mergedCompletions(), {\n isExcluded: isInCodeZone,\n });\n if (!context) return clearCompletion();\n completionAbort?.abort();\n if (completionTimer) clearTimeout(completionTimer);\n completionTimer = null;\n completionAbort = new AbortController();\n startCompletionResolution(context, completionAbort.signal);\n };\n\n const activateSuggestion = (index = state()?.selectedIndex ?? -1): boolean => {\n const current = state();\n const active = current?.suggestions[index];\n if (!textarea || !current || !active) return false;\n if (!active.textEdit && active.text === current.context.text) {\n closeDropdown();\n setState(null);\n return false;\n }\n const applied = completionBehavior.applySuggestion(textarea, current.context, active);\n closeDropdown();\n setState(null);\n return applied;\n };\n\n const moveSelection = (direction: 1 | -1): void => {\n const current = state();\n if (!current || current.suggestions.length === 0) return;\n setState({\n ...current,\n selectedIndex: (current.selectedIndex + direction + current.suggestions.length) % current.suggestions.length,\n });\n };\n\n const stats = createMemo(() => {\n const value = localValue();\n return {\n lines: value.length === 0 ? 0 : value.split(\"\\n\").length,\n words: value.match(/\\S+/g)?.length ?? 0,\n chars: value.length,\n };\n });\n\n onMount(() => {\n if (textarea) setTextareaSignal(textarea);\n updateActiveFormats();\n const selectionChange = (): void => {\n if (document.activeElement === textarea) {\n updateActiveFormats();\n recomputeCompletion();\n }\n };\n // Reposition an OPEN popover only. Calling `positionDropdown` blindly\n // would `showPopover()` a dropdown that is deliberately closed (a\n // ghost-only completion keeps state without a dropdown).\n const reposition = (): void => {\n if (dropdown?.matches(\":popover-open\")) positionDropdown();\n };\n document.addEventListener(\"selectionchange\", selectionChange);\n window.addEventListener(\"resize\", reposition);\n onCleanup(() => {\n document.removeEventListener(\"selectionchange\", selectionChange);\n window.removeEventListener(\"resize\", reposition);\n if (dropdown?.matches(\":popover-open\")) dropdown.hidePopover();\n completionAbort?.abort();\n if (completionTimer) clearTimeout(completionTimer);\n if (overlayFrame !== undefined) cancelAnimationFrame(overlayFrame);\n overlayFrame = undefined;\n renderPendingOverlay = undefined;\n completionBehavior.reset();\n });\n });\n\n const onInput = (event: InputEvent & { currentTarget: HTMLTextAreaElement }): void => {\n if (\n completionBehavior.tryExpand(event.currentTarget, mergedCompletions(), {\n isExcluded: isInCodeZone,\n })\n ) {\n return;\n }\n setLocalValue(event.currentTarget.value);\n props.onValueChange?.(event.currentTarget.value);\n updateActiveFormats();\n recomputeCompletion();\n };\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (!textarea || event.isComposing) return;\n if (\n event.key === \"Backspace\" &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey &&\n !event.shiftKey &&\n completionBehavior.tryRestore(textarea)\n ) {\n event.preventDefault();\n return;\n }\n const current = state();\n const dropdownCompletion = current?.context.completion.dropdown === true;\n if (current && dropdownCompletion && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\")) {\n event.preventDefault();\n moveSelection(event.key === \"ArrowDown\" ? 1 : -1);\n return;\n }\n if (\n event.key === \"Enter\" &&\n !event.shiftKey &&\n !event.metaKey &&\n !event.ctrlKey &&\n !event.altKey &&\n current &&\n dropdownCompletion &&\n dropdownOpen()\n ) {\n event.preventDefault();\n activateSuggestion();\n return;\n }\n if (event.key === \"Tab\" && !event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey && current) {\n event.preventDefault();\n activateSuggestion();\n return;\n }\n if (event.key === \"Escape\") {\n if (current) {\n event.preventDefault();\n closeDropdown();\n setState(null);\n return;\n }\n if ((mergedCompletions()?.length ?? 0) > 0) {\n event.preventDefault();\n textarea.blur();\n return;\n }\n }\n if (event.key === \"Enter\" && (event.metaKey || event.ctrlKey) && props.onSubmit) {\n event.preventDefault();\n props.onSubmit();\n return;\n }\n if (handleShortcut(event, textarea)) {\n event.preventDefault();\n return;\n }\n if (event.key === \"Enter\" && !event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey && handleListContinuation(textarea)) {\n event.preventDefault();\n }\n };\n\n const saveControls = (): JSX.Element => (\n <>\n <Show when={props.onSave}>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-markdown-editor__tool\"\n content={messages().saveShortcut}\n aria-label={messages().save}\n tabIndex={-1}\n disabled={props.disabled || props.saveDisabled || props.saving}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => props.onSave?.()}\n >\n <i class={props.saving ? \"ti ti-loader-2 k2b-spin\" : props.saved ? \"ti ti-check\" : \"ti ti-device-floppy\"} aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </Show>\n </>\n );\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={props.error}\n fill={props.fill}\n meta={meta}\n required={props.required}\n disabled={props.disabled}\n >\n <div\n class=\"k2b-markdown-editor\"\n role=\"group\"\n aria-labelledby={props.label ? meta.labelId : undefined}\n aria-label={!props.label ? props[\"aria-label\"] : undefined}\n data-disabled={props.disabled ? \"true\" : undefined}\n data-invalid={error() ? \"true\" : undefined}\n data-variant={props.variant === \"default\" ? undefined : props.variant}\n data-fill={props.fill ? \"true\" : undefined}\n style={{\n \"--k2b-editor-lines\": String(props.lines ?? 6),\n }}\n onKeyDown={(event) => {\n if (props.onSave && (event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"s\") {\n event.preventDefault();\n if (!props.disabled && !props.saveDisabled && !props.saving) props.onSave();\n }\n }}\n >\n <Show when={!props.noToolbar}>\n <Toolbar\n textarea={textareaSignal}\n activeFormats={activeFormats}\n disabled={props.disabled}\n trailing={\n <>\n {props.toolbarTrailing}\n {saveControls()}\n <Show when={props.onClose}>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-markdown-editor__tool\"\n content={messages().close}\n aria-label={messages().close}\n tabIndex={props.disabled ? 0 : -1}\n onClick={() => props.onClose?.()}\n >\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </Show>\n </>\n }\n />\n </Show>\n <div class=\"k2b-markdown-editor__surface\">\n <Show when={!localValue() && props.placeholder}>\n <div class=\"k2b-markdown-editor__placeholder\" aria-hidden=\"true\">\n {props.placeholder}\n </div>\n </Show>\n <div ref={preview} class=\"k2b-markdown-editor__preview\" aria-hidden=\"true\" />\n <textarea\n ref={(element) => {\n textarea = element;\n props.textareaRef?.(element);\n }}\n id={meta.controlId}\n name={props.name}\n class=\"k2b-markdown-editor__input\"\n onInput={onInput}\n onChange={(event) => props.onValueCommit?.(event.currentTarget.value)}\n onKeyDown={onKeyDown}\n onPaste={(event) => {\n if (textarea && handleSmartPaste(event, textarea)) {\n event.preventDefault();\n }\n }}\n onScroll={(event) => {\n if (preview) {\n preview.scrollTop = event.currentTarget.scrollTop;\n preview.scrollLeft = event.currentTarget.scrollLeft;\n }\n }}\n onCompositionStart={() => setComposing(true)}\n onCompositionEnd={() => setComposing(false)}\n onBlur={(event) => {\n const next = event.relatedTarget as HTMLElement | null;\n if (next && dropdown?.contains(next)) return;\n completionBehavior.reset();\n clearCompletion();\n }}\n disabled={props.disabled}\n required={props.required}\n spellcheck={props.spellcheck ?? true}\n maxLength={props.maxLength}\n {...fieldControlAria(meta, props)}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n aria-controls={dropdownOpen() ? listboxId : undefined}\n aria-activedescendant={dropdownOpen() && state() ? optionId(state()!.selectedIndex) : undefined}\n />\n </div>\n <Show when={(props.showStats ?? true) && !props.disabled}>\n <div class=\"k2b-markdown-editor__stats\" aria-hidden=\"true\" data-empty={stats().chars === 0 ? \"true\" : undefined}>\n <span>{messages().editorLines({ count: stats().lines, value: formatCount(stats().lines) })}</span>\n <span>{messages().editorWords({ count: stats().words, value: formatCount(stats().words) })}</span>\n <span>{messages().editorCharacters({ count: stats().chars, value: formatCount(stats().chars) })}</span>\n </div>\n </Show>\n <Show when={state() || loading() || completionError()}>\n <div\n ref={dropdown}\n popover=\"manual\"\n class=\"k2b-autocomplete__options\"\n role=\"presentation\"\n aria-label={messages().completionSuggestions}\n >\n <div id={listboxId} class=\"k2b-autocomplete__listbox\" role=\"listbox\" aria-label={messages().suggestions}>\n <Show when={loading()}>\n <div class=\"k2b-autocomplete__status\" role=\"status\">\n <i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\" />\n Loading suggestions\n </div>\n </Show>\n <Show when={completionError()}>\n {(message) => (\n <div class=\"k2b-autocomplete__status\" data-error=\"true\" role=\"alert\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n <span>{message()}</span>\n <button type=\"button\" onMouseDown={(event) => event.preventDefault()} onClick={retryCompletion}>\n {messages().retry}\n </button>\n </div>\n )}\n </Show>\n <For each={state()?.suggestions ?? []}>\n {(suggestion, index) => (\n // biome-ignore lint/a11y/useKeyWithClickEvents: the owning textarea handles keyboard activation through aria-activedescendant.\n <div\n id={optionId(index())}\n class=\"k2b-autocomplete__option\"\n role=\"option\"\n aria-selected={index() === state()?.selectedIndex}\n onMouseEnter={() => {\n const current = state();\n if (current) {\n setState({ ...current, selectedIndex: index() });\n }\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n }}\n onClick={() => {\n activateSuggestion(index());\n textarea?.focus();\n }}\n >\n <span>{displayLabel(suggestion, state()!.context.completion)}</span>\n <Show when={suggestion.hint}>{(hint) => <small>{hint()}</small>}</Show>\n </div>\n )}\n </For>\n </div>\n </div>\n </Show>\n </div>\n </Field>\n );\n}\n\nexport type { Completion, SuggestContext, Suggestion } from \"../completion\";\nexport { abbreviations } from \"../completion\";\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { replaceTextareaRange as replaceRange } from "../editor-dom";
|
|
2
|
+
import { closesCodeFence, openCodeFence } from "./code-zone";
|
|
2
3
|
const lineAt = (value, position) => {
|
|
3
4
|
const lineStart = value.lastIndexOf("\n", position - 1) + 1;
|
|
4
5
|
const nextNewline = value.indexOf("\n", position);
|
|
@@ -31,15 +32,17 @@ const toggleInlineWrap = (textarea, marker, placeholder) => {
|
|
|
31
32
|
selectionEnd
|
|
32
33
|
} = textarea;
|
|
33
34
|
const markerLength = marker.length;
|
|
35
|
+
// A one-character marker never takes half of a doubled one, so italic `*` leaves bold `**` alone.
|
|
36
|
+
const doubled = (text, from, step) => markerLength === 1 && text[from] === marker && text[from + step] === marker && text[from + 2 * step] !== marker;
|
|
34
37
|
const before = value.slice(Math.max(0, selectionStart - markerLength), selectionStart);
|
|
35
38
|
const after = value.slice(selectionEnd, selectionEnd + markerLength);
|
|
36
|
-
if (before === marker && after === marker) {
|
|
39
|
+
if (before === marker && after === marker && !doubled(value, selectionStart - 1, -1) && !doubled(value, selectionEnd, 1)) {
|
|
37
40
|
replaceRange(textarea, selectionStart - markerLength, selectionEnd + markerLength, value.slice(selectionStart, selectionEnd));
|
|
38
41
|
textarea.setSelectionRange(selectionStart - markerLength, selectionEnd - markerLength);
|
|
39
42
|
return;
|
|
40
43
|
}
|
|
41
44
|
const selected = value.slice(selectionStart, selectionEnd);
|
|
42
|
-
if (selected.length >= markerLength * 2 && selected.startsWith(marker) && selected.endsWith(marker)) {
|
|
45
|
+
if (selected.length >= markerLength * 2 && selected.startsWith(marker) && selected.endsWith(marker) && !doubled(selected, 0, 1) && !doubled(selected, selected.length - 1, -1)) {
|
|
43
46
|
const stripped = selected.slice(markerLength, -markerLength);
|
|
44
47
|
replaceRange(textarea, selectionStart, selectionEnd, stripped);
|
|
45
48
|
textarea.setSelectionRange(selectionStart, selectionStart + stripped.length);
|
|
@@ -56,6 +59,8 @@ const toggleInlineWrap = (textarea, marker, placeholder) => {
|
|
|
56
59
|
export const toggleBold = textarea => toggleInlineWrap(textarea, "**", "bold text");
|
|
57
60
|
export const toggleItalic = textarea => toggleInlineWrap(textarea, "*", "italic text");
|
|
58
61
|
export const toggleCode = textarea => toggleInlineWrap(textarea, "`", "code");
|
|
62
|
+
/** Wraps the selection in `marker`, or unwraps it; without a selection the caret lands between two markers. */
|
|
63
|
+
export const toggleInlineMarker = (textarea, marker) => toggleInlineWrap(textarea, marker, "");
|
|
59
64
|
export const insertLink = (textarea, url) => {
|
|
60
65
|
const {
|
|
61
66
|
value,
|
|
@@ -112,6 +117,47 @@ export const toggleHeading = (textarea, level) => {
|
|
|
112
117
|
textarea.setSelectionRange(caret, caret);
|
|
113
118
|
};
|
|
114
119
|
export const toggleBulletList = textarea => togglePrefix(textarea, "- ");
|
|
120
|
+
|
|
121
|
+
/** Puts the selected lines between ``` fences. Inside a fenced block, from its opening line on, it removes that block's fences. */
|
|
122
|
+
export const toggleCodeBlock = textarea => {
|
|
123
|
+
const {
|
|
124
|
+
value
|
|
125
|
+
} = textarea;
|
|
126
|
+
const {
|
|
127
|
+
start,
|
|
128
|
+
end,
|
|
129
|
+
lines
|
|
130
|
+
} = selectedLineRange(textarea);
|
|
131
|
+
const open = openCodeFence(value, lineAt(value, start).lineEnd);
|
|
132
|
+
if (open) {
|
|
133
|
+
const bodyStart = Math.min(lineAt(value, open.start).lineEnd + 1, value.length);
|
|
134
|
+
// An unclosed block runs to the end of the text.
|
|
135
|
+
let bodyEnd = value.length;
|
|
136
|
+
let blockEnd = value.length;
|
|
137
|
+
for (let lineStart = bodyStart; lineStart < value.length;) {
|
|
138
|
+
const {
|
|
139
|
+
lineEnd,
|
|
140
|
+
line
|
|
141
|
+
} = lineAt(value, lineStart);
|
|
142
|
+
if (closesCodeFence(line, open.marker)) {
|
|
143
|
+
bodyEnd = Math.max(bodyStart, lineStart - 1);
|
|
144
|
+
blockEnd = lineEnd;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
lineStart = lineEnd + 1;
|
|
148
|
+
}
|
|
149
|
+
const body = value.slice(bodyStart, bodyEnd);
|
|
150
|
+
replaceRange(textarea, open.start, blockEnd, body);
|
|
151
|
+
textarea.setSelectionRange(open.start, open.start + body.length);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const body = lines.join("\n");
|
|
155
|
+
// A fence in the selection would close a ``` block early, so the new block's fence is longer than any of them.
|
|
156
|
+
const longest = Math.max(0, ...lines.map(line => /^(?:[ \t]*>)*[ \t]*(`{3,})/.exec(line)?.[1].length ?? 0));
|
|
157
|
+
const fence = "`".repeat(Math.max(3, longest + 1));
|
|
158
|
+
replaceRange(textarea, start, end, `${fence}\n${body}\n${fence}`);
|
|
159
|
+
textarea.setSelectionRange(start + fence.length + 1, start + fence.length + 1 + body.length);
|
|
160
|
+
};
|
|
115
161
|
export const toggleQuote = textarea => togglePrefix(textarea, "> ");
|
|
116
162
|
export const toggleNumberedList = textarea => {
|
|
117
163
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["inputs/markdown/actions.ts"],"sourcesContent":["import { replaceTextareaRange as replaceRange } from \"../editor-dom\";\n\nconst lineAt = (value: string, position: number): { lineStart: number; lineEnd: number; line: string } => {\n const lineStart = value.lastIndexOf(\"\\n\", position - 1) + 1;\n const nextNewline = value.indexOf(\"\\n\", position);\n const lineEnd = nextNewline === -1 ? value.length : nextNewline;\n return { lineStart, lineEnd, line: value.slice(lineStart, lineEnd) };\n};\n\nconst selectedLineRange = (textarea: HTMLTextAreaElement): { start: number; end: number; lines: string[] } => {\n const { value, selectionStart, selectionEnd } = textarea;\n const startLine = lineAt(value, selectionStart);\n const adjustedEnd =\n selectionEnd > selectionStart && selectionEnd > 0 && value[selectionEnd - 1] === \"\\n\" ? selectionEnd - 1 : selectionEnd;\n const endLine = lineAt(value, adjustedEnd);\n return {\n start: startLine.lineStart,\n end: endLine.lineEnd,\n lines: value.slice(startLine.lineStart, endLine.lineEnd).split(\"\\n\"),\n };\n};\n\nconst toggleInlineWrap = (textarea: HTMLTextAreaElement, marker: string, placeholder: string): void => {\n const { value, selectionStart, selectionEnd } = textarea;\n const markerLength = marker.length;\n const before = value.slice(Math.max(0, selectionStart - markerLength), selectionStart);\n const after = value.slice(selectionEnd, selectionEnd + markerLength);\n if (before === marker && after === marker) {\n replaceRange(textarea, selectionStart - markerLength, selectionEnd + markerLength, value.slice(selectionStart, selectionEnd));\n textarea.setSelectionRange(selectionStart - markerLength, selectionEnd - markerLength);\n return;\n }\n\n const selected = value.slice(selectionStart, selectionEnd);\n if (selected.length >= markerLength * 2 && selected.startsWith(marker) && selected.endsWith(marker)) {\n const stripped = selected.slice(markerLength, -markerLength);\n replaceRange(textarea, selectionStart, selectionEnd, stripped);\n textarea.setSelectionRange(selectionStart, selectionStart + stripped.length);\n return;\n }\n\n if (selectionStart === selectionEnd) {\n replaceRange(textarea, selectionStart, selectionEnd, marker + placeholder + marker);\n textarea.setSelectionRange(selectionStart + markerLength, selectionStart + markerLength + placeholder.length);\n } else {\n replaceRange(textarea, selectionStart, selectionEnd, marker + selected + marker);\n textarea.setSelectionRange(selectionStart + markerLength, selectionStart + markerLength + selected.length);\n }\n};\n\nexport const toggleBold = (textarea: HTMLTextAreaElement): void => toggleInlineWrap(textarea, \"**\", \"bold text\");\nexport const toggleItalic = (textarea: HTMLTextAreaElement): void => toggleInlineWrap(textarea, \"*\", \"italic text\");\nexport const toggleCode = (textarea: HTMLTextAreaElement): void => toggleInlineWrap(textarea, \"`\", \"code\");\n\nexport const insertLink = (textarea: HTMLTextAreaElement, url?: string): void => {\n const { value, selectionStart, selectionEnd } = textarea;\n const selected = value.slice(selectionStart, selectionEnd);\n const label = selected || \"link\";\n const finalUrl = url ?? \"\";\n replaceRange(textarea, selectionStart, selectionEnd, `[${label}](${finalUrl})`);\n if (finalUrl) {\n textarea.setSelectionRange(selectionStart + 1, selectionStart + 1 + label.length);\n } else {\n const caret = selectionStart + label.length + 3;\n textarea.setSelectionRange(caret, caret);\n }\n};\n\nconst togglePrefix = (textarea: HTMLTextAreaElement, prefix: string): void => {\n const { start, end, lines } = selectedLineRange(textarea);\n const parts = lines.map((line) => {\n const match = /^(\\s*)(.*)$/.exec(line)!;\n return { indent: match[1]!, body: match[2]! };\n });\n const remove = parts.every(({ body }) => body.startsWith(prefix));\n const replacement = parts.map(({ indent, body }) => (remove ? indent + body.slice(prefix.length) : indent + prefix + body)).join(\"\\n\");\n replaceRange(textarea, start, end, replacement);\n textarea.setSelectionRange(start, start + replacement.length);\n};\n\nexport const toggleHeading = (textarea: HTMLTextAreaElement, level: 1 | 2 | 3): void => {\n const oldCaret = textarea.selectionStart;\n const { lineStart, lineEnd, line } = lineAt(textarea.value, oldCaret);\n const prefix = `${\"#\".repeat(level)} `;\n const existing = /^(#{1,6})\\s/.exec(line);\n const next =\n existing?.[1]?.length === level ? line.slice(existing[0].length) : existing ? prefix + line.slice(existing[0].length) : prefix + line;\n replaceRange(textarea, lineStart, lineEnd, next);\n const desired = Math.max(lineStart, oldCaret + next.length - line.length);\n const caret = Math.min(desired, lineStart + next.length);\n textarea.setSelectionRange(caret, caret);\n};\n\nexport const toggleBulletList = (textarea: HTMLTextAreaElement): void => togglePrefix(textarea, \"- \");\nexport const toggleQuote = (textarea: HTMLTextAreaElement): void => togglePrefix(textarea, \"> \");\n\nexport const toggleNumberedList = (textarea: HTMLTextAreaElement): void => {\n const { start, end, lines } = selectedLineRange(textarea);\n const parts = lines.map((line) => {\n const match = /^(\\s*)(\\d+\\.\\s)?(.*)$/.exec(line)!;\n return {\n indent: match[1] ?? \"\",\n marker: match[2],\n body: match[3] ?? \"\",\n };\n });\n const remove = parts.every(({ marker }) => Boolean(marker));\n const replacement = parts.map(({ indent, body }, index) => (remove ? indent + body : `${indent}${index + 1}. ${body}`)).join(\"\\n\");\n replaceRange(textarea, start, end, replacement);\n textarea.setSelectionRange(start, start + replacement.length);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/markdown/actions.ts"],"sourcesContent":["import { replaceTextareaRange as replaceRange } from \"../editor-dom\";\nimport { closesCodeFence, openCodeFence } from \"./code-zone\";\n\nconst lineAt = (value: string, position: number): { lineStart: number; lineEnd: number; line: string } => {\n const lineStart = value.lastIndexOf(\"\\n\", position - 1) + 1;\n const nextNewline = value.indexOf(\"\\n\", position);\n const lineEnd = nextNewline === -1 ? value.length : nextNewline;\n return { lineStart, lineEnd, line: value.slice(lineStart, lineEnd) };\n};\n\nconst selectedLineRange = (textarea: HTMLTextAreaElement): { start: number; end: number; lines: string[] } => {\n const { value, selectionStart, selectionEnd } = textarea;\n const startLine = lineAt(value, selectionStart);\n const adjustedEnd =\n selectionEnd > selectionStart && selectionEnd > 0 && value[selectionEnd - 1] === \"\\n\" ? selectionEnd - 1 : selectionEnd;\n const endLine = lineAt(value, adjustedEnd);\n return {\n start: startLine.lineStart,\n end: endLine.lineEnd,\n lines: value.slice(startLine.lineStart, endLine.lineEnd).split(\"\\n\"),\n };\n};\n\nconst toggleInlineWrap = (textarea: HTMLTextAreaElement, marker: string, placeholder: string): void => {\n const { value, selectionStart, selectionEnd } = textarea;\n const markerLength = marker.length;\n // A one-character marker never takes half of a doubled one, so italic `*` leaves bold `**` alone.\n const doubled = (text: string, from: number, step: 1 | -1) =>\n markerLength === 1 && text[from] === marker && text[from + step] === marker && text[from + 2 * step] !== marker;\n const before = value.slice(Math.max(0, selectionStart - markerLength), selectionStart);\n const after = value.slice(selectionEnd, selectionEnd + markerLength);\n if (before === marker && after === marker && !doubled(value, selectionStart - 1, -1) && !doubled(value, selectionEnd, 1)) {\n replaceRange(textarea, selectionStart - markerLength, selectionEnd + markerLength, value.slice(selectionStart, selectionEnd));\n textarea.setSelectionRange(selectionStart - markerLength, selectionEnd - markerLength);\n return;\n }\n\n const selected = value.slice(selectionStart, selectionEnd);\n if (\n selected.length >= markerLength * 2 &&\n selected.startsWith(marker) &&\n selected.endsWith(marker) &&\n !doubled(selected, 0, 1) &&\n !doubled(selected, selected.length - 1, -1)\n ) {\n const stripped = selected.slice(markerLength, -markerLength);\n replaceRange(textarea, selectionStart, selectionEnd, stripped);\n textarea.setSelectionRange(selectionStart, selectionStart + stripped.length);\n return;\n }\n\n if (selectionStart === selectionEnd) {\n replaceRange(textarea, selectionStart, selectionEnd, marker + placeholder + marker);\n textarea.setSelectionRange(selectionStart + markerLength, selectionStart + markerLength + placeholder.length);\n } else {\n replaceRange(textarea, selectionStart, selectionEnd, marker + selected + marker);\n textarea.setSelectionRange(selectionStart + markerLength, selectionStart + markerLength + selected.length);\n }\n};\n\nexport const toggleBold = (textarea: HTMLTextAreaElement): void => toggleInlineWrap(textarea, \"**\", \"bold text\");\nexport const toggleItalic = (textarea: HTMLTextAreaElement): void => toggleInlineWrap(textarea, \"*\", \"italic text\");\nexport const toggleCode = (textarea: HTMLTextAreaElement): void => toggleInlineWrap(textarea, \"`\", \"code\");\n/** Wraps the selection in `marker`, or unwraps it; without a selection the caret lands between two markers. */\nexport const toggleInlineMarker = (textarea: HTMLTextAreaElement, marker: string): void => toggleInlineWrap(textarea, marker, \"\");\n\nexport const insertLink = (textarea: HTMLTextAreaElement, url?: string): void => {\n const { value, selectionStart, selectionEnd } = textarea;\n const selected = value.slice(selectionStart, selectionEnd);\n const label = selected || \"link\";\n const finalUrl = url ?? \"\";\n replaceRange(textarea, selectionStart, selectionEnd, `[${label}](${finalUrl})`);\n if (finalUrl) {\n textarea.setSelectionRange(selectionStart + 1, selectionStart + 1 + label.length);\n } else {\n const caret = selectionStart + label.length + 3;\n textarea.setSelectionRange(caret, caret);\n }\n};\n\nconst togglePrefix = (textarea: HTMLTextAreaElement, prefix: string): void => {\n const { start, end, lines } = selectedLineRange(textarea);\n const parts = lines.map((line) => {\n const match = /^(\\s*)(.*)$/.exec(line)!;\n return { indent: match[1]!, body: match[2]! };\n });\n const remove = parts.every(({ body }) => body.startsWith(prefix));\n const replacement = parts.map(({ indent, body }) => (remove ? indent + body.slice(prefix.length) : indent + prefix + body)).join(\"\\n\");\n replaceRange(textarea, start, end, replacement);\n textarea.setSelectionRange(start, start + replacement.length);\n};\n\nexport const toggleHeading = (textarea: HTMLTextAreaElement, level: 1 | 2 | 3): void => {\n const oldCaret = textarea.selectionStart;\n const { lineStart, lineEnd, line } = lineAt(textarea.value, oldCaret);\n const prefix = `${\"#\".repeat(level)} `;\n const existing = /^(#{1,6})\\s/.exec(line);\n const next =\n existing?.[1]?.length === level ? line.slice(existing[0].length) : existing ? prefix + line.slice(existing[0].length) : prefix + line;\n replaceRange(textarea, lineStart, lineEnd, next);\n const desired = Math.max(lineStart, oldCaret + next.length - line.length);\n const caret = Math.min(desired, lineStart + next.length);\n textarea.setSelectionRange(caret, caret);\n};\n\nexport const toggleBulletList = (textarea: HTMLTextAreaElement): void => togglePrefix(textarea, \"- \");\n\n/** Puts the selected lines between ``` fences. Inside a fenced block, from its opening line on, it removes that block's fences. */\nexport const toggleCodeBlock = (textarea: HTMLTextAreaElement): void => {\n const { value } = textarea;\n const { start, end, lines } = selectedLineRange(textarea);\n const open = openCodeFence(value, lineAt(value, start).lineEnd);\n if (open) {\n const bodyStart = Math.min(lineAt(value, open.start).lineEnd + 1, value.length);\n // An unclosed block runs to the end of the text.\n let bodyEnd = value.length;\n let blockEnd = value.length;\n for (let lineStart = bodyStart; lineStart < value.length; ) {\n const { lineEnd, line } = lineAt(value, lineStart);\n if (closesCodeFence(line, open.marker)) {\n bodyEnd = Math.max(bodyStart, lineStart - 1);\n blockEnd = lineEnd;\n break;\n }\n lineStart = lineEnd + 1;\n }\n const body = value.slice(bodyStart, bodyEnd);\n replaceRange(textarea, open.start, blockEnd, body);\n textarea.setSelectionRange(open.start, open.start + body.length);\n return;\n }\n const body = lines.join(\"\\n\");\n // A fence in the selection would close a ``` block early, so the new block's fence is longer than any of them.\n const longest = Math.max(0, ...lines.map((line) => /^(?:[ \\t]*>)*[ \\t]*(`{3,})/.exec(line)?.[1]!.length ?? 0));\n const fence = \"`\".repeat(Math.max(3, longest + 1));\n replaceRange(textarea, start, end, `${fence}\\n${body}\\n${fence}`);\n textarea.setSelectionRange(start + fence.length + 1, start + fence.length + 1 + body.length);\n};\n\nexport const toggleQuote = (textarea: HTMLTextAreaElement): void => togglePrefix(textarea, \"> \");\n\nexport const toggleNumberedList = (textarea: HTMLTextAreaElement): void => {\n const { start, end, lines } = selectedLineRange(textarea);\n const parts = lines.map((line) => {\n const match = /^(\\s*)(\\d+\\.\\s)?(.*)$/.exec(line)!;\n return {\n indent: match[1] ?? \"\",\n marker: match[2],\n body: match[3] ?? \"\",\n };\n });\n const remove = parts.every(({ marker }) => Boolean(marker));\n const replacement = parts.map(({ indent, body }, index) => (remove ? indent + body : `${indent}${index + 1}. ${body}`)).join(\"\\n\");\n replaceRange(textarea, start, end, replacement);\n textarea.setSelectionRange(start, start + replacement.length);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,43 @@
|
|
|
1
|
+
/** A fence line: optional quote markers and indentation, then three or more backticks or tildes, then the rest. */
|
|
2
|
+
const fenceLine = /^(?:[ \t]*>)*[ \t]*(`{3,}|~{3,})(.*)$/;
|
|
3
|
+
|
|
4
|
+
/** Whether `line` closes a block that `marker` opened: the same character, at least as many, nothing after it. */
|
|
5
|
+
export const closesCodeFence = (line, marker) => {
|
|
6
|
+
const fence = fenceLine.exec(line);
|
|
7
|
+
return Boolean(fence && fence[1][0] === marker[0] && fence[1].length >= marker.length && !fence[2].trim());
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/** How many quotes `line` is in: the `>` markers before its content. */
|
|
11
|
+
const quoteDepth = line => (/^(?:[ \t]*>)*/.exec(line)[0].match(/>/g) ?? []).length;
|
|
12
|
+
|
|
13
|
+
/** The fenced code block that is still open at `position`, judged by the text before it: its opening line's start and marker. */
|
|
14
|
+
export const openCodeFence = (text, position) => {
|
|
15
|
+
let open = null;
|
|
16
|
+
let start = 0;
|
|
17
|
+
for (const line of text.slice(0, position).split("\n")) {
|
|
18
|
+
// A block inside a quote ends with that quote, for example at a blank line or an unquoted one.
|
|
19
|
+
if (open && quoteDepth(line) < open.depth) open = null;
|
|
20
|
+
if (open) {
|
|
21
|
+
if (closesCodeFence(line, open.marker)) open = null;
|
|
22
|
+
} else {
|
|
23
|
+
const fence = fenceLine.exec(line);
|
|
24
|
+
// A backtick in the info string makes the line inline code instead of a fence.
|
|
25
|
+
if (fence && !(fence[1][0] === "`" && fence[2].includes("`"))) open = {
|
|
26
|
+
start,
|
|
27
|
+
marker: fence[1],
|
|
28
|
+
depth: quoteDepth(line)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
start += line.length + 1;
|
|
32
|
+
}
|
|
33
|
+
return open && {
|
|
34
|
+
start: open.start,
|
|
35
|
+
marker: open.marker
|
|
36
|
+
};
|
|
37
|
+
};
|
|
1
38
|
export const isInCodeZone = (text, position) => {
|
|
39
|
+
if (openCodeFence(text, position)) return true;
|
|
2
40
|
const before = text.slice(0, position);
|
|
3
|
-
const fences = before.match(/^```/gm);
|
|
4
|
-
if (fences && fences.length % 2 !== 0) return true;
|
|
5
41
|
const line = before.slice(before.lastIndexOf("\n") + 1);
|
|
6
42
|
return (line.match(/`/g) ?? []).length % 2 !== 0;
|
|
7
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["inputs/markdown/code-zone.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/markdown/code-zone.ts"],"sourcesContent":["/** A fence line: optional quote markers and indentation, then three or more backticks or tildes, then the rest. */\nconst fenceLine = /^(?:[ \\t]*>)*[ \\t]*(`{3,}|~{3,})(.*)$/;\n\n/** Whether `line` closes a block that `marker` opened: the same character, at least as many, nothing after it. */\nexport const closesCodeFence = (line: string, marker: string): boolean => {\n const fence = fenceLine.exec(line);\n return Boolean(fence && fence[1]![0] === marker[0] && fence[1]!.length >= marker.length && !fence[2]!.trim());\n};\n\n/** How many quotes `line` is in: the `>` markers before its content. */\nconst quoteDepth = (line: string): number => (/^(?:[ \\t]*>)*/.exec(line)![0].match(/>/g) ?? []).length;\n\n/** The fenced code block that is still open at `position`, judged by the text before it: its opening line's start and marker. */\nexport const openCodeFence = (text: string, position: number): { start: number; marker: string } | null => {\n let open: { start: number; marker: string; depth: number } | null = null;\n let start = 0;\n for (const line of text.slice(0, position).split(\"\\n\")) {\n // A block inside a quote ends with that quote, for example at a blank line or an unquoted one.\n if (open && quoteDepth(line) < open.depth) open = null;\n if (open) {\n if (closesCodeFence(line, open.marker)) open = null;\n } else {\n const fence = fenceLine.exec(line);\n // A backtick in the info string makes the line inline code instead of a fence.\n if (fence && !(fence[1]![0] === \"`\" && fence[2]!.includes(\"`\"))) open = { start, marker: fence[1]!, depth: quoteDepth(line) };\n }\n start += line.length + 1;\n }\n return open && { start: open.start, marker: open.marker };\n};\n\nexport const isInCodeZone = (text: string, position: number): boolean => {\n if (openCodeFence(text, position)) return true;\n const before = text.slice(0, position);\n const line = before.slice(before.lastIndexOf(\"\\n\") + 1);\n return (line.match(/`/g) ?? []).length % 2 !== 0;\n};\n"],"mappings":"AAAA;AACA,MAAM,SAAS,GAAG,uCAAuC;;AAEzD;AACA,OAAO,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,MAAc,KAAc;EACxE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;EAClC,OAAO,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAE,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAAC;AAC/G,CAAC;;AAED;AACA,MAAM,UAAU,GAAI,IAAY,IAAa,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM;;AAEtG;AACA,OAAO,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,QAAgB,KAA+C;EACzG,IAAI,IAA6D,GAAG,IAAI;EACxE,IAAI,KAAK,GAAG,CAAC;EACb,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;IACtD;IACA,IAAI,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IACtD,IAAI,IAAI,EAAE;MACR,IAAI,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI;IACrD,CAAC,MAAM;MACL,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;MAClC;MACA,IAAI,KAAK,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG;QAAE,KAAK;QAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE;QAAE,KAAK,EAAE,UAAU,CAAC,IAAI;MAAE,CAAC;IAC/H;IACA,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;EAC1B;EACA,OAAO,IAAI,IAAI;IAAE,KAAK,EAAE,IAAI,CAAC,KAAK;IAAE,MAAM,EAAE,IAAI,CAAC;EAAO,CAAC;AAC3D,CAAC;AAED,OAAO,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,QAAgB,KAAc;EACvE,IAAI,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,IAAI;EAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;EACtC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,GAAG,CAAC,KAAK,CAAC;AAClD,CAAC","ignoreList":[]}
|