@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/index.js
CHANGED
|
@@ -521,6 +521,31 @@ var elementStyles = import_el_base.css`
|
|
|
521
521
|
gap: 0.5rem;
|
|
522
522
|
}
|
|
523
523
|
|
|
524
|
+
.status-bar-start,
|
|
525
|
+
.status-bar-end {
|
|
526
|
+
display: flex;
|
|
527
|
+
align-items: center;
|
|
528
|
+
gap: 0.5rem;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/* Allow slotted light-DOM children to inherit font and alignment */
|
|
532
|
+
.status-bar ::slotted(*),
|
|
533
|
+
.status-bar-start ::slotted(*),
|
|
534
|
+
.status-bar-end ::slotted(*) {
|
|
535
|
+
font-size: inherit;
|
|
536
|
+
font-family: inherit;
|
|
537
|
+
vertical-align: middle;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/* When slot="bottom" is used, the slotted element fills the bar */
|
|
541
|
+
.status-bar > slot[name="bottom"]::slotted(*) {
|
|
542
|
+
display: flex;
|
|
543
|
+
align-items: center;
|
|
544
|
+
justify-content: space-between;
|
|
545
|
+
flex: 1;
|
|
546
|
+
gap: 0.5rem;
|
|
547
|
+
}
|
|
548
|
+
|
|
524
549
|
.attach-btn {
|
|
525
550
|
display: inline-flex;
|
|
526
551
|
align-items: center;
|
|
@@ -555,7 +580,6 @@ var elementStyles = import_el_base.css`
|
|
|
555
580
|
}
|
|
556
581
|
|
|
557
582
|
.status-bar-count {
|
|
558
|
-
margin-left: auto;
|
|
559
583
|
white-space: nowrap;
|
|
560
584
|
}
|
|
561
585
|
|
|
@@ -684,6 +708,52 @@ var elementStyles = import_el_base.css`
|
|
|
684
708
|
white-space: nowrap;
|
|
685
709
|
}
|
|
686
710
|
|
|
711
|
+
/* ── Attached files (local form mode) ────────────────────────────── */
|
|
712
|
+
|
|
713
|
+
.upload-attached-row {
|
|
714
|
+
display: flex;
|
|
715
|
+
align-items: center;
|
|
716
|
+
gap: 0.5rem;
|
|
717
|
+
padding: 0.375rem 0.75rem;
|
|
718
|
+
border-top: 1px solid var(--md-border);
|
|
719
|
+
font-size: 0.75rem;
|
|
720
|
+
color: var(--md-text-muted);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.upload-attached-size {
|
|
724
|
+
white-space: nowrap;
|
|
725
|
+
color: var(--md-text-muted);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.upload-remove-btn {
|
|
729
|
+
display: inline-flex;
|
|
730
|
+
align-items: center;
|
|
731
|
+
justify-content: center;
|
|
732
|
+
width: 1.25rem;
|
|
733
|
+
height: 1.25rem;
|
|
734
|
+
margin-left: auto;
|
|
735
|
+
border: none;
|
|
736
|
+
background: transparent;
|
|
737
|
+
color: var(--md-text-muted);
|
|
738
|
+
font-size: 0.85rem;
|
|
739
|
+
line-height: 1;
|
|
740
|
+
cursor: pointer;
|
|
741
|
+
border-radius: 50%;
|
|
742
|
+
transition:
|
|
743
|
+
color 150ms ease,
|
|
744
|
+
background 150ms ease;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.upload-remove-btn:hover {
|
|
748
|
+
color: var(--md-color-error);
|
|
749
|
+
background: var(--md-bg-hover);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
.upload-remove-btn:focus-visible {
|
|
753
|
+
outline: 2px solid var(--md-accent);
|
|
754
|
+
outline-offset: 1px;
|
|
755
|
+
}
|
|
756
|
+
|
|
687
757
|
/* ── Resizable editor ──────────────────────────────────────────────── */
|
|
688
758
|
/* resize attribute mirrors the CSS resize property: vertical | horizontal | both */
|
|
689
759
|
:host([resize='vertical']) .editor {
|
|
@@ -1028,6 +1098,13 @@ var coreMarkdownStyles = import_markdown_body.css.replace(/@layer\s+components\s
|
|
|
1028
1098
|
var markdownBodySheet = import_el_base3.css`
|
|
1029
1099
|
${coreMarkdownStyles}
|
|
1030
1100
|
`;
|
|
1101
|
+
function formatFileSize(bytes) {
|
|
1102
|
+
if (bytes < 1024)
|
|
1103
|
+
return `${bytes} B`;
|
|
1104
|
+
if (bytes < 1024 * 1024)
|
|
1105
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1106
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1107
|
+
}
|
|
1031
1108
|
|
|
1032
1109
|
class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
1033
1110
|
static formAssociated = true;
|
|
@@ -1074,6 +1151,7 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1074
1151
|
#lastRenderedSource = null;
|
|
1075
1152
|
#katexCssInjected = false;
|
|
1076
1153
|
#uploadIdCounter = 0;
|
|
1154
|
+
#attachedFiles = [];
|
|
1077
1155
|
constructor() {
|
|
1078
1156
|
super();
|
|
1079
1157
|
this.#internals = this.attachInternals();
|
|
@@ -1206,10 +1284,20 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1206
1284
|
></div>
|
|
1207
1285
|
|
|
1208
1286
|
<div class="status-bar">
|
|
1209
|
-
<
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1287
|
+
<slot name="bottom">
|
|
1288
|
+
<div class="status-bar-start">
|
|
1289
|
+
<slot name="bottom-start">
|
|
1290
|
+
<button class="attach-btn" type="button" aria-label="Attach files" ${disabled || readonly ? "disabled" : ""}>
|
|
1291
|
+
📎 Attach files
|
|
1292
|
+
</button>
|
|
1293
|
+
</slot>
|
|
1294
|
+
</div>
|
|
1295
|
+
<div class="status-bar-end">
|
|
1296
|
+
<slot name="bottom-end">
|
|
1297
|
+
<span class="status-bar-count" aria-live="polite"></span>
|
|
1298
|
+
</slot>
|
|
1299
|
+
</div>
|
|
1300
|
+
</slot>
|
|
1213
1301
|
<input
|
|
1214
1302
|
type="file"
|
|
1215
1303
|
class="file-input"
|
|
@@ -1496,15 +1584,28 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1496
1584
|
}, ms);
|
|
1497
1585
|
}
|
|
1498
1586
|
#syncFormValue() {
|
|
1499
|
-
this.#
|
|
1587
|
+
const text = this.#textarea?.value ?? "";
|
|
1588
|
+
if (this.#attachedFiles.length === 0) {
|
|
1589
|
+
this.#internals?.setFormValue(text);
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1592
|
+
const name = this.name || "markdown";
|
|
1593
|
+
const fd = new FormData;
|
|
1594
|
+
fd.append(name, text);
|
|
1595
|
+
for (const f of this.#attachedFiles) {
|
|
1596
|
+
fd.append(`${name}_files`, f, f.name);
|
|
1597
|
+
}
|
|
1598
|
+
this.#internals?.setFormValue(fd);
|
|
1500
1599
|
}
|
|
1501
1600
|
#startUpload(file) {
|
|
1502
1601
|
this.emit("upload-start", { file });
|
|
1503
1602
|
const id = `upload-${++this.#uploadIdCounter}`;
|
|
1504
1603
|
const uploadUrl = this.uploadUrl;
|
|
1505
1604
|
if (!uploadUrl) {
|
|
1506
|
-
this.
|
|
1507
|
-
this.#
|
|
1605
|
+
this.#attachedFiles.push(file);
|
|
1606
|
+
this.#addAttachedRow(file, this.#attachedFiles.length - 1, id);
|
|
1607
|
+
this.#syncFormValue();
|
|
1608
|
+
this.emit("upload-done", { file, url: "", markdown: "" });
|
|
1508
1609
|
return;
|
|
1509
1610
|
}
|
|
1510
1611
|
this.#addProgressRow(id, file.name);
|
|
@@ -1559,6 +1660,22 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1559
1660
|
this.#uploadList.appendChild(row);
|
|
1560
1661
|
setTimeout(() => row.remove(), 4000);
|
|
1561
1662
|
}
|
|
1663
|
+
#addAttachedRow(file, index, id) {
|
|
1664
|
+
if (!this.#uploadList)
|
|
1665
|
+
return;
|
|
1666
|
+
const row = document.createElement("div");
|
|
1667
|
+
row.className = "upload-attached-row";
|
|
1668
|
+
row.id = id;
|
|
1669
|
+
row.innerHTML = `
|
|
1670
|
+
<span class="upload-filename">${escapeHtmlStr(file.name)}</span>
|
|
1671
|
+
<span class="upload-attached-size">${formatFileSize(file.size)}</span>
|
|
1672
|
+
<button type="button" class="upload-remove-btn" data-attach-index="${index}" aria-label="Remove ${escapeHtmlStr(file.name)}">×</button>
|
|
1673
|
+
`;
|
|
1674
|
+
row.querySelector(".upload-remove-btn").addEventListener("click", () => {
|
|
1675
|
+
this.removeFile(index);
|
|
1676
|
+
});
|
|
1677
|
+
this.#uploadList.appendChild(row);
|
|
1678
|
+
}
|
|
1562
1679
|
#handleAutocompleteInput() {
|
|
1563
1680
|
const ta = this.#textarea;
|
|
1564
1681
|
if (!ta)
|
|
@@ -1764,6 +1881,25 @@ class ElDmMarkdownInput extends import_el_base2.BaseElement {
|
|
|
1764
1881
|
this.#acSelectedIndex = list.length > 0 ? 0 : -1;
|
|
1765
1882
|
this.#updateDropdown();
|
|
1766
1883
|
}
|
|
1884
|
+
getFiles() {
|
|
1885
|
+
return [...this.#attachedFiles];
|
|
1886
|
+
}
|
|
1887
|
+
removeFile(index) {
|
|
1888
|
+
if (index < 0 || index >= this.#attachedFiles.length)
|
|
1889
|
+
return;
|
|
1890
|
+
this.#attachedFiles.splice(index, 1);
|
|
1891
|
+
this.#rebuildAttachedRows();
|
|
1892
|
+
this.#syncFormValue();
|
|
1893
|
+
}
|
|
1894
|
+
#rebuildAttachedRows() {
|
|
1895
|
+
if (!this.#uploadList)
|
|
1896
|
+
return;
|
|
1897
|
+
this.#uploadList.querySelectorAll(".upload-attached-row").forEach((r) => r.remove());
|
|
1898
|
+
this.#attachedFiles.forEach((file, i) => {
|
|
1899
|
+
const id = `upload-${++this.#uploadIdCounter}`;
|
|
1900
|
+
this.#addAttachedRow(file, i, id);
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1767
1903
|
}
|
|
1768
1904
|
function escapeHtmlStr(s) {
|
|
1769
1905
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -1794,5 +1930,5 @@ var MarkdownInputHook = {
|
|
|
1794
1930
|
}
|
|
1795
1931
|
};
|
|
1796
1932
|
|
|
1797
|
-
//# debugId=
|
|
1933
|
+
//# debugId=FC4F4846FEEC843664756E2164756E21
|
|
1798
1934
|
//# sourceMappingURL=index.js.map
|