@threadlabs/looma 0.22.2 → 0.22.4

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.
@@ -403,6 +403,23 @@ var autoCodeLanguageNames = [
403
403
  ];
404
404
  //#endregion
405
405
  //#region src/vue/editor/LoomaEditor.ts
406
+ /**
407
+ * Shows a key binding in ProseMirror notation ("Mod-Shift-8") the way the reader's platform writes
408
+ * it: modifier symbols in Apple's order on Apple devices (⇧⌘8), and Ctrl+Shift+8 elsewhere.
409
+ */
410
+ function formatEditorShortcut(keys, apple) {
411
+ const parts = keys.split("-");
412
+ const key = (parts.pop() ?? "").toUpperCase();
413
+ const has = (name) => parts.includes(name);
414
+ if (apple) return `${has("Ctrl") ? "⌃" : ""}${has("Alt") ? "⌥" : ""}${has("Shift") ? "⇧" : ""}${has("Mod") ? "⌘" : ""}${key}`;
415
+ return [
416
+ has("Mod") || has("Ctrl") ? "Ctrl" : "",
417
+ has("Alt") ? "Alt" : "",
418
+ has("Shift") ? "Shift" : "",
419
+ key
420
+ ].filter(Boolean).join("+");
421
+ }
422
+ var isApplePlatform = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad|iPod/.test(navigator.userAgentData?.platform || navigator.platform || navigator.userAgent);
406
423
  var EMPTY_DOCUMENT = {
407
424
  type: "doc",
408
425
  content: []
@@ -606,16 +623,18 @@ var LoomaEditor = defineComponent({
606
623
  const toolbarScope = `looma-editor-tool-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
607
624
  const tooltipFor = ref("");
608
625
  const tooltipLabel = ref("");
626
+ const tooltipShortcut = ref("");
609
627
  const tooltipOpen = ref(false);
610
628
  let tooltipTimer = 0;
611
629
  const clearTooltipTimer = () => {
612
630
  if (tooltipTimer) window.clearTimeout(tooltipTimer);
613
631
  tooltipTimer = 0;
614
632
  };
615
- const showTool = (id, label, immediate) => {
633
+ const showTool = (id, label, immediate, shortcut = "") => {
616
634
  clearTooltipTimer();
617
635
  tooltipFor.value = id;
618
636
  tooltipLabel.value = label;
637
+ tooltipShortcut.value = shortcut ? formatEditorShortcut(shortcut, isApplePlatform()) : "";
619
638
  if (immediate || tooltipOpen.value) {
620
639
  tooltipOpen.value = true;
621
640
  return;
@@ -1507,7 +1526,7 @@ var LoomaEditor = defineComponent({
1507
1526
  const onTableOverlayMouseDown = (event) => {
1508
1527
  if (event.target instanceof Element ? event.target.closest("button[data-action]") : null) event.preventDefault();
1509
1528
  };
1510
- const commandButton = (label, icon, active, disabled, run) => {
1529
+ const commandButton = (label, icon, active, disabled, run, shortcut = "") => {
1511
1530
  const syncNativeDisabled = (vnode) => {
1512
1531
  if (!(vnode.el instanceof Element)) return;
1513
1532
  const button = vnode.el instanceof HTMLButtonElement ? vnode.el : vnode.el.querySelector("button");
@@ -1519,9 +1538,9 @@ var LoomaEditor = defineComponent({
1519
1538
  class: "looma-editor__toolbar-button",
1520
1539
  label,
1521
1540
  size: "sm",
1522
- onPointerenter: () => showTool(id, label, false),
1541
+ onPointerenter: () => showTool(id, label, false, shortcut),
1523
1542
  onPointerleave: hideTool,
1524
- onFocusin: () => showTool(id, label, true),
1543
+ onFocusin: () => showTool(id, label, true, shortcut),
1525
1544
  onFocusout: hideTool,
1526
1545
  variant: "ghost",
1527
1546
  disabled,
@@ -1534,12 +1553,12 @@ var LoomaEditor = defineComponent({
1534
1553
  };
1535
1554
  const renderToolbar = (instance, floating = true, textOnly = false) => {
1536
1555
  const textButtons = [
1537
- commandButton("Bold", "bold", instance.isActive("bold"), !instance.can().toggleBold(), () => instance.chain().focus().toggleBold().run()),
1538
- commandButton("Italic", "italic", instance.isActive("italic"), !instance.can().toggleItalic(), () => instance.chain().focus().toggleItalic().run()),
1539
- commandButton("Underline", "underline", instance.isActive("underline"), !instance.can().toggleUnderline(), () => instance.chain().focus().toggleUnderline().run()),
1540
- commandButton("Strike", "strikethrough", instance.isActive("strike"), !instance.can().toggleStrike(), () => instance.chain().focus().toggleStrike().run()),
1541
- ...authorHighlight ? [commandButton("Highlight", "highlighter", instance.isActive("highlight"), !instance.can().toggleHighlight(), () => instance.chain().focus().toggleHighlight().run())] : [],
1542
- commandButton("Inline code", "code-xml", instance.isActive("code"), !instance.can().toggleCode(), () => instance.chain().focus().toggleCode().run())
1556
+ commandButton("Bold", "bold", instance.isActive("bold"), !instance.can().toggleBold(), () => instance.chain().focus().toggleBold().run(), "Mod-b"),
1557
+ commandButton("Italic", "italic", instance.isActive("italic"), !instance.can().toggleItalic(), () => instance.chain().focus().toggleItalic().run(), "Mod-i"),
1558
+ commandButton("Underline", "underline", instance.isActive("underline"), !instance.can().toggleUnderline(), () => instance.chain().focus().toggleUnderline().run(), "Mod-u"),
1559
+ commandButton("Strike", "strikethrough", instance.isActive("strike"), !instance.can().toggleStrike(), () => instance.chain().focus().toggleStrike().run(), "Mod-Shift-s"),
1560
+ ...authorHighlight ? [commandButton("Highlight", "highlighter", instance.isActive("highlight"), !instance.can().toggleHighlight(), () => instance.chain().focus().toggleHighlight().run(), "Mod-Shift-h")] : [],
1561
+ commandButton("Inline code", "code-xml", instance.isActive("code"), !instance.can().toggleCode(), () => instance.chain().focus().toggleCode().run(), "Mod-e")
1543
1562
  ];
1544
1563
  const buttons = textOnly ? textButtons : [
1545
1564
  ...textButtons,
@@ -1568,13 +1587,13 @@ var LoomaEditor = defineComponent({
1568
1587
  class: "divider",
1569
1588
  "aria-hidden": "true"
1570
1589
  }),
1571
- commandButton("Heading 1", "heading-1", instance.isActive("heading", { level: 1 }), false, () => instance.chain().focus().toggleHeading({ level: 1 }).run()),
1572
- commandButton("Heading 2", "heading-2", instance.isActive("heading", { level: 2 }), false, () => instance.chain().focus().toggleHeading({ level: 2 }).run()),
1573
- commandButton("Heading 3", "heading-3", instance.isActive("heading", { level: 3 }), false, () => instance.chain().focus().toggleHeading({ level: 3 }).run()),
1574
- commandButton("Bullet list", "list", instance.isActive("bulletList"), false, () => instance.chain().focus().toggleBulletList().run()),
1575
- commandButton("Numbered list", "list-ordered", instance.isActive("orderedList"), false, () => instance.chain().focus().toggleOrderedList().run()),
1576
- commandButton("Blockquote", "quote", instance.isActive("blockquote"), !instance.can().toggleBlockquote(), () => instance.chain().focus().toggleBlockquote().run()),
1577
- commandButton("Code block", "braces", instance.isActive("codeBlock"), !instance.can().toggleCodeBlock(), () => instance.chain().focus().toggleCodeBlock().run()),
1590
+ commandButton("Heading 1", "heading-1", instance.isActive("heading", { level: 1 }), false, () => instance.chain().focus().toggleHeading({ level: 1 }).run(), "Mod-Alt-1"),
1591
+ commandButton("Heading 2", "heading-2", instance.isActive("heading", { level: 2 }), false, () => instance.chain().focus().toggleHeading({ level: 2 }).run(), "Mod-Alt-2"),
1592
+ commandButton("Heading 3", "heading-3", instance.isActive("heading", { level: 3 }), false, () => instance.chain().focus().toggleHeading({ level: 3 }).run(), "Mod-Alt-3"),
1593
+ commandButton("Bullet list", "list", instance.isActive("bulletList"), false, () => instance.chain().focus().toggleBulletList().run(), "Mod-Shift-8"),
1594
+ commandButton("Numbered list", "list-ordered", instance.isActive("orderedList"), false, () => instance.chain().focus().toggleOrderedList().run(), "Mod-Shift-7"),
1595
+ commandButton("Blockquote", "quote", instance.isActive("blockquote"), !instance.can().toggleBlockquote(), () => instance.chain().focus().toggleBlockquote().run(), "Mod-Shift-b"),
1596
+ commandButton("Code block", "braces", instance.isActive("codeBlock"), !instance.can().toggleCodeBlock(), () => instance.chain().focus().toggleCodeBlock().run(), "Mod-Alt-c"),
1578
1597
  h(IconButton, {
1579
1598
  id: blockActionAnchorId,
1580
1599
  class: "looma-editor__toolbar-button",
@@ -1607,8 +1626,8 @@ var LoomaEditor = defineComponent({
1607
1626
  class: "divider",
1608
1627
  "aria-hidden": "true"
1609
1628
  }),
1610
- commandButton("Undo", "undo", false, !instance.can().undo(), () => instance.chain().focus().undo().run()),
1611
- commandButton("Redo", "redo", false, !instance.can().redo(), () => instance.chain().focus().redo().run())
1629
+ commandButton("Undo", "undo", false, !instance.can().undo(), () => instance.chain().focus().undo().run(), "Mod-z"),
1630
+ commandButton("Redo", "redo", false, !instance.can().redo(), () => instance.chain().focus().redo().run(), isApplePlatform() ? "Mod-Shift-z" : "Mod-y")
1612
1631
  ];
1613
1632
  return h(EditorToolbar, { floating }, () => [...buttons, h(Tooltip, {
1614
1633
  class: "looma-editor__toolbar-tip",
@@ -1616,7 +1635,10 @@ var LoomaEditor = defineComponent({
1616
1635
  open: tooltipOpen.value,
1617
1636
  placement: floating ? "top" : "bottom",
1618
1637
  trigger: "focus"
1619
- }, () => tooltipLabel.value)]);
1638
+ }, {
1639
+ default: () => tooltipLabel.value,
1640
+ shortcut: () => tooltipShortcut.value ? h("kbd", tooltipShortcut.value) : null
1641
+ })]);
1620
1642
  };
1621
1643
  const focus = (position = "start") => {
1622
1644
  editor.value?.commands.focus(position);