@duskmoon-dev/el-markdown-input 1.1.2 → 1.2.0

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.
@@ -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
- <button class="attach-btn" type="button" aria-label="Attach files" ${disabled || readonly ? "disabled" : ""}>
1201
- &#128206; Attach files
1202
- </button>
1203
- <span class="status-bar-count" aria-live="polite"></span>
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
+ &#128206; 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.#internals?.setFormValue(this.#textarea?.value ?? "");
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.emit("upload-error", { file, error: "no upload-url set" });
1498
- this.#showUploadError(file, "no upload-url set");
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)}">&#215;</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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
@@ -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=3B9F93434B1F637F64756E2164756E21
1904
+ //# debugId=5E28FBCFFD0322DF64756E2164756E21
1769
1905
  //# sourceMappingURL=register.js.map