@duskmoon-dev/el-markdown-input 1.1.2 → 1.1.3
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/cjs/index.js +145 -9
- package/dist/cjs/index.js.map +4 -4
- package/dist/cjs/register.js +145 -9
- package/dist/cjs/register.js.map +4 -4
- package/dist/esm/index.js +145 -9
- package/dist/esm/index.js.map +4 -4
- package/dist/esm/register.js +145 -9
- package/dist/esm/register.js.map +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/css.d.ts.map +1 -1
- package/dist/types/element.d.ts +4 -0
- package/dist/types/element.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cjs/register.js
CHANGED
|
@@ -512,6 +512,31 @@ var elementStyles = import_el_base.css`
|
|
|
512
512
|
gap: 0.5rem;
|
|
513
513
|
}
|
|
514
514
|
|
|
515
|
+
.status-bar-start,
|
|
516
|
+
.status-bar-end {
|
|
517
|
+
display: flex;
|
|
518
|
+
align-items: center;
|
|
519
|
+
gap: 0.5rem;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/* Allow slotted light-DOM children to inherit font and alignment */
|
|
523
|
+
.status-bar ::slotted(*),
|
|
524
|
+
.status-bar-start ::slotted(*),
|
|
525
|
+
.status-bar-end ::slotted(*) {
|
|
526
|
+
font-size: inherit;
|
|
527
|
+
font-family: inherit;
|
|
528
|
+
vertical-align: middle;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/* When slot="bottom" is used, the slotted element fills the bar */
|
|
532
|
+
.status-bar > slot[name="bottom"]::slotted(*) {
|
|
533
|
+
display: flex;
|
|
534
|
+
align-items: center;
|
|
535
|
+
justify-content: space-between;
|
|
536
|
+
flex: 1;
|
|
537
|
+
gap: 0.5rem;
|
|
538
|
+
}
|
|
539
|
+
|
|
515
540
|
.attach-btn {
|
|
516
541
|
display: inline-flex;
|
|
517
542
|
align-items: center;
|
|
@@ -546,7 +571,6 @@ var elementStyles = import_el_base.css`
|
|
|
546
571
|
}
|
|
547
572
|
|
|
548
573
|
.status-bar-count {
|
|
549
|
-
margin-left: auto;
|
|
550
574
|
white-space: nowrap;
|
|
551
575
|
}
|
|
552
576
|
|
|
@@ -675,6 +699,52 @@ var elementStyles = import_el_base.css`
|
|
|
675
699
|
white-space: nowrap;
|
|
676
700
|
}
|
|
677
701
|
|
|
702
|
+
/* ── Attached files (local form mode) ────────────────────────────── */
|
|
703
|
+
|
|
704
|
+
.upload-attached-row {
|
|
705
|
+
display: flex;
|
|
706
|
+
align-items: center;
|
|
707
|
+
gap: 0.5rem;
|
|
708
|
+
padding: 0.375rem 0.75rem;
|
|
709
|
+
border-top: 1px solid var(--md-border);
|
|
710
|
+
font-size: 0.75rem;
|
|
711
|
+
color: var(--md-text-muted);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.upload-attached-size {
|
|
715
|
+
white-space: nowrap;
|
|
716
|
+
color: var(--md-text-muted);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.upload-remove-btn {
|
|
720
|
+
display: inline-flex;
|
|
721
|
+
align-items: center;
|
|
722
|
+
justify-content: center;
|
|
723
|
+
width: 1.25rem;
|
|
724
|
+
height: 1.25rem;
|
|
725
|
+
margin-left: auto;
|
|
726
|
+
border: none;
|
|
727
|
+
background: transparent;
|
|
728
|
+
color: var(--md-text-muted);
|
|
729
|
+
font-size: 0.85rem;
|
|
730
|
+
line-height: 1;
|
|
731
|
+
cursor: pointer;
|
|
732
|
+
border-radius: 50%;
|
|
733
|
+
transition:
|
|
734
|
+
color 150ms ease,
|
|
735
|
+
background 150ms ease;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.upload-remove-btn:hover {
|
|
739
|
+
color: var(--md-color-error);
|
|
740
|
+
background: var(--md-bg-hover);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
.upload-remove-btn:focus-visible {
|
|
744
|
+
outline: 2px solid var(--md-accent);
|
|
745
|
+
outline-offset: 1px;
|
|
746
|
+
}
|
|
747
|
+
|
|
678
748
|
/* ── Resizable editor ──────────────────────────────────────────────── */
|
|
679
749
|
/* resize attribute mirrors the CSS resize property: vertical | horizontal | both */
|
|
680
750
|
:host([resize='vertical']) .editor {
|
|
@@ -1019,6 +1089,13 @@ var coreMarkdownStyles = import_markdown_body.css.replace(/@layer\s+components\s
|
|
|
1019
1089
|
var markdownBodySheet = import_el_base3.css`
|
|
1020
1090
|
${coreMarkdownStyles}
|
|
1021
1091
|
`;
|
|
1092
|
+
function formatFileSize(bytes) {
|
|
1093
|
+
if (bytes < 1024)
|
|
1094
|
+
return `${bytes} B`;
|
|
1095
|
+
if (bytes < 1024 * 1024)
|
|
1096
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1097
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1098
|
+
}
|
|
1022
1099
|
|
|
1023
1100
|
class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
1024
1101
|
static formAssociated = true;
|
|
@@ -1065,6 +1142,7 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1065
1142
|
#lastRenderedSource = null;
|
|
1066
1143
|
#katexCssInjected = false;
|
|
1067
1144
|
#uploadIdCounter = 0;
|
|
1145
|
+
#attachedFiles = [];
|
|
1068
1146
|
constructor() {
|
|
1069
1147
|
super();
|
|
1070
1148
|
this.#internals = this.attachInternals();
|
|
@@ -1197,10 +1275,20 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1197
1275
|
></div>
|
|
1198
1276
|
|
|
1199
1277
|
<div class="status-bar">
|
|
1200
|
-
<
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1278
|
+
<slot name="bottom">
|
|
1279
|
+
<div class="status-bar-start">
|
|
1280
|
+
<slot name="bottom-start">
|
|
1281
|
+
<button class="attach-btn" type="button" aria-label="Attach files" ${disabled || readonly ? "disabled" : ""}>
|
|
1282
|
+
📎 Attach files
|
|
1283
|
+
</button>
|
|
1284
|
+
</slot>
|
|
1285
|
+
</div>
|
|
1286
|
+
<div class="status-bar-end">
|
|
1287
|
+
<slot name="bottom-end">
|
|
1288
|
+
<span class="status-bar-count" aria-live="polite"></span>
|
|
1289
|
+
</slot>
|
|
1290
|
+
</div>
|
|
1291
|
+
</slot>
|
|
1204
1292
|
<input
|
|
1205
1293
|
type="file"
|
|
1206
1294
|
class="file-input"
|
|
@@ -1487,15 +1575,28 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1487
1575
|
}, ms);
|
|
1488
1576
|
}
|
|
1489
1577
|
#syncFormValue() {
|
|
1490
|
-
this.#
|
|
1578
|
+
const text = this.#textarea?.value ?? "";
|
|
1579
|
+
if (this.#attachedFiles.length === 0) {
|
|
1580
|
+
this.#internals?.setFormValue(text);
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
const name = this.name || "markdown";
|
|
1584
|
+
const fd = new FormData;
|
|
1585
|
+
fd.append(name, text);
|
|
1586
|
+
for (const f of this.#attachedFiles) {
|
|
1587
|
+
fd.append(`${name}_files`, f, f.name);
|
|
1588
|
+
}
|
|
1589
|
+
this.#internals?.setFormValue(fd);
|
|
1491
1590
|
}
|
|
1492
1591
|
#startUpload(file) {
|
|
1493
1592
|
this.emit("upload-start", { file });
|
|
1494
1593
|
const id = `upload-${++this.#uploadIdCounter}`;
|
|
1495
1594
|
const uploadUrl = this.uploadUrl;
|
|
1496
1595
|
if (!uploadUrl) {
|
|
1497
|
-
this.
|
|
1498
|
-
this.#
|
|
1596
|
+
this.#attachedFiles.push(file);
|
|
1597
|
+
this.#addAttachedRow(file, this.#attachedFiles.length - 1, id);
|
|
1598
|
+
this.#syncFormValue();
|
|
1599
|
+
this.emit("upload-done", { file, url: "", markdown: "" });
|
|
1499
1600
|
return;
|
|
1500
1601
|
}
|
|
1501
1602
|
this.#addProgressRow(id, file.name);
|
|
@@ -1550,6 +1651,22 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1550
1651
|
this.#uploadList.appendChild(row);
|
|
1551
1652
|
setTimeout(() => row.remove(), 4000);
|
|
1552
1653
|
}
|
|
1654
|
+
#addAttachedRow(file, index, id) {
|
|
1655
|
+
if (!this.#uploadList)
|
|
1656
|
+
return;
|
|
1657
|
+
const row = document.createElement("div");
|
|
1658
|
+
row.className = "upload-attached-row";
|
|
1659
|
+
row.id = id;
|
|
1660
|
+
row.innerHTML = `
|
|
1661
|
+
<span class="upload-filename">${escapeHtmlStr(file.name)}</span>
|
|
1662
|
+
<span class="upload-attached-size">${formatFileSize(file.size)}</span>
|
|
1663
|
+
<button type="button" class="upload-remove-btn" data-attach-index="${index}" aria-label="Remove ${escapeHtmlStr(file.name)}">×</button>
|
|
1664
|
+
`;
|
|
1665
|
+
row.querySelector(".upload-remove-btn").addEventListener("click", () => {
|
|
1666
|
+
this.removeFile(index);
|
|
1667
|
+
});
|
|
1668
|
+
this.#uploadList.appendChild(row);
|
|
1669
|
+
}
|
|
1553
1670
|
#handleAutocompleteInput() {
|
|
1554
1671
|
const ta = this.#textarea;
|
|
1555
1672
|
if (!ta)
|
|
@@ -1755,6 +1872,25 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1755
1872
|
this.#acSelectedIndex = list.length > 0 ? 0 : -1;
|
|
1756
1873
|
this.#updateDropdown();
|
|
1757
1874
|
}
|
|
1875
|
+
getFiles() {
|
|
1876
|
+
return [...this.#attachedFiles];
|
|
1877
|
+
}
|
|
1878
|
+
removeFile(index) {
|
|
1879
|
+
if (index < 0 || index >= this.#attachedFiles.length)
|
|
1880
|
+
return;
|
|
1881
|
+
this.#attachedFiles.splice(index, 1);
|
|
1882
|
+
this.#rebuildAttachedRows();
|
|
1883
|
+
this.#syncFormValue();
|
|
1884
|
+
}
|
|
1885
|
+
#rebuildAttachedRows() {
|
|
1886
|
+
if (!this.#uploadList)
|
|
1887
|
+
return;
|
|
1888
|
+
this.#uploadList.querySelectorAll(".upload-attached-row").forEach((r) => r.remove());
|
|
1889
|
+
this.#attachedFiles.forEach((file, i) => {
|
|
1890
|
+
const id = `upload-${++this.#uploadIdCounter}`;
|
|
1891
|
+
this.#addAttachedRow(file, i, id);
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1758
1894
|
}
|
|
1759
1895
|
function escapeHtmlStr(s) {
|
|
1760
1896
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -1765,5 +1901,5 @@ if (!customElements.get("el-dm-markdown-input")) {
|
|
|
1765
1901
|
customElements.define("el-dm-markdown-input", ElDmMarkdownInput);
|
|
1766
1902
|
}
|
|
1767
1903
|
|
|
1768
|
-
//# debugId=
|
|
1904
|
+
//# debugId=5E28FBCFFD0322DF64756E2164756E21
|
|
1769
1905
|
//# sourceMappingURL=register.js.map
|