@valu/block-components 0.3.1 → 0.5.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.
@@ -558,6 +558,54 @@ var DocMetaInline = styled__default.default.div`
558
558
  white-space: nowrap;
559
559
  }
560
560
  `;
561
+ var ReorderButtons = styled__default.default.span`
562
+ display: none;
563
+
564
+ @container valu-dp-row (min-width: 340px) {
565
+ display: inline-flex;
566
+ }
567
+ `;
568
+ var LabelEditBody = styled__default.default.div`
569
+ flex: 1;
570
+ min-width: 0;
571
+ display: flex;
572
+ flex-direction: column;
573
+ gap: 2px;
574
+ padding: 4px 0;
575
+
576
+ .components-base-control,
577
+ .components-text-control__input {
578
+ width: 100%;
579
+ min-width: 0;
580
+ }
581
+
582
+ /* __nextHasNoMarginBottom is not honored by every bundled
583
+ wp-components version — enforce the no-margin layout here. */
584
+ .components-base-control.components-base-control {
585
+ margin-bottom: 0;
586
+ }
587
+
588
+ /* Doubled class beats wp-components' own input rules regardless of
589
+ stylesheet order (the emotion cache may be prepended). */
590
+ .components-text-control__input.components-text-control__input {
591
+ font-size: ${tokens.fontSizeBody};
592
+ height: 28px;
593
+ min-height: 28px;
594
+ padding: 2px 8px;
595
+ }
596
+
597
+ @container valu-dp-row (min-width: ${WIDE_ROW}) {
598
+ flex-direction: row;
599
+ align-items: center;
600
+ gap: ${tokens.spaceMd};
601
+
602
+ .components-base-control {
603
+ flex: 0 1 340px;
604
+ min-width: 180px;
605
+ width: auto;
606
+ }
607
+ }
608
+ `;
561
609
  var Root2 = styled__default.default.div`
562
610
  color: ${tokens.fg};
563
611
  font-size: ${tokens.fontSizeBody};
@@ -718,6 +766,7 @@ var mapMediaToDocumentItem = (raw) => {
718
766
  raw
719
767
  };
720
768
  };
769
+ var displayTitle = (item) => item.label?.trim() || item.title;
721
770
  var dedupeAgainst = (items, value, enabled) => {
722
771
  if (!enabled || value.length === 0) return items;
723
772
  const ids = new Set(value.map((v) => v.id));
@@ -1722,6 +1771,8 @@ var SelectedItem = ({
1722
1771
  onRemove,
1723
1772
  onMoveUp,
1724
1773
  onMoveDown,
1774
+ enableLabelEdit = false,
1775
+ onLabelChange,
1725
1776
  render
1726
1777
  }) => {
1727
1778
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable.useSortable({
@@ -1735,22 +1786,46 @@ var SelectedItem = ({
1735
1786
  };
1736
1787
  const isMissing = item.missing === "deleted";
1737
1788
  const missingLabel = labels.missing ?? i18n.__("This document is no longer available.", "valu-block-components");
1789
+ const displayName = displayTitle(item);
1738
1790
  const removeLabel = labels.remove ? labels.remove : i18n.sprintf(
1739
1791
  /* translators: %s: document title */
1740
1792
  i18n.__("Remove %s", "valu-block-components"),
1741
- item.title
1793
+ displayName
1742
1794
  );
1743
1795
  const moveUpLabel = labels.moveUp ? labels.moveUp : i18n.sprintf(
1744
1796
  /* translators: %s: document title */
1745
1797
  i18n.__("Move %s up", "valu-block-components"),
1746
- item.title
1798
+ displayName
1747
1799
  );
1748
1800
  const moveDownLabel = labels.moveDown ? labels.moveDown : i18n.sprintf(
1749
1801
  /* translators: %s: document title */
1750
1802
  i18n.__("Move %s down", "valu-block-components"),
1751
- item.title
1803
+ displayName
1752
1804
  );
1753
1805
  const modified = showModifiedDate ? formatModified(item.modified) : "";
1806
+ const isLabelEdit = enableLabelEdit && !isMissing && Boolean(onLabelChange);
1807
+ const [labelDraft, setLabelDraft] = react$1.useState(null);
1808
+ const commitTimer = react$1.useRef(null);
1809
+ react$1.useEffect(
1810
+ () => () => {
1811
+ if (commitTimer.current) {
1812
+ clearTimeout(commitTimer.current);
1813
+ }
1814
+ },
1815
+ []
1816
+ );
1817
+ const normalizeLabel = (value) => {
1818
+ const trimmed = value.trim();
1819
+ return trimmed === "" || trimmed === item.title ? "" : value;
1820
+ };
1821
+ const itemLabelText = labels.itemLabel ?? i18n.__("Display name", "valu-block-components");
1822
+ const metaParts = [item.filename];
1823
+ if (showFileSize && item.fileSize) {
1824
+ metaParts.push(formatFileSize(item.fileSize));
1825
+ }
1826
+ if (modified) {
1827
+ metaParts.push(modified);
1828
+ }
1754
1829
  return /* @__PURE__ */ jsxRuntime.jsxs(
1755
1830
  SelectedRow2,
1756
1831
  {
@@ -1772,9 +1847,45 @@ var SelectedItem = ({
1772
1847
  }
1773
1848
  ) : null,
1774
1849
  isMissing ? /* @__PURE__ */ jsxRuntime.jsx(components.Icon, { icon: icons.caution, size: 20 }) : showExtensionBadge ? /* @__PURE__ */ jsxRuntime.jsx(ExtensionBadge, { extension: item.extension }) : null,
1775
- render ? render(item) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1850
+ render ? render(item) : isLabelEdit ? /* @__PURE__ */ jsxRuntime.jsxs(LabelEditBody, { children: [
1851
+ /* @__PURE__ */ jsxRuntime.jsx(
1852
+ components.TextControl,
1853
+ {
1854
+ __nextHasNoMarginBottom: true,
1855
+ __next40pxDefaultSize: false,
1856
+ "aria-label": i18n.sprintf(
1857
+ /* translators: 1: display-name field label, 2: filename */
1858
+ "%1$s: %2$s",
1859
+ itemLabelText,
1860
+ item.filename
1861
+ ),
1862
+ value: labelDraft ?? item.label ?? item.title,
1863
+ onChange: (value) => {
1864
+ setLabelDraft(value);
1865
+ if (commitTimer.current) {
1866
+ clearTimeout(commitTimer.current);
1867
+ }
1868
+ commitTimer.current = setTimeout(() => {
1869
+ commitTimer.current = null;
1870
+ onLabelChange?.(normalizeLabel(value));
1871
+ }, 300);
1872
+ },
1873
+ onBlur: () => {
1874
+ if (commitTimer.current) {
1875
+ clearTimeout(commitTimer.current);
1876
+ commitTimer.current = null;
1877
+ if (labelDraft !== null) {
1878
+ onLabelChange?.(normalizeLabel(labelDraft));
1879
+ }
1880
+ }
1881
+ setLabelDraft(null);
1882
+ }
1883
+ }
1884
+ ),
1885
+ /* @__PURE__ */ jsxRuntime.jsx(FilenameText, { title: item.filename, children: metaParts.join(" \xB7 ") })
1886
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1776
1887
  /* @__PURE__ */ jsxRuntime.jsxs(DocRowBody, { children: [
1777
- /* @__PURE__ */ jsxRuntime.jsx(PrimaryText, { muted: isMissing, title: item.title, children: isMissing ? missingLabel : item.title }),
1888
+ /* @__PURE__ */ jsxRuntime.jsx(PrimaryText, { muted: isMissing, title: displayName, children: isMissing ? missingLabel : displayName }),
1778
1889
  !isMissing ? /* @__PURE__ */ jsxRuntime.jsx(FilenameText, { title: item.filename, children: item.filename }) : null
1779
1890
  ] }),
1780
1891
  !isMissing && (showFileSize || modified) ? /* @__PURE__ */ jsxRuntime.jsxs(DocMetaInline, { children: [
@@ -1783,7 +1894,7 @@ var SelectedItem = ({
1783
1894
  ] }) : null
1784
1895
  ] }),
1785
1896
  /* @__PURE__ */ jsxRuntime.jsxs(ActionColumn, { children: [
1786
- orderable ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1897
+ orderable ? /* @__PURE__ */ jsxRuntime.jsxs(ReorderButtons, { children: [
1787
1898
  /* @__PURE__ */ jsxRuntime.jsx(
1788
1899
  components.Button,
1789
1900
  {
@@ -1839,7 +1950,7 @@ var useResolvedDocuments = (value) => {
1839
1950
  "attachment",
1840
1951
  item.id
1841
1952
  ]);
1842
- out[item.id] = { record: record ?? null, resolved };
1953
+ out[item.id] = resolved ? record ?? null : void 0;
1843
1954
  }
1844
1955
  return out;
1845
1956
  },
@@ -1847,10 +1958,8 @@ var useResolvedDocuments = (value) => {
1847
1958
  );
1848
1959
  return react$1.useMemo(
1849
1960
  () => value.map((item) => {
1850
- const entry = records[item.id];
1851
- if (!entry) return item;
1852
- const { record, resolved } = entry;
1853
- if (!resolved) return item;
1961
+ const record = records[item.id];
1962
+ if (record === void 0) return item;
1854
1963
  if (!record) return { ...item, missing: "deleted" };
1855
1964
  const fresh = mapMediaToDocumentItem(
1856
1965
  record
@@ -1879,7 +1988,8 @@ var SelectedList = ({
1879
1988
  showHeader = true,
1880
1989
  showExtensionBadge,
1881
1990
  showFileSize,
1882
- showModifiedDate
1991
+ showModifiedDate,
1992
+ enableItemLabels = false
1883
1993
  }) => {
1884
1994
  const resolved = useResolvedDocuments(value);
1885
1995
  const [activeKey, setActiveKey] = react$1.useState(null);
@@ -1894,6 +2004,22 @@ var SelectedList = ({
1894
2004
  (key) => onChange(value.filter((i) => i.key !== key)),
1895
2005
  [value, onChange]
1896
2006
  );
2007
+ const setLabel = react$1.useCallback(
2008
+ (key, label) => onChange(
2009
+ value.map((i) => {
2010
+ if (i.key !== key) {
2011
+ return i;
2012
+ }
2013
+ if (label === "") {
2014
+ const rest = { ...i };
2015
+ delete rest.label;
2016
+ return rest;
2017
+ }
2018
+ return { ...i, label };
2019
+ })
2020
+ ),
2021
+ [value, onChange]
2022
+ );
1897
2023
  const reorder = react$1.useCallback(
1898
2024
  (from, to) => {
1899
2025
  if (from === to) return;
@@ -1942,6 +2068,10 @@ var SelectedList = ({
1942
2068
  onRemove: () => remove(item.key),
1943
2069
  ...index > 0 ? { onMoveUp: () => reorder(index, index - 1) } : {},
1944
2070
  ...index < resolved.length - 1 ? { onMoveDown: () => reorder(index, index + 1) } : {},
2071
+ ...enableItemLabels ? {
2072
+ enableLabelEdit: true,
2073
+ onLabelChange: (label) => setLabel(item.key, label)
2074
+ } : {},
1945
2075
  ...renderSelected ? { render: renderSelected } : {}
1946
2076
  },
1947
2077
  item.key
@@ -1964,7 +2094,7 @@ var SelectedList = ({
1964
2094
  onDragCancel: () => setActiveKey(null),
1965
2095
  children: [
1966
2096
  /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: ids, strategy: sortable.verticalListSortingStrategy, children: /* @__PURE__ */ jsxRuntime.jsx(SelectedListEl, { role: "list", children: rows }) }),
1967
- /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { dropAnimation: core.defaultDropAnimation, children: activeItem ? /* @__PURE__ */ jsxRuntime.jsx(DragChip, { title: activeItem.title }) : null })
2097
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { dropAnimation: core.defaultDropAnimation, children: activeItem ? /* @__PURE__ */ jsxRuntime.jsx(DragChip, { title: displayTitle(activeItem) }) : null })
1968
2098
  ]
1969
2099
  }
1970
2100
  )
@@ -1995,6 +2125,7 @@ var DocumentPicker = ({
1995
2125
  fetchOnOpen = false,
1996
2126
  uniqueItems = true,
1997
2127
  enableMediaLibrary = true,
2128
+ enableItemLabels = false,
1998
2129
  showExtensionBadge = true,
1999
2130
  showFileSize = true,
2000
2131
  showModifiedDate = false,
@@ -2086,7 +2217,14 @@ var DocumentPicker = ({
2086
2217
  ...allowedExtensions !== void 0 ? { allowedExtensions } : {},
2087
2218
  multiple: false,
2088
2219
  value,
2089
- onSelect: (items) => handleChange([items[items.length - 1]]),
2220
+ onSelect: (items) => {
2221
+ const next = items[items.length - 1];
2222
+ const prev = value[0];
2223
+ const keepLabel = prev?.id === next.id && prev.label !== void 0;
2224
+ handleChange([
2225
+ keepLabel ? { ...next, label: prev.label } : next
2226
+ ]);
2227
+ },
2090
2228
  labels,
2091
2229
  variant: "tertiary",
2092
2230
  label: labels.replace
@@ -2104,7 +2242,8 @@ var DocumentPicker = ({
2104
2242
  showHeader: value.length > 0,
2105
2243
  showExtensionBadge,
2106
2244
  showFileSize,
2107
- showModifiedDate
2245
+ showModifiedDate,
2246
+ enableItemLabels
2108
2247
  }
2109
2248
  )
2110
2249
  ] }) }) });