@unhingged/vizu-core 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto.cjs +302 -43
- package/dist/auto.cjs.map +1 -1
- package/dist/auto.js +302 -43
- package/dist/auto.js.map +1 -1
- package/dist/index.cjs +302 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +302 -43
- package/dist/index.js.map +1 -1
- package/dist/vizu.min.js +85 -60
- package/dist/vizu.min.js.map +1 -1
- package/package.json +1 -1
package/dist/auto.cjs
CHANGED
|
@@ -1265,8 +1265,50 @@ var Popover = class {
|
|
|
1265
1265
|
this.mentionPicker = null;
|
|
1266
1266
|
/** Dismiss handlers wired to document for the open picker; cleared in closeMentionPicker. */
|
|
1267
1267
|
this.mentionPickerDismiss = null;
|
|
1268
|
+
/** All mentionable users fetched for the open picker — pre-filter list. */
|
|
1269
|
+
this.mentionPickerUsers = [];
|
|
1270
|
+
/** Currently visible subset of `mentionPickerUsers` after the user's filter. */
|
|
1271
|
+
this.mentionPickerFiltered = [];
|
|
1272
|
+
/** Highlighted index in `mentionPickerFiltered`. Up/Down arrows mutate this. */
|
|
1273
|
+
this.mentionPickerSelected = 0;
|
|
1274
|
+
/**
|
|
1275
|
+
* 'manual' = opened from the @ mention button (separate search input).
|
|
1276
|
+
* 'editor' = opened by typing `@` in the editor; filter is derived
|
|
1277
|
+
* from the text after `@` in the editor itself, no search input.
|
|
1278
|
+
*/
|
|
1279
|
+
this.mentionPickerMode = "manual";
|
|
1280
|
+
/**
|
|
1281
|
+
* In editor mode: a Range covering `@<query>` in the editor's text.
|
|
1282
|
+
* Used to replace that span with the mention chip on commit, and to
|
|
1283
|
+
* recompute the bounding rect when re-positioning after typing.
|
|
1284
|
+
*/
|
|
1285
|
+
this.mentionPickerEditorRange = null;
|
|
1268
1286
|
this.handleEditorKey = (e) => {
|
|
1269
1287
|
const editor = e.currentTarget;
|
|
1288
|
+
if (this.mentionPicker && this.mentionPickerMode === "editor") {
|
|
1289
|
+
if (e.key === "ArrowDown") {
|
|
1290
|
+
e.preventDefault();
|
|
1291
|
+
this.moveMentionPickerSelection(1);
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
if (e.key === "ArrowUp") {
|
|
1295
|
+
e.preventDefault();
|
|
1296
|
+
this.moveMentionPickerSelection(-1);
|
|
1297
|
+
return;
|
|
1298
|
+
}
|
|
1299
|
+
if (e.key === "Enter" || e.key === "Tab") {
|
|
1300
|
+
if (this.mentionPickerFiltered.length > 0) {
|
|
1301
|
+
e.preventDefault();
|
|
1302
|
+
this.commitMentionPickerSelection();
|
|
1303
|
+
return;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
if (e.key === "Escape") {
|
|
1307
|
+
e.preventDefault();
|
|
1308
|
+
this.closeMentionPicker();
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1270
1312
|
if (e.key === "#") {
|
|
1271
1313
|
e.preventDefault();
|
|
1272
1314
|
const savedRange = this.saveRange();
|
|
@@ -1289,6 +1331,21 @@ var Popover = class {
|
|
|
1289
1331
|
this.callbacks.onClose();
|
|
1290
1332
|
}
|
|
1291
1333
|
};
|
|
1334
|
+
/**
|
|
1335
|
+
* Fires after every keystroke in the editor (post-insertion). Looks
|
|
1336
|
+
* for an `@<query>` pattern adjacent to the caret. If found, opens
|
|
1337
|
+
* (or refreshes) the mention picker in editor mode. If the trigger
|
|
1338
|
+
* disappears (user typed a space, backspaced over @, etc.), closes
|
|
1339
|
+
* the picker.
|
|
1340
|
+
*/
|
|
1341
|
+
this.handleEditorInput = () => {
|
|
1342
|
+
const trigger = this.detectMentionTrigger();
|
|
1343
|
+
if (trigger) {
|
|
1344
|
+
void this.openOrUpdateEditorMentionPicker(trigger.range, trigger.query);
|
|
1345
|
+
} else if (this.mentionPicker && this.mentionPickerMode === "editor") {
|
|
1346
|
+
this.closeMentionPicker();
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1292
1349
|
this.handleEditorPaste = (e) => {
|
|
1293
1350
|
if (this.callbacks.canUploadAttachments()) {
|
|
1294
1351
|
const items = e.clipboardData?.items ?? null;
|
|
@@ -1549,6 +1606,7 @@ var Popover = class {
|
|
|
1549
1606
|
const editor = this.el.querySelector(".vz-textarea");
|
|
1550
1607
|
editor.focus();
|
|
1551
1608
|
editor.addEventListener("keydown", this.handleEditorKey);
|
|
1609
|
+
editor.addEventListener("input", this.handleEditorInput);
|
|
1552
1610
|
editor.addEventListener("paste", this.handleEditorPaste);
|
|
1553
1611
|
const wrap = this.el.querySelector(".vz-editor-wrap");
|
|
1554
1612
|
if (wrap && this.callbacks.canUploadAttachments()) {
|
|
@@ -1578,6 +1636,37 @@ var Popover = class {
|
|
|
1578
1636
|
<div class="vz-anchor-list">${chips}</div>
|
|
1579
1637
|
`;
|
|
1580
1638
|
}
|
|
1639
|
+
/**
|
|
1640
|
+
* Walk back from the caret looking for the most recent `@` that
|
|
1641
|
+
* starts a mention trigger — must be at start-of-text-node or
|
|
1642
|
+
* preceded by whitespace, and there must be no whitespace between
|
|
1643
|
+
* `@` and the caret. Returns the Range covering `@<query>` plus
|
|
1644
|
+
* the bare query string.
|
|
1645
|
+
*/
|
|
1646
|
+
detectMentionTrigger() {
|
|
1647
|
+
const sel = window.getSelection();
|
|
1648
|
+
if (!sel || sel.rangeCount === 0 || !sel.isCollapsed) return null;
|
|
1649
|
+
const caret = sel.getRangeAt(0);
|
|
1650
|
+
const node = caret.startContainer;
|
|
1651
|
+
if (node.nodeType !== Node.TEXT_NODE) return null;
|
|
1652
|
+
const text = node.textContent ?? "";
|
|
1653
|
+
const offset = caret.startOffset;
|
|
1654
|
+
for (let i = offset - 1; i >= 0; i--) {
|
|
1655
|
+
const ch = text[i];
|
|
1656
|
+
if (ch === "@") {
|
|
1657
|
+
const prev = i > 0 ? text[i - 1] : "";
|
|
1658
|
+
if (prev !== "" && !/\s/.test(prev)) return null;
|
|
1659
|
+
const query = text.slice(i + 1, offset);
|
|
1660
|
+
if (/\s/.test(query)) return null;
|
|
1661
|
+
const range = document.createRange();
|
|
1662
|
+
range.setStart(node, i);
|
|
1663
|
+
range.setEnd(node, offset);
|
|
1664
|
+
return { range, query };
|
|
1665
|
+
}
|
|
1666
|
+
if (/\s/.test(ch)) return null;
|
|
1667
|
+
}
|
|
1668
|
+
return null;
|
|
1669
|
+
}
|
|
1581
1670
|
async uploadAndAppend(file) {
|
|
1582
1671
|
if (!this.callbacks.canUploadAttachments()) return;
|
|
1583
1672
|
const placeholderId = "upload-" + Math.random().toString(36).slice(2, 9);
|
|
@@ -1708,54 +1797,195 @@ var Popover = class {
|
|
|
1708
1797
|
return parts.join("").trim();
|
|
1709
1798
|
}
|
|
1710
1799
|
/**
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
*
|
|
1714
|
-
*
|
|
1715
|
-
*
|
|
1716
|
-
* in another tab are picked up without a popover reopen. Falls back
|
|
1717
|
-
* to silent no-op if `onMentionSearch` isn't wired (non-cloud
|
|
1718
|
-
* adapters) or returns an empty list.
|
|
1800
|
+
* Manual-mode picker: opens from the @ mention button. Renders a
|
|
1801
|
+
* search input above the list; the user types into the input to
|
|
1802
|
+
* filter, arrows + Enter to pick. The selection inserts a mention
|
|
1803
|
+
* chip at the editor's current caret (no `@<query>` replacement —
|
|
1804
|
+
* the user didn't type one).
|
|
1719
1805
|
*/
|
|
1720
1806
|
async openMentionPicker(anchor) {
|
|
1721
1807
|
this.closeMentionPicker();
|
|
1722
1808
|
if (!this.callbacks.onMentionSearch) return;
|
|
1809
|
+
this.mentionPickerMode = "manual";
|
|
1810
|
+
this.mentionPickerEditorRange = null;
|
|
1811
|
+
const picker = this.createMentionPickerShell();
|
|
1812
|
+
this.positionMentionPickerByElement(picker, anchor);
|
|
1813
|
+
const users = await this.fetchMentionables();
|
|
1814
|
+
if (this.mentionPicker !== picker) return;
|
|
1815
|
+
this.mentionPickerUsers = users;
|
|
1816
|
+
this.renderMentionPickerBody("");
|
|
1817
|
+
this.positionMentionPickerByElement(picker, anchor);
|
|
1818
|
+
const input = picker.querySelector(".vz-mention-search");
|
|
1819
|
+
input?.focus();
|
|
1820
|
+
this.wireMentionPickerDismiss();
|
|
1821
|
+
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Editor-mode picker: opens because the user typed `@` in the
|
|
1824
|
+
* editor. No search input — the editor IS the search; the query is
|
|
1825
|
+
* the text after `@`. On commit, replaces the `@<query>` range with
|
|
1826
|
+
* the chip.
|
|
1827
|
+
*/
|
|
1828
|
+
async openOrUpdateEditorMentionPicker(range, query) {
|
|
1829
|
+
this.mentionPickerEditorRange = range;
|
|
1830
|
+
if (!this.mentionPicker || this.mentionPickerMode !== "editor") {
|
|
1831
|
+
this.closeMentionPicker();
|
|
1832
|
+
this.mentionPickerMode = "editor";
|
|
1833
|
+
const picker = this.createMentionPickerShell({ showSearch: false });
|
|
1834
|
+
this.positionMentionPickerByRange(picker, range);
|
|
1835
|
+
const users = await this.fetchMentionables();
|
|
1836
|
+
if (this.mentionPicker !== picker) return;
|
|
1837
|
+
this.mentionPickerUsers = users;
|
|
1838
|
+
this.renderMentionPickerBody(query);
|
|
1839
|
+
this.positionMentionPickerByRange(picker, range);
|
|
1840
|
+
this.wireMentionPickerDismiss();
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
this.renderMentionPickerBody(query);
|
|
1844
|
+
this.positionMentionPickerByRange(this.mentionPicker, range);
|
|
1845
|
+
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Build the picker DOM scaffold and attach it to the popover. Does
|
|
1848
|
+
* NOT fetch users or render the body — caller's responsibility.
|
|
1849
|
+
* Search input is hidden in editor mode where the user already has
|
|
1850
|
+
* a perfectly good text-entry surface (the editor itself).
|
|
1851
|
+
*/
|
|
1852
|
+
createMentionPickerShell({ showSearch = true } = {}) {
|
|
1723
1853
|
const picker = document.createElement("div");
|
|
1724
1854
|
picker.className = "vz-mention-picker";
|
|
1725
1855
|
picker.setAttribute("data-vz-ignore", "");
|
|
1726
|
-
picker.innerHTML =
|
|
1856
|
+
picker.innerHTML = `
|
|
1857
|
+
${showSearch ? `<input class="vz-mention-search" type="text" placeholder="Search teammates\u2026" autocomplete="off" spellcheck="false" />` : ""}
|
|
1858
|
+
<div class="vz-mention-list" data-vz="mention-list">
|
|
1859
|
+
<div class="vz-mention-loading">Loading\u2026</div>
|
|
1860
|
+
</div>
|
|
1861
|
+
`;
|
|
1727
1862
|
this.el.appendChild(picker);
|
|
1728
1863
|
this.mentionPicker = picker;
|
|
1729
|
-
this.
|
|
1730
|
-
|
|
1864
|
+
this.mentionPickerFiltered = [];
|
|
1865
|
+
this.mentionPickerSelected = 0;
|
|
1866
|
+
picker.addEventListener("mousemove", (e) => {
|
|
1867
|
+
const btn = e.target?.closest(".vz-mention-item");
|
|
1868
|
+
if (!btn) return;
|
|
1869
|
+
const idx = Number(btn.getAttribute("data-mention-index") ?? -1);
|
|
1870
|
+
if (idx >= 0 && idx !== this.mentionPickerSelected) {
|
|
1871
|
+
this.mentionPickerSelected = idx;
|
|
1872
|
+
this.refreshMentionPickerHighlight();
|
|
1873
|
+
}
|
|
1874
|
+
});
|
|
1875
|
+
picker.addEventListener("click", (e) => {
|
|
1876
|
+
const btn = e.target?.closest(".vz-mention-item");
|
|
1877
|
+
if (!btn) return;
|
|
1878
|
+
e.preventDefault();
|
|
1879
|
+
e.stopPropagation();
|
|
1880
|
+
const idx = Number(btn.getAttribute("data-mention-index") ?? -1);
|
|
1881
|
+
if (idx >= 0) {
|
|
1882
|
+
this.mentionPickerSelected = idx;
|
|
1883
|
+
this.commitMentionPickerSelection();
|
|
1884
|
+
}
|
|
1885
|
+
});
|
|
1886
|
+
if (showSearch) {
|
|
1887
|
+
const input = picker.querySelector(".vz-mention-search");
|
|
1888
|
+
input?.addEventListener("input", () => this.renderMentionPickerBody(input.value));
|
|
1889
|
+
input?.addEventListener("keydown", (e) => {
|
|
1890
|
+
if (e.key === "ArrowDown") {
|
|
1891
|
+
e.preventDefault();
|
|
1892
|
+
this.moveMentionPickerSelection(1);
|
|
1893
|
+
} else if (e.key === "ArrowUp") {
|
|
1894
|
+
e.preventDefault();
|
|
1895
|
+
this.moveMentionPickerSelection(-1);
|
|
1896
|
+
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
1897
|
+
if (this.mentionPickerFiltered.length > 0) {
|
|
1898
|
+
e.preventDefault();
|
|
1899
|
+
this.commitMentionPickerSelection();
|
|
1900
|
+
}
|
|
1901
|
+
} else if (e.key === "Escape") {
|
|
1902
|
+
e.preventDefault();
|
|
1903
|
+
this.closeMentionPicker();
|
|
1904
|
+
}
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
return picker;
|
|
1908
|
+
}
|
|
1909
|
+
/** Fetch the mentionable list. Swallows errors → []. */
|
|
1910
|
+
async fetchMentionables() {
|
|
1911
|
+
if (!this.callbacks.onMentionSearch) return [];
|
|
1731
1912
|
try {
|
|
1732
|
-
|
|
1913
|
+
return await this.callbacks.onMentionSearch();
|
|
1733
1914
|
} catch {
|
|
1915
|
+
return [];
|
|
1734
1916
|
}
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1917
|
+
}
|
|
1918
|
+
/**
|
|
1919
|
+
* Re-filter the cached users by `query`, render the list, reset
|
|
1920
|
+
* selected to 0. Called on every search input change and on every
|
|
1921
|
+
* editor input event while in editor mode.
|
|
1922
|
+
*/
|
|
1923
|
+
renderMentionPickerBody(query) {
|
|
1924
|
+
const picker = this.mentionPicker;
|
|
1925
|
+
if (!picker) return;
|
|
1926
|
+
const list = picker.querySelector('[data-vz="mention-list"]');
|
|
1927
|
+
if (!list) return;
|
|
1928
|
+
const q = query.toLowerCase().trim();
|
|
1929
|
+
this.mentionPickerFiltered = q ? this.mentionPickerUsers.filter((u) => u.name.toLowerCase().includes(q)) : this.mentionPickerUsers.slice();
|
|
1930
|
+
this.mentionPickerSelected = 0;
|
|
1931
|
+
if (this.mentionPickerFiltered.length === 0) {
|
|
1932
|
+
list.innerHTML = `<div class="vz-mention-empty">${this.mentionPickerUsers.length === 0 ? "No teammates to mention yet." : "No teammates match."}</div>`;
|
|
1740
1933
|
return;
|
|
1741
1934
|
}
|
|
1742
|
-
|
|
1935
|
+
list.innerHTML = this.mentionPickerFiltered.map((u, i) => {
|
|
1743
1936
|
const avatar = u.avatarUrl ? `<img class="vz-mention-avatar" src="${escapeHtml(u.avatarUrl)}" alt="" />` : `<span class="vz-mention-avatar vz-mention-avatar-initials">${escapeHtml(initials(u.name) || "?")}</span>`;
|
|
1744
|
-
return `<button class="vz-mention-item"
|
|
1937
|
+
return `<button class="vz-mention-item${i === 0 ? " is-selected" : ""}" type="button" data-mention-index="${i}">${avatar}<span class="vz-mention-item-name">${escapeHtml(u.name)}</span></button>`;
|
|
1745
1938
|
}).join("");
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
this.
|
|
1939
|
+
}
|
|
1940
|
+
moveMentionPickerSelection(delta) {
|
|
1941
|
+
if (this.mentionPickerFiltered.length === 0) return;
|
|
1942
|
+
const n = this.mentionPickerFiltered.length;
|
|
1943
|
+
this.mentionPickerSelected = (this.mentionPickerSelected + delta + n) % n;
|
|
1944
|
+
this.refreshMentionPickerHighlight();
|
|
1945
|
+
}
|
|
1946
|
+
refreshMentionPickerHighlight() {
|
|
1947
|
+
const picker = this.mentionPicker;
|
|
1948
|
+
if (!picker) return;
|
|
1949
|
+
const items = picker.querySelectorAll(".vz-mention-item");
|
|
1950
|
+
items.forEach((el, i) => el.classList.toggle("is-selected", i === this.mentionPickerSelected));
|
|
1951
|
+
items[this.mentionPickerSelected]?.scrollIntoView({ block: "nearest" });
|
|
1952
|
+
}
|
|
1953
|
+
commitMentionPickerSelection() {
|
|
1954
|
+
const user = this.mentionPickerFiltered[this.mentionPickerSelected];
|
|
1955
|
+
if (!user) return;
|
|
1956
|
+
if (this.mentionPickerMode === "editor" && this.mentionPickerEditorRange) {
|
|
1957
|
+
this.replaceRangeWithMentionChip(this.mentionPickerEditorRange, user);
|
|
1958
|
+
} else {
|
|
1959
|
+
this.insertMentionChip(user);
|
|
1960
|
+
}
|
|
1961
|
+
this.closeMentionPicker();
|
|
1962
|
+
}
|
|
1963
|
+
/**
|
|
1964
|
+
* Swap a Range covering `@<query>` for a mention chip + trailing
|
|
1965
|
+
* space, then place the caret after the space so the user can keep
|
|
1966
|
+
* typing. Used only in editor-trigger mode.
|
|
1967
|
+
*/
|
|
1968
|
+
replaceRangeWithMentionChip(range, user) {
|
|
1969
|
+
const editor = this.el.querySelector(".vz-textarea");
|
|
1970
|
+
if (!editor) return;
|
|
1971
|
+
const chip = document.createElement("span");
|
|
1972
|
+
chip.className = "vz-chip vz-chip-mention";
|
|
1973
|
+
chip.contentEditable = "false";
|
|
1974
|
+
chip.setAttribute("data-mention-id", user.id);
|
|
1975
|
+
chip.textContent = "@" + user.name;
|
|
1976
|
+
range.deleteContents();
|
|
1977
|
+
range.insertNode(chip);
|
|
1978
|
+
const space = document.createTextNode(" ");
|
|
1979
|
+
chip.after(space);
|
|
1980
|
+
const sel = window.getSelection();
|
|
1981
|
+
if (sel) {
|
|
1982
|
+
const after = document.createRange();
|
|
1983
|
+
after.setStartAfter(space);
|
|
1984
|
+
after.collapse(true);
|
|
1985
|
+
sel.removeAllRanges();
|
|
1986
|
+
sel.addRange(after);
|
|
1987
|
+
}
|
|
1988
|
+
editor.focus();
|
|
1759
1989
|
}
|
|
1760
1990
|
/** Wires Esc + outside-click handlers to close the open picker. */
|
|
1761
1991
|
wireMentionPickerDismiss() {
|
|
@@ -1769,6 +1999,10 @@ var Popover = class {
|
|
|
1769
1999
|
const onOutside = (e) => {
|
|
1770
2000
|
if (!this.mentionPicker) return;
|
|
1771
2001
|
if (this.mentionPicker.contains(e.target)) return;
|
|
2002
|
+
if (this.mentionPickerMode === "editor") {
|
|
2003
|
+
const editor = this.el.querySelector(".vz-textarea");
|
|
2004
|
+
if (editor && editor.contains(e.target)) return;
|
|
2005
|
+
}
|
|
1772
2006
|
this.closeMentionPicker();
|
|
1773
2007
|
};
|
|
1774
2008
|
document.addEventListener("keydown", onKey, true);
|
|
@@ -1787,18 +2021,23 @@ var Popover = class {
|
|
|
1787
2021
|
this.mentionPicker.remove();
|
|
1788
2022
|
this.mentionPicker = null;
|
|
1789
2023
|
}
|
|
2024
|
+
this.mentionPickerFiltered = [];
|
|
2025
|
+
this.mentionPickerSelected = 0;
|
|
2026
|
+
this.mentionPickerEditorRange = null;
|
|
1790
2027
|
}
|
|
1791
|
-
/**
|
|
1792
|
-
|
|
1793
|
-
* popover's right edge so we don't overflow the popover frame.
|
|
1794
|
-
*/
|
|
1795
|
-
positionMentionPicker(picker, anchor) {
|
|
2028
|
+
/** Position the picker below the given anchor (the @ mention button). */
|
|
2029
|
+
positionMentionPickerByElement(picker, anchor) {
|
|
1796
2030
|
const popRect = this.el.getBoundingClientRect();
|
|
1797
2031
|
const btnRect = anchor.getBoundingClientRect();
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
2032
|
+
picker.style.left = `${btnRect.left - popRect.left}px`;
|
|
2033
|
+
picker.style.top = `${btnRect.bottom - popRect.top + 4}px`;
|
|
2034
|
+
}
|
|
2035
|
+
/** Position the picker below the `@<query>` text range in the editor. */
|
|
2036
|
+
positionMentionPickerByRange(picker, range) {
|
|
2037
|
+
const popRect = this.el.getBoundingClientRect();
|
|
2038
|
+
const rect = range.getBoundingClientRect();
|
|
2039
|
+
picker.style.left = `${rect.left - popRect.left}px`;
|
|
2040
|
+
picker.style.top = `${rect.bottom - popRect.top + 4}px`;
|
|
1802
2041
|
}
|
|
1803
2042
|
/**
|
|
1804
2043
|
* Insert a mention chip for the given user into the editor at the
|
|
@@ -2677,6 +2916,26 @@ var STYLES = `
|
|
|
2677
2916
|
flex-direction: column;
|
|
2678
2917
|
gap: 1px;
|
|
2679
2918
|
}
|
|
2919
|
+
.vz-mention-search {
|
|
2920
|
+
width: 100%;
|
|
2921
|
+
padding: 7px 9px;
|
|
2922
|
+
margin-bottom: 4px;
|
|
2923
|
+
background: rgba(255,255,255,0.04);
|
|
2924
|
+
border: 1px solid var(--vz-border, rgba(255,255,255,0.08));
|
|
2925
|
+
border-radius: 6px;
|
|
2926
|
+
color: #fafafa;
|
|
2927
|
+
font-size: 13px;
|
|
2928
|
+
outline: none;
|
|
2929
|
+
box-sizing: border-box;
|
|
2930
|
+
}
|
|
2931
|
+
.vz-mention-search:focus { border-color: var(--vz-accent, #ff8b6e); }
|
|
2932
|
+
.vz-mention-search::placeholder { color: var(--vz-text-muted); }
|
|
2933
|
+
.vz-mention-list {
|
|
2934
|
+
display: flex;
|
|
2935
|
+
flex-direction: column;
|
|
2936
|
+
gap: 1px;
|
|
2937
|
+
min-height: 0;
|
|
2938
|
+
}
|
|
2680
2939
|
.vz-mention-loading,
|
|
2681
2940
|
.vz-mention-empty {
|
|
2682
2941
|
padding: 10px 12px;
|
|
@@ -2698,9 +2957,9 @@ var STYLES = `
|
|
|
2698
2957
|
cursor: pointer;
|
|
2699
2958
|
transition: background 80ms;
|
|
2700
2959
|
}
|
|
2701
|
-
.vz-mention-item
|
|
2960
|
+
.vz-mention-item.is-selected,
|
|
2702
2961
|
.vz-mention-item:focus-visible {
|
|
2703
|
-
background: var(--vz-bg-hover, rgba(255,255,255,0.
|
|
2962
|
+
background: var(--vz-bg-hover, rgba(255,255,255,0.08));
|
|
2704
2963
|
outline: none;
|
|
2705
2964
|
}
|
|
2706
2965
|
.vz-mention-avatar {
|