@youcan/celeste 0.6.30 → 0.6.31

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.
Files changed (99) hide show
  1. package/dist/celeste.css +293 -74
  2. package/dist/cjs/alert.js +2 -2
  3. package/dist/cjs/chunks/index.js +229 -2
  4. package/dist/cjs/chunks/index2.js +1457 -0
  5. package/dist/cjs/chunks/index3.js +16457 -0
  6. package/dist/cjs/chunks/sonner.js +1153 -0
  7. package/dist/cjs/config.js +136 -0
  8. package/dist/cjs/extra-settings.js +155 -0
  9. package/dist/cjs/index.js +9 -0
  10. package/dist/cjs/label.js +2 -2
  11. package/dist/cjs/link-bubble.js +228 -0
  12. package/dist/cjs/link-button.js +2 -2
  13. package/dist/cjs/rich-editor.js +4996 -0
  14. package/dist/cjs/select-icon.js +2 -2
  15. package/dist/cjs/sonner-alert.js +41 -0
  16. package/dist/cjs/sonner.js +3 -0
  17. package/dist/cjs/text-input-affix.js +2 -2
  18. package/dist/cjs/types.js +1 -0
  19. package/dist/components/index.d.ts +2 -0
  20. package/dist/components/rich-editor/config.d.ts +33 -0
  21. package/dist/components/rich-editor/extra-settings.d.ts +6 -0
  22. package/dist/components/rich-editor/index.d.ts +2 -0
  23. package/dist/components/rich-editor/link-bubble.d.ts +11 -0
  24. package/dist/components/rich-editor/rich-editor.d.ts +55 -0
  25. package/dist/components/rich-editor/types.d.ts +19 -0
  26. package/dist/components/sonner/index.d.ts +4 -0
  27. package/dist/components/sonner/sonner-alert.d.ts +13 -0
  28. package/dist/components/sonner/sonner.d.ts +5 -0
  29. package/dist/es/alert.js +2 -2
  30. package/dist/es/checkbox-label.js +1 -1
  31. package/dist/es/chunks/index.js +277 -50
  32. package/dist/es/chunks/index2.js +1457 -0
  33. package/dist/es/chunks/index3.js +16458 -0
  34. package/dist/es/chunks/sonner.js +1154 -0
  35. package/dist/es/combobox-group.js +1 -1
  36. package/dist/es/combobox-input.js +1 -1
  37. package/dist/es/combobox-item.js +1 -1
  38. package/dist/es/combobox-list.js +1 -1
  39. package/dist/es/combobox-root.js +1 -1
  40. package/dist/es/combobox-separator.js +1 -1
  41. package/dist/es/combobox-trigger.js +1 -1
  42. package/dist/es/command-group.js +1 -1
  43. package/dist/es/command-input.js +1 -1
  44. package/dist/es/command-item.js +1 -1
  45. package/dist/es/command-list.js +1 -1
  46. package/dist/es/command-root.js +1 -1
  47. package/dist/es/command-separator.js +1 -1
  48. package/dist/es/config.js +136 -0
  49. package/dist/es/dropdown-menu-group.js +1 -1
  50. package/dist/es/dropdown-menu-item.js +1 -1
  51. package/dist/es/dropdown-menu-label.js +1 -1
  52. package/dist/es/dropdown-menu-separator.js +1 -1
  53. package/dist/es/dropdown-menu-trigger.js +1 -1
  54. package/dist/es/dropdown-menu.js +1 -1
  55. package/dist/es/dropdown.js +1 -1
  56. package/dist/es/extra-settings.js +156 -0
  57. package/dist/es/index.js +27 -18
  58. package/dist/es/label.js +3 -3
  59. package/dist/es/link-bubble.js +229 -0
  60. package/dist/es/link-button.js +2 -2
  61. package/dist/es/modal-content.js +1 -1
  62. package/dist/es/modal-header.js +1 -1
  63. package/dist/es/popover-content.js +1 -1
  64. package/dist/es/popover-trigger.js +1 -1
  65. package/dist/es/rich-editor.js +4997 -0
  66. package/dist/es/scroll-bar.js +1 -1
  67. package/dist/es/segmented-control-item.js +1 -1
  68. package/dist/es/segmented-control.js +1 -1
  69. package/dist/es/select-content.js +1 -1
  70. package/dist/es/select-icon.js +2 -2
  71. package/dist/es/select-item.js +1 -1
  72. package/dist/es/select-trigger.js +1 -1
  73. package/dist/es/select-value.js +1 -1
  74. package/dist/es/sonner-alert.js +42 -0
  75. package/dist/es/sonner.js +4 -0
  76. package/dist/es/tab-menu-content.js +1 -1
  77. package/dist/es/tab-menu-item.js +1 -1
  78. package/dist/es/tab-menu-list.js +1 -1
  79. package/dist/es/tab-menu.js +1 -1
  80. package/dist/es/text-input-affix.js +2 -2
  81. package/dist/es/tooltip.js +1 -1
  82. package/dist/es/types.js +1 -0
  83. package/dist/utils/index.d.ts +3 -0
  84. package/dist/utils/sonner.d.ts +19 -0
  85. package/package.json +15 -4
  86. package/src/components/index.ts +2 -0
  87. package/src/components/rich-editor/config.ts +150 -0
  88. package/src/components/rich-editor/extra-settings.vue +151 -0
  89. package/src/components/rich-editor/index.ts +2 -0
  90. package/src/components/rich-editor/link-bubble.vue +288 -0
  91. package/src/components/rich-editor/rich-editor.vue +428 -0
  92. package/src/components/rich-editor/stories/rich-editor.stories.ts +87 -0
  93. package/src/components/rich-editor/types.ts +21 -0
  94. package/src/components/sonner/index.ts +5 -0
  95. package/src/components/sonner/sonner-alert.vue +54 -0
  96. package/src/components/sonner/sonner.vue +13 -0
  97. package/src/components/sonner/stories/sonner.stories.ts +194 -0
  98. package/src/utils/index.ts +3 -0
  99. package/src/utils/sonner.ts +72 -0
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const Mo = require("vue");
4
+ const fullToolbar = Mo.ref([
5
+ {
6
+ slug: "heading",
7
+ name: "Text styles",
8
+ children: [
9
+ { option: "p", name: "Normal text", active: "paragraph" },
10
+ { option: "1", name: "Heading 1", active: { level: 1 } },
11
+ { option: "2", name: "Heading 2", active: { level: 2 } },
12
+ { option: "3", name: "Heading 3", active: { level: 3 } },
13
+ { option: "4", name: "Heading 4", active: { level: 4 } },
14
+ { option: "5", name: "Heading 5", active: { level: 5 } },
15
+ { option: "6", name: "Heading 6", active: { level: 6 } }
16
+ ]
17
+ },
18
+ { type: "divider" },
19
+ {
20
+ slug: "fontSize",
21
+ name: "Font size",
22
+ children: [
23
+ { option: "8px", name: "8", active: { fontSize: "8px" } },
24
+ { option: "10px", name: "10", active: { fontSize: "10px" } },
25
+ { option: "12px", name: "12", active: { fontSize: "12px" } },
26
+ { option: "14px", name: "14", active: { fontSize: "14px" } },
27
+ { option: "16px", name: "16", active: { fontSize: "16px" } },
28
+ { option: "18px", name: "18", active: { fontSize: "18px" } },
29
+ { option: "24px", name: "24", active: { fontSize: "24px" } },
30
+ { option: "30px", name: "30", active: { fontSize: "30px" } },
31
+ { option: "36px", name: "36", active: { fontSize: "36px" } },
32
+ { option: "48px", name: "48", active: { fontSize: "48px" } },
33
+ { option: "60px", name: "60", active: { fontSize: "60px" } },
34
+ { option: "72px", name: "72", active: { fontSize: "72px" } },
35
+ { option: "96px", name: "96", active: { fontSize: "96px" } }
36
+ ]
37
+ },
38
+ { type: "divider" },
39
+ {
40
+ slug: "color",
41
+ name: "Text color",
42
+ children: [
43
+ { option: "#000000", name: "Black", icon: "i-celeste-circle-fill", active: { color: "#000000" } },
44
+ { option: "#7B7B7B", name: "Gray", icon: "i-celeste-circle-fill", active: { color: "#7B7B7B" } },
45
+ { option: "#335CFF", name: "Blue", icon: "i-celeste-circle-fill", active: { color: "#335CFF" } },
46
+ { option: "#FA7319", name: "Orange", icon: "i-celeste-circle-fill", active: { color: "#FA7319" } },
47
+ { option: "#7D52F4", name: "Purple", icon: "i-celeste-circle-fill", active: { color: "#7D52F4" } },
48
+ { option: "#47C2FF", name: "Sky", icon: "i-celeste-circle-fill", active: { color: "#47C2FF" } }
49
+ ]
50
+ },
51
+ { type: "divider" },
52
+ { slug: "bold", name: "Bold", icon: "i-celeste-bold", active: "bold" },
53
+ { slug: "italic", name: "Italic", icon: "i-celeste-italic", active: "italic" },
54
+ { slug: "underline", name: "Underline", icon: "i-celeste-underline", active: "underline" },
55
+ { slug: "strike", name: "Strike", icon: "i-celeste-strikethrough", active: "strike" },
56
+ { type: "divider" },
57
+ { slug: "bulletList", name: "Bulleted list", icon: "i-celeste-list-unordered", active: "bulletList" },
58
+ { slug: "orderedList", name: "Numbered list", icon: "i-celeste-list-ordered", active: "orderedList" },
59
+ { type: "divider" },
60
+ {
61
+ slug: "align",
62
+ name: "Text alignment",
63
+ children: [
64
+ { option: "left", name: "Left align", icon: "i-celeste-align-left", active: { textAlign: "left" } },
65
+ { option: "center", name: "Center align", icon: "i-celeste-align-center", active: { textAlign: "center" } },
66
+ { option: "right", name: "Right align", icon: "i-celeste-align-right", active: { textAlign: "right" } },
67
+ { option: "justify", name: "Justify", icon: "i-celeste-align-justify", active: { textAlign: "justify" } }
68
+ ]
69
+ },
70
+ { type: "divider" },
71
+ { slug: "link", name: "Insert Link", icon: "i-celeste-link", active: "link" },
72
+ { type: "divider" },
73
+ { slug: "undo", name: "Undo", icon: "i-celeste-arrow-go-back-line", active: "undo" },
74
+ { slug: "redo", name: "Redo", icon: "i-celeste-arrow-go-forward-line", active: "redo" },
75
+ { slug: "clear", name: "Clear style", icon: "i-celeste-format-clear", active: "clear" }
76
+ ]);
77
+ function onActionClick(editor, slug, option = null, showLinkBubble) {
78
+ var _a;
79
+ const chain = editor.chain().focus();
80
+ if (!chain) {
81
+ return;
82
+ }
83
+ const actionTriggers = {
84
+ heading: () => {
85
+ if (!option) {
86
+ return;
87
+ }
88
+ if (option === "p") {
89
+ chain.setParagraph().run();
90
+ } else {
91
+ const headingLevel = Number(option);
92
+ chain.toggleHeading({ level: headingLevel }).run();
93
+ }
94
+ },
95
+ fontSize: () => {
96
+ editor.chain().focus().setFontSize(option ?? "16px").run();
97
+ },
98
+ color: () => {
99
+ editor.chain().focus().setColor(option ?? "#000000").run();
100
+ },
101
+ bold: () => chain.toggleBold().run(),
102
+ italic: () => chain.toggleItalic().run(),
103
+ underline: () => chain.toggleUnderline().run(),
104
+ strike: () => chain.toggleStrike().run(),
105
+ bulletList: () => chain.toggleBulletList().run(),
106
+ orderedList: () => chain.toggleOrderedList().run(),
107
+ align: () => chain.setTextAlign(option ?? "left").run(),
108
+ link: () => {
109
+ if (showLinkBubble) {
110
+ showLinkBubble();
111
+ }
112
+ },
113
+ undo: () => chain.undo().run(),
114
+ redo: () => chain.redo().run(),
115
+ clear: () => chain.clearNodes().unsetAllMarks().run()
116
+ };
117
+ (_a = actionTriggers[slug]) == null ? void 0 : _a.call(actionTriggers);
118
+ }
119
+ function selectedOption(editor, children) {
120
+ if (!Array.isArray(children)) {
121
+ return "";
122
+ }
123
+ for (const child of children) {
124
+ if (Object.prototype.hasOwnProperty.call(child.active, "fontSize")) {
125
+ const currentFontSize = editor.getAttributes("textStyle").fontSize || "16px";
126
+ return currentFontSize;
127
+ }
128
+ if (editor.isActive(child.active)) {
129
+ return child.option;
130
+ }
131
+ }
132
+ return children[0].option;
133
+ }
134
+ exports.fullToolbar = fullToolbar;
135
+ exports.onActionClick = onActionClick;
136
+ exports.selectedOption = selectedOption;
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ const Mo = require("vue");
3
+ const compactButton = require("./compact-button.js");
4
+ const selectContent = require("./select-content.js");
5
+ const selectIcon = require("./select-icon.js");
6
+ const selectItem = require("./select-item.js");
7
+ const selectTrigger = require("./select-trigger.js");
8
+ const select_vue_vue_type_script_setup_true_lang = require("./chunks/select.js");
9
+ const tooltip = require("./tooltip.js");
10
+ const _pluginVue_exportHelper = require("./chunks/_plugin-vue_export-helper.js");
11
+ const _hoisted_1 = { class: "show-more-wrapper" };
12
+ const _sfc_main = /* @__PURE__ */ Mo.defineComponent({
13
+ __name: "extra-settings",
14
+ props: {
15
+ editor: {}
16
+ },
17
+ setup(__props) {
18
+ const props = __props;
19
+ const defaultValue = Mo.ref("");
20
+ const extraSettings = [
21
+ {
22
+ name: "Copy",
23
+ icon: "i-celeste-file-copy-line"
24
+ },
25
+ {
26
+ name: "Cut",
27
+ icon: "i-celeste-scissors-line"
28
+ },
29
+ {
30
+ name: "Delete",
31
+ icon: "i-celeste-delete-bin-4-line"
32
+ },
33
+ {
34
+ name: "Duplicate",
35
+ icon: "i-celeste-add-circle-line"
36
+ }
37
+ ];
38
+ function selectedText(editor) {
39
+ const { from, to } = editor.state.selection;
40
+ const text = editor.state.doc.textBetween(from, to, "\n");
41
+ return text || null;
42
+ }
43
+ async function copySelectionToClipboard(editor) {
44
+ const text = selectedText(editor);
45
+ if (!text) {
46
+ return;
47
+ }
48
+ try {
49
+ if (!window.isSecureContext) {
50
+ throw new Error("Clipboard API is not available in insecure contexts");
51
+ }
52
+ const copyText = await navigator.clipboard.writeText(text);
53
+ return copyText;
54
+ } catch (error) {
55
+ console.error(error);
56
+ }
57
+ }
58
+ async function cutSelection(editor) {
59
+ await copySelectionToClipboard(editor);
60
+ deleteSelection(editor);
61
+ }
62
+ function deleteSelection(editor) {
63
+ return editor.commands.deleteSelection();
64
+ }
65
+ function duplicateSelection(editor) {
66
+ const { to } = editor.state.selection;
67
+ const text = selectedText(editor);
68
+ if (!text) {
69
+ return;
70
+ }
71
+ return editor.commands.insertContentAt(to, text);
72
+ }
73
+ function clearSelectedValue() {
74
+ defaultValue.value = "";
75
+ }
76
+ function onActionClick(name, editor) {
77
+ switch (name) {
78
+ case "Copy":
79
+ copySelectionToClipboard(editor);
80
+ break;
81
+ case "Cut":
82
+ cutSelection(editor);
83
+ break;
84
+ case "Delete":
85
+ deleteSelection(editor);
86
+ break;
87
+ case "Duplicate":
88
+ duplicateSelection(editor);
89
+ break;
90
+ }
91
+ }
92
+ return (_ctx, _cache) => {
93
+ return Mo.openBlock(), Mo.createElementBlock("div", _hoisted_1, [
94
+ Mo.createVNode(select_vue_vue_type_script_setup_true_lang._sfc_main, {
95
+ modelValue: defaultValue.value,
96
+ "onUpdate:modelValue": [
97
+ _cache[0] || (_cache[0] = ($event) => defaultValue.value = $event),
98
+ _cache[1] || (_cache[1] = ($event) => onActionClick($event, props.editor))
99
+ ],
100
+ "onUpdate:open": clearSelectedValue
101
+ }, {
102
+ default: Mo.withCtx(() => [
103
+ Mo.createVNode(selectTrigger, { variant: "inline" }, {
104
+ default: Mo.withCtx(() => [
105
+ Mo.createVNode(tooltip, {
106
+ title: "Extra settings",
107
+ variant: "dark"
108
+ }, {
109
+ default: Mo.withCtx(() => [
110
+ Mo.createVNode(compactButton, {
111
+ icon: "i-celeste-more-2-line",
112
+ variant: "ghost"
113
+ })
114
+ ]),
115
+ _: 1
116
+ })
117
+ ]),
118
+ _: 1
119
+ }),
120
+ Mo.createVNode(selectContent, {
121
+ align: "end",
122
+ width: "fit"
123
+ }, {
124
+ default: Mo.withCtx(() => [
125
+ (Mo.openBlock(), Mo.createElementBlock(Mo.Fragment, null, Mo.renderList(extraSettings, (item, index) => {
126
+ return Mo.createVNode(selectItem, {
127
+ key: index,
128
+ value: item.name
129
+ }, {
130
+ default: Mo.withCtx(() => [
131
+ Mo.createVNode(selectIcon, null, {
132
+ default: Mo.withCtx(() => [
133
+ Mo.createElementVNode("i", {
134
+ class: Mo.normalizeClass(item.icon)
135
+ }, null, 2)
136
+ ]),
137
+ _: 2
138
+ }, 1024),
139
+ Mo.createElementVNode("span", null, Mo.toDisplayString(item.name), 1)
140
+ ]),
141
+ _: 2
142
+ }, 1032, ["value"]);
143
+ }), 64))
144
+ ]),
145
+ _: 1
146
+ })
147
+ ]),
148
+ _: 1
149
+ }, 8, ["modelValue"])
150
+ ]);
151
+ };
152
+ }
153
+ });
154
+ const ExtraSettings = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-49d51443"]]);
155
+ module.exports = ExtraSettings;
package/dist/cjs/index.js CHANGED
@@ -46,6 +46,7 @@ const modal_vue_vue_type_script_setup_true_lang = require("./chunks/modal.js");
46
46
  const popoverContent = require("./popover-content.js");
47
47
  const popoverTrigger = require("./popover-trigger.js");
48
48
  const popover_vue_vue_type_script_setup_true_lang = require("./chunks/popover.js");
49
+ const richEditor = require("./rich-editor.js");
49
50
  const scrollArea_vue_vue_type_script_setup_true_lang = require("./chunks/scroll-area.js");
50
51
  const segmentedControlItem = require("./segmented-control-item.js");
51
52
  const segmentedControl = require("./segmented-control.js");
@@ -59,6 +60,8 @@ const selectTrigger = require("./select-trigger.js");
59
60
  const selectValue = require("./select-value.js");
60
61
  const select_vue_vue_type_script_setup_true_lang = require("./chunks/select.js");
61
62
  const slider_vue_vue_type_style_index_0_lang = require("./chunks/slider.vue_vue_type_style_index_0_lang.js");
63
+ const sonnerAlert = require("./sonner-alert.js");
64
+ const sonner_vue_vue_type_script_setup_true_lang = require("./chunks/sonner.js");
62
65
  const switch_vue_vue_type_style_index_0_lang = require("./chunks/switch.vue_vue_type_style_index_0_lang.js");
63
66
  const tabMenuContent = require("./tab-menu-content.js");
64
67
  const tabMenuItem = require("./tab-menu-item.js");
@@ -115,6 +118,7 @@ const components = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
115
118
  Popover: popover_vue_vue_type_script_setup_true_lang._sfc_main,
116
119
  PopoverContent: popoverContent,
117
120
  PopoverTrigger: popoverTrigger,
121
+ RichEditor: richEditor,
118
122
  ScrollArea: scrollArea_vue_vue_type_script_setup_true_lang._sfc_main,
119
123
  SegmentedControl: segmentedControl,
120
124
  SegmentedControlItem: segmentedControlItem,
@@ -129,6 +133,8 @@ const components = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
129
133
  SelectValue: selectValue,
130
134
  Slider: slider_vue_vue_type_style_index_0_lang._sfc_main,
131
135
  SocialButton: socialButton,
136
+ Sonner: sonner_vue_vue_type_script_setup_true_lang._sfc_main,
137
+ SonnerAlert: sonnerAlert,
132
138
  StatusBadge: statusBadge,
133
139
  Switch: switch_vue_vue_type_style_index_0_lang._sfc_main,
134
140
  TabMenu: tabMenu,
@@ -194,6 +200,7 @@ exports.Modal = modal_vue_vue_type_script_setup_true_lang._sfc_main;
194
200
  exports.PopoverContent = popoverContent;
195
201
  exports.PopoverTrigger = popoverTrigger;
196
202
  exports.Popover = popover_vue_vue_type_script_setup_true_lang._sfc_main;
203
+ exports.RichEditor = richEditor;
197
204
  exports.ScrollArea = scrollArea_vue_vue_type_script_setup_true_lang._sfc_main;
198
205
  exports.SegmentedControlItem = segmentedControlItem;
199
206
  exports.SegmentedControl = segmentedControl;
@@ -207,6 +214,8 @@ exports.SelectTrigger = selectTrigger;
207
214
  exports.SelectValue = selectValue;
208
215
  exports.Select = select_vue_vue_type_script_setup_true_lang._sfc_main;
209
216
  exports.Slider = slider_vue_vue_type_style_index_0_lang._sfc_main;
217
+ exports.SonnerAlert = sonnerAlert;
218
+ exports.Sonner = sonner_vue_vue_type_script_setup_true_lang._sfc_main;
210
219
  exports.Switch = switch_vue_vue_type_style_index_0_lang._sfc_main;
211
220
  exports.TabMenuContent = tabMenuContent;
212
221
  exports.TabMenuItem = tabMenuItem;
package/dist/cjs/label.js CHANGED
@@ -51,5 +51,5 @@ const _sfc_main = /* @__PURE__ */ Mo.defineComponent({
51
51
  };
52
52
  }
53
53
  });
54
- const label = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-4768213c"]]);
55
- module.exports = label;
54
+ const Label = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-4768213c"]]);
55
+ module.exports = Label;
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ const Mo = require("vue");
3
+ const button = require("./button.js");
4
+ const compactButton = require("./compact-button.js");
5
+ const linkButton = require("./link-button.js");
6
+ const label = require("./label.js");
7
+ const switch_vue_vue_type_style_index_0_lang = require("./chunks/switch.vue_vue_type_style_index_0_lang.js");
8
+ const textInputAffix = require("./text-input-affix.js");
9
+ const textInput = require("./text-input.js");
10
+ const _pluginVue_exportHelper = require("./chunks/_plugin-vue_export-helper.js");
11
+ const _hoisted_1 = {
12
+ key: 0,
13
+ class: "set-mode"
14
+ };
15
+ const _hoisted_2 = { class: "set-link" };
16
+ const _hoisted_3 = { class: "switch-button-box" };
17
+ const _hoisted_4 = {
18
+ key: 1,
19
+ class: "edit-mode"
20
+ };
21
+ const _sfc_main = /* @__PURE__ */ Mo.defineComponent({
22
+ __name: "link-bubble",
23
+ props: {
24
+ editor: {},
25
+ showSetLinkFromToolbar: { type: Boolean }
26
+ },
27
+ emits: ["set-link-closed"],
28
+ setup(__props, { emit: __emit }) {
29
+ const props = __props;
30
+ const emit = __emit;
31
+ const BubbleMenu = Mo.defineAsyncComponent(
32
+ () => Promise.resolve().then(() => require("./chunks/index2.js")).then((m) => m.BubbleMenu)
33
+ );
34
+ const href = Mo.ref("");
35
+ const openInNewTab = Mo.ref(false);
36
+ const editing = Mo.ref(false);
37
+ const isTextSelected = () => props.editor.state.selection.from !== props.editor.state.selection.to;
38
+ const showBubble = Mo.computed(() => {
39
+ return editing.value || props.editor.isActive("link") || props.showSetLinkFromToolbar && isTextSelected();
40
+ });
41
+ function startEdit() {
42
+ editing.value = true;
43
+ const attrs = props.editor.getAttributes("link");
44
+ href.value = attrs.href || "";
45
+ openInNewTab.value = attrs.target === "_blank";
46
+ }
47
+ function removeLink() {
48
+ props.editor.chain().focus().unsetLink().run();
49
+ reset();
50
+ }
51
+ function reset() {
52
+ editing.value = false;
53
+ href.value = "";
54
+ openInNewTab.value = false;
55
+ emit("set-link-closed");
56
+ }
57
+ function truncateMiddleUrl(str) {
58
+ const maxLength = 40;
59
+ if (str.length <= maxLength) {
60
+ return str;
61
+ }
62
+ const startChars = Math.ceil((maxLength - 3) / 2);
63
+ const endChars = Math.floor((maxLength - 3) / 2);
64
+ return `${str.slice(0, startChars)}...${str.slice(-endChars)}`;
65
+ }
66
+ function isAllowedUri() {
67
+ const url = href.value.trim();
68
+ if (!url || url.includes(" ")) {
69
+ return false;
70
+ }
71
+ if (url.startsWith("/")) {
72
+ return true;
73
+ }
74
+ if (url.startsWith("./") || url.startsWith("../")) {
75
+ return false;
76
+ }
77
+ const allowedProtocols = /^(?:https?:|mailto:)/i;
78
+ const disallowedProtocols = /^(?:javascript:|data:)/i;
79
+ if (disallowedProtocols.test(url)) {
80
+ return false;
81
+ }
82
+ if (allowedProtocols.test(url)) {
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+ const isValidUrl = Mo.computed(() => isAllowedUri());
88
+ function applyLink() {
89
+ if (!href.value || !isValidUrl.value) {
90
+ return;
91
+ }
92
+ props.editor.chain().focus().extendMarkRange("link").setLink({
93
+ href: href.value,
94
+ target: openInNewTab.value ? "_blank" : null
95
+ }).run();
96
+ reset();
97
+ }
98
+ const bubbleRef = Mo.ref(null);
99
+ function handleClickOutside(event) {
100
+ const target = event.target;
101
+ if (!bubbleRef.value) {
102
+ return;
103
+ }
104
+ if (bubbleRef.value && bubbleRef.value.contains(target)) {
105
+ return;
106
+ }
107
+ if (target.closest(".i-celeste-link")) {
108
+ return;
109
+ }
110
+ emit("set-link-closed");
111
+ }
112
+ Mo.onMounted(() => {
113
+ props.editor.on("selectionUpdate", () => {
114
+ if (props.editor.isActive("link") || props.showSetLinkFromToolbar) {
115
+ const attrs = props.editor.getAttributes("link");
116
+ href.value = attrs.href || "";
117
+ openInNewTab.value = attrs.target === "_blank";
118
+ } else {
119
+ reset();
120
+ }
121
+ });
122
+ document.addEventListener("click", handleClickOutside);
123
+ });
124
+ Mo.onUnmounted(() => {
125
+ document.removeEventListener("click", handleClickOutside);
126
+ });
127
+ return (_ctx, _cache) => {
128
+ return Mo.openBlock(), Mo.createBlock(Mo.unref(BubbleMenu), {
129
+ "should-show": () => true,
130
+ editor: _ctx.editor,
131
+ options: {
132
+ placement: "bottom",
133
+ offset: {
134
+ mainAxis: 0,
135
+ crossAxis: 12
136
+ }
137
+ }
138
+ }, {
139
+ default: Mo.withCtx(() => [
140
+ showBubble.value ? (Mo.openBlock(), Mo.createElementBlock("div", {
141
+ key: 0,
142
+ ref_key: "bubbleRef",
143
+ ref: bubbleRef,
144
+ class: "link-bubble"
145
+ }, [
146
+ editing.value || props.showSetLinkFromToolbar && isTextSelected() ? (Mo.openBlock(), Mo.createElementBlock("div", _hoisted_1, [
147
+ Mo.createElementVNode("div", _hoisted_2, [
148
+ Mo.createVNode(textInput, {
149
+ modelValue: href.value,
150
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => href.value = $event),
151
+ type: "url",
152
+ size: "xs",
153
+ placeholder: "Paste or type a link",
154
+ class: "link-input",
155
+ onKeydown: [
156
+ Mo.withKeys(applyLink, ["enter"]),
157
+ Mo.withKeys(reset, ["esc"])
158
+ ]
159
+ }, {
160
+ leadingNode: Mo.withCtx(() => [
161
+ Mo.createVNode(textInputAffix, null, {
162
+ default: Mo.withCtx(() => _cache[2] || (_cache[2] = [
163
+ Mo.createElementVNode("i", { class: "i-celeste-link" }, null, -1)
164
+ ])),
165
+ _: 1
166
+ })
167
+ ]),
168
+ _: 1
169
+ }, 8, ["modelValue"]),
170
+ Mo.createVNode(button, {
171
+ intent: "neutral",
172
+ size: "xs",
173
+ variant: "stroke",
174
+ disabled: !isValidUrl.value,
175
+ onClick: applyLink
176
+ }, {
177
+ default: Mo.withCtx(() => _cache[3] || (_cache[3] = [
178
+ Mo.createTextVNode(" Set link ")
179
+ ])),
180
+ _: 1
181
+ }, 8, ["disabled"])
182
+ ]),
183
+ Mo.createElementVNode("div", _hoisted_3, [
184
+ Mo.createVNode(label, { for: "open-in-new-tab" }, {
185
+ default: Mo.withCtx(() => _cache[4] || (_cache[4] = [
186
+ Mo.createTextVNode(" Open in new tab ")
187
+ ])),
188
+ _: 1
189
+ }),
190
+ Mo.createVNode(switch_vue_vue_type_style_index_0_lang._sfc_main, {
191
+ id: "open-in-new-tab",
192
+ checked: openInNewTab.value,
193
+ "onUpdate:checked": _cache[1] || (_cache[1] = ($event) => openInNewTab.value = $event)
194
+ }, null, 8, ["checked"])
195
+ ])
196
+ ])) : props.editor.isActive("link") ? (Mo.openBlock(), Mo.createElementBlock("div", _hoisted_4, [
197
+ Mo.createVNode(linkButton, {
198
+ href: _ctx.editor.getAttributes("link").href,
199
+ target: _ctx.editor.getAttributes("link").target
200
+ }, {
201
+ default: Mo.withCtx(() => [
202
+ Mo.createTextVNode(Mo.toDisplayString(truncateMiddleUrl(_ctx.editor.getAttributes("link").href)), 1)
203
+ ]),
204
+ _: 1
205
+ }, 8, ["href", "target"]),
206
+ _cache[5] || (_cache[5] = Mo.createElementVNode("div", { class: "divider" }, null, -1)),
207
+ Mo.createVNode(compactButton, {
208
+ icon: "i-celeste-edit-line",
209
+ size: "lg",
210
+ variant: "ghost",
211
+ onClick: startEdit
212
+ }),
213
+ Mo.createVNode(compactButton, {
214
+ icon: "i-celeste-delete-bin-line",
215
+ size: "lg",
216
+ variant: "ghost",
217
+ onClick: removeLink
218
+ })
219
+ ])) : Mo.createCommentVNode("", true)
220
+ ], 512)) : Mo.createCommentVNode("", true)
221
+ ]),
222
+ _: 1
223
+ }, 8, ["editor"]);
224
+ };
225
+ }
226
+ });
227
+ const LinkBubble = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-c63c1d92"]]);
228
+ module.exports = LinkBubble;
@@ -40,5 +40,5 @@ const _sfc_main = /* @__PURE__ */ Mo.defineComponent({
40
40
  };
41
41
  }
42
42
  });
43
- const linkButton = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-82b3b1ab"]]);
44
- module.exports = linkButton;
43
+ const LinkButton = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-82b3b1ab"]]);
44
+ module.exports = LinkButton;