feat: add link insertion functionality and update styles for link appearance

This commit is contained in:
Vadim Melnicuk
2026-02-18 20:53:37 +00:00
parent a58ca40a5e
commit 398f73ce95
4 changed files with 34 additions and 12 deletions
-10
View File
@@ -12,16 +12,6 @@
"group": "build-tasks"
}
},
{
"label": "watch",
"dependsOn": [
"build:extension",
"watch:webview"
],
"dependsOrder": "parallel",
"problemMatcher": [],
"group": "build"
},
{
"label": "build:extension",
"type": "shell",
+22
View File
@@ -380,6 +380,8 @@ export function createEditor({ parent, text, onApplyChanges }) {
return insertHr(view, selection);
case 'table':
return insertTable(view, selection, level?.cols, level?.rows);
case 'link':
return insertLink(view, selection);
}
const newMarkerLen = insert.length;
@@ -546,6 +548,26 @@ function insertHr(view, selection) {
});
}
function insertLink(view, selection) {
const { state } = view;
if (!selection.empty) {
const selectedText = state.doc.sliceString(selection.from, selection.to);
const insert = `[${selectedText}]()`;
view.dispatch({
changes: { from: selection.from, to: selection.to, insert },
selection: { anchor: selection.from + insert.length - 1 }
});
return;
}
const insert = '[]()';
view.dispatch({
changes: { from: selection.from, insert },
selection: { anchor: selection.from + 1 }
});
}
function sourceMode() {
return [
markdown({
+10 -2
View File
@@ -1,5 +1,5 @@
import { createEditor } from './editor';
import { createElement, Heading, Heading1, Heading2, Heading3, Heading4, Heading5, Heading6, List, ListOrdered, ListTodo, Save, ListTree, Code, Terminal, Quote, Minus, Table2 } from 'lucide';
import { createElement, Heading, Heading1, Heading2, Heading3, Heading4, Heading5, Heading6, List, ListOrdered, ListTodo, Save, ListTree, Code, Terminal, Quote, Minus, Table2, Link } from 'lucide';
import * as colors from './theme';
for (const [name, value] of Object.entries(colors)) {
@@ -192,6 +192,13 @@ hrBtn.dataset.action = 'hr';
hrBtn.title = 'Horizontal Rule';
hrBtn.appendChild(createElement(Minus, { width: 18, height: 18 }));
const linkBtn = document.createElement('button');
linkBtn.type = 'button';
linkBtn.className = 'format-button';
linkBtn.dataset.action = 'link';
linkBtn.title = 'Link';
linkBtn.appendChild(createElement(Link, { width: 18, height: 18 }));
const tableBtn = document.createElement('button');
tableBtn.type = 'button';
tableBtn.className = 'format-button';
@@ -267,7 +274,7 @@ tableGrid.addEventListener('click', (event) => {
editor.focus();
});
formatGroup.append(headingWrapper, bulletListBtn, numberedListBtn, taskBtn, separator, tableWrapper, codeBlockBtn, inlineCodeBtn, quoteBtn, hrBtn);
formatGroup.append(headingWrapper, bulletListBtn, numberedListBtn, taskBtn, separator, tableWrapper, codeBlockBtn, inlineCodeBtn, linkBtn, quoteBtn, hrBtn);
const rightGroup = document.createElement('div');
rightGroup.className = 'right-group';
@@ -659,6 +666,7 @@ codeBlockBtn.addEventListener('click', () => handleFormatAction('codeBlock'));
inlineCodeBtn.addEventListener('click', () => handleFormatAction('inlineCode'));
quoteBtn.addEventListener('click', () => handleFormatAction('quote'));
hrBtn.addEventListener('click', () => handleFormatAction('hr'));
linkBtn.addEventListener('click', () => handleFormatAction('link'));
autoSaveBtn.addEventListener('click', toggleAutoSave);
outlineBtn.addEventListener('click', toggleOutline);
+2
View File
@@ -394,6 +394,8 @@ body {
.cm-editor .meo-md-link {
text-decoration: underline;
text-decoration-color: var(--meo-color-base05);
text-underline-offset: 4px;
}
.cm-editor .meo-md-quote {