fui-material 2.8.17 → 2.8.19

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.
@@ -1825,22 +1825,101 @@ const FDownloadIcon = React.forwardRef(({
1825
1825
  );
1826
1826
  });
1827
1827
  FDownloadIcon.displayName = "FDownloadIcon";
1828
- const overlay$1 = "_overlay_19vq5_1";
1829
- const entering$1 = "_entering_19vq5_15";
1830
- const exiting$1 = "_exiting_19vq5_19";
1831
- const viewport = "_viewport_19vq5_24";
1832
- const image = "_image_19vq5_33";
1833
- const zoomed = "_zoomed_19vq5_44";
1834
- const close$1 = "_close_19vq5_52";
1835
- const download$1 = "_download_19vq5_53";
1836
- const arrow = "_arrow_19vq5_54";
1837
- const left = "_left_19vq5_107";
1838
- const right = "_right_19vq5_111";
1839
- const indicators = "_indicators_19vq5_115";
1840
- const dot = "_dot_19vq5_124";
1841
- const active$4 = "_active_19vq5_133";
1842
- const spinner = "_spinner_19vq5_138";
1843
- const error$2 = "_error_19vq5_148";
1828
+ function fDownloadBlobFile(blob, fileName) {
1829
+ if (!blob) {
1830
+ throw new Error("Blob or string content must not be empty");
1831
+ }
1832
+ const blobObject = typeof blob === "string" ? new Blob([blob], { type: "text/plain;charset=utf-8" }) : blob;
1833
+ const link2 = document.createElement("a");
1834
+ const url = window.URL.createObjectURL(blobObject);
1835
+ link2.href = url;
1836
+ link2.download = fileName;
1837
+ link2.style.display = "none";
1838
+ document.body.appendChild(link2);
1839
+ link2.click();
1840
+ document.body.removeChild(link2);
1841
+ window.URL.revokeObjectURL(url);
1842
+ }
1843
+ const fDownloadFileFromBase64 = (base64String, fileName) => {
1844
+ if (!base64String) {
1845
+ console.error("Invalid Base64 string");
1846
+ return;
1847
+ }
1848
+ let mimeType;
1849
+ let base64Data;
1850
+ if (base64String.startsWith("data:")) {
1851
+ const dataUriMatch = base64String.match(/^data:([^;]+);base64,/);
1852
+ if (dataUriMatch && dataUriMatch[1]) {
1853
+ mimeType = dataUriMatch[1];
1854
+ } else {
1855
+ mimeType = "application/octet-stream";
1856
+ }
1857
+ base64Data = base64String.split(",")[1] || "";
1858
+ } else {
1859
+ mimeType = getMimeTypeFromFileName(fileName) || "application/octet-stream";
1860
+ base64Data = base64String;
1861
+ }
1862
+ try {
1863
+ const byteCharacters = atob(base64Data);
1864
+ const byteNumbers = new Array(byteCharacters.length);
1865
+ for (let i = 0; i < byteCharacters.length; i++) {
1866
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
1867
+ }
1868
+ const byteArray = new Uint8Array(byteNumbers);
1869
+ const blob = new Blob([byteArray], { type: mimeType });
1870
+ const url = window.URL.createObjectURL(blob);
1871
+ const link2 = document.createElement("a");
1872
+ link2.href = url;
1873
+ link2.download = fileName;
1874
+ document.body.appendChild(link2);
1875
+ link2.click();
1876
+ document.body.removeChild(link2);
1877
+ window.URL.revokeObjectURL(url);
1878
+ } catch (error2) {
1879
+ console.error("Ошибка при обработке Base64:", error2);
1880
+ }
1881
+ };
1882
+ const getMimeTypeFromFileName = (fileName) => {
1883
+ var _a;
1884
+ const extension = (_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase();
1885
+ if (!extension) return void 0;
1886
+ const mimeTypes = {
1887
+ txt: "text/plain",
1888
+ pdf: "application/pdf",
1889
+ png: "image/png",
1890
+ jpg: "image/jpeg",
1891
+ jpeg: "image/jpeg",
1892
+ gif: "image/gif",
1893
+ svg: "image/svg+xml",
1894
+ doc: "application/msword",
1895
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
1896
+ xls: "application/vnd.ms-excel",
1897
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
1898
+ ppt: "application/vnd.ms-powerpoint",
1899
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
1900
+ json: "application/json",
1901
+ zip: "application/zip",
1902
+ mp3: "audio/mpeg",
1903
+ mp4: "video/mp4"
1904
+ };
1905
+ return mimeTypes[extension];
1906
+ };
1907
+ const overlay$1 = "_overlay_1x5hi_1";
1908
+ const entering$1 = "_entering_1x5hi_15";
1909
+ const exiting$1 = "_exiting_1x5hi_19";
1910
+ const viewport = "_viewport_1x5hi_24";
1911
+ const image = "_image_1x5hi_33";
1912
+ const zoomed = "_zoomed_1x5hi_44";
1913
+ const close$1 = "_close_1x5hi_52";
1914
+ const download$1 = "_download_1x5hi_53";
1915
+ const arrow = "_arrow_1x5hi_54";
1916
+ const left = "_left_1x5hi_108";
1917
+ const right = "_right_1x5hi_112";
1918
+ const indicators = "_indicators_1x5hi_116";
1919
+ const dot = "_dot_1x5hi_125";
1920
+ const active$4 = "_active_1x5hi_134";
1921
+ const spinner = "_spinner_1x5hi_139";
1922
+ const error$2 = "_error_1x5hi_149";
1844
1923
  const styles$o = {
1845
1924
  overlay: overlay$1,
1846
1925
  entering: entering$1,
@@ -1860,6 +1939,54 @@ const styles$o = {
1860
1939
  error: error$2
1861
1940
  };
1862
1941
  let openImageViewersCount = 0;
1942
+ const getExtensionFromMimeType$1 = (mimeType) => {
1943
+ const cleanType = mimeType.split(";")[0].trim().toLowerCase();
1944
+ switch (cleanType) {
1945
+ case "image/jpeg":
1946
+ return "jpg";
1947
+ case "image/png":
1948
+ return "png";
1949
+ case "image/gif":
1950
+ return "gif";
1951
+ case "image/webp":
1952
+ return "webp";
1953
+ case "image/svg+xml":
1954
+ return "svg";
1955
+ case "image/avif":
1956
+ return "avif";
1957
+ case "image/bmp":
1958
+ return "bmp";
1959
+ case "image/x-icon":
1960
+ case "image/vnd.microsoft.icon":
1961
+ return "ico";
1962
+ default:
1963
+ return "";
1964
+ }
1965
+ };
1966
+ const getFileName$1 = (url, fallback) => {
1967
+ if (url.startsWith("data:")) {
1968
+ const mimeMatch = url.match(/^data:([^;]+);/);
1969
+ const ext = mimeMatch ? getExtensionFromMimeType$1(mimeMatch[1]) : "png";
1970
+ const base = "image";
1971
+ return base.includes(".") ? base : `${base}.${ext || "png"}`;
1972
+ }
1973
+ try {
1974
+ const parsed = new URL(url, window.location.href);
1975
+ const segments = parsed.pathname.split("/").filter(Boolean);
1976
+ const lastSegment = segments.pop();
1977
+ if (lastSegment) {
1978
+ return decodeURIComponent(lastSegment);
1979
+ }
1980
+ } catch {
1981
+ const clean = url.split("?")[0].split("#")[0];
1982
+ const segments = clean.split("/").filter(Boolean);
1983
+ const lastSegment = segments.pop();
1984
+ if (lastSegment) {
1985
+ return decodeURIComponent(lastSegment);
1986
+ }
1987
+ }
1988
+ return "image";
1989
+ };
1863
1990
  const FOpenImgFull = ({
1864
1991
  id,
1865
1992
  className,
@@ -1868,7 +1995,9 @@ const FOpenImgFull = ({
1868
1995
  selectedImg,
1869
1996
  setSelectedImg,
1870
1997
  handleClose,
1871
- openAndClose
1998
+ openAndClose,
1999
+ fileName,
2000
+ fileNames
1872
2001
  }) => {
1873
2002
  const [isMounted, setIsMounted] = useState(openAndClose);
1874
2003
  const [isClosing, setIsClosing] = useState(false);
@@ -1925,6 +2054,40 @@ const FOpenImgFull = ({
1925
2054
  const nextIndex = selectedImg + offset;
1926
2055
  if (nextIndex >= 0 && nextIndex < imagesUrl.length) setSelectedImg(nextIndex);
1927
2056
  };
2057
+ const handleDownload = async (event) => {
2058
+ event.stopPropagation();
2059
+ if (!imageUrl) return;
2060
+ const defaultFileName = getFileName$1(imageUrl);
2061
+ const resolvedFileName = (fileNames == null ? void 0 : fileNames[selectedImg]) || fileName || defaultFileName;
2062
+ try {
2063
+ if (imageUrl.startsWith("data:")) {
2064
+ fDownloadFileFromBase64(imageUrl, resolvedFileName);
2065
+ return;
2066
+ }
2067
+ const response = await fetch(imageUrl);
2068
+ if (!response.ok) {
2069
+ throw new Error(`Failed to fetch image: ${response.statusText}`);
2070
+ }
2071
+ const blob = await response.blob();
2072
+ let finalName = resolvedFileName;
2073
+ if (!finalName.includes(".") && blob.type) {
2074
+ const ext = getExtensionFromMimeType$1(blob.type);
2075
+ if (ext) {
2076
+ finalName = `${finalName}.${ext}`;
2077
+ }
2078
+ }
2079
+ fDownloadBlobFile(blob, finalName);
2080
+ } catch {
2081
+ const link2 = document.createElement("a");
2082
+ link2.href = imageUrl;
2083
+ link2.download = resolvedFileName;
2084
+ link2.target = "_blank";
2085
+ link2.rel = "noreferrer noopener";
2086
+ document.body.appendChild(link2);
2087
+ link2.click();
2088
+ document.body.removeChild(link2);
2089
+ }
2090
+ };
1928
2091
  return createPortal(
1929
2092
  /* @__PURE__ */ jsxs(
1930
2093
  "div",
@@ -1937,7 +2100,17 @@ const FOpenImgFull = ({
1937
2100
  },
1938
2101
  children: [
1939
2102
  handleClose && /* @__PURE__ */ jsx("button", { type: "button", className: styles$o.close, onClick: handleClose, "aria-label": "Закрыть просмотр изображений", children: /* @__PURE__ */ jsx(FCloseIcon, { color: "light", size: 24 }) }),
1940
- /* @__PURE__ */ jsx("a", { className: styles$o.download, href: imageUrl, download: true, "aria-label": "Скачать изображение", title: "Скачать изображение", children: /* @__PURE__ */ jsx(FDownloadIcon, { color: "light", size: 20 }) }),
2103
+ /* @__PURE__ */ jsx(
2104
+ "button",
2105
+ {
2106
+ type: "button",
2107
+ className: styles$o.download,
2108
+ onClick: handleDownload,
2109
+ "aria-label": "Скачать изображение",
2110
+ title: "Скачать изображение",
2111
+ children: /* @__PURE__ */ jsx(FDownloadIcon, { color: "light", size: 20 })
2112
+ }
2113
+ ),
1941
2114
  selectedImg > 0 && /* @__PURE__ */ jsx("button", { type: "button", className: `${styles$o.arrow} ${styles$o.left}`, onClick: () => changeImage(-1), "aria-label": "Предыдущее изображение", children: /* @__PURE__ */ jsx(FArrowIcon, { direction: "left", color: "light", size: 28 }) }),
1942
2115
  /* @__PURE__ */ jsxs("div", { className: styles$o.viewport, children: [
1943
2116
  isLoading && !hasError && /* @__PURE__ */ jsx("span", { className: styles$o.spinner, "aria-label": "Загрузка изображения" }),
@@ -2018,85 +2191,6 @@ const FOpenImgFull = ({
2018
2191
  document.body
2019
2192
  );
2020
2193
  };
2021
- function fDownloadBlobFile(blob, fileName) {
2022
- if (!blob) {
2023
- throw new Error("Blob or string content must not be empty");
2024
- }
2025
- const blobObject = typeof blob === "string" ? new Blob([blob], { type: "text/plain;charset=utf-8" }) : blob;
2026
- const link2 = document.createElement("a");
2027
- const url = window.URL.createObjectURL(blobObject);
2028
- link2.href = url;
2029
- link2.download = fileName;
2030
- link2.style.display = "none";
2031
- document.body.appendChild(link2);
2032
- link2.click();
2033
- document.body.removeChild(link2);
2034
- window.URL.revokeObjectURL(url);
2035
- }
2036
- const fDownloadFileFromBase64 = (base64String, fileName) => {
2037
- if (!base64String) {
2038
- console.error("Invalid Base64 string");
2039
- return;
2040
- }
2041
- let mimeType;
2042
- let base64Data;
2043
- if (base64String.startsWith("data:")) {
2044
- const dataUriMatch = base64String.match(/^data:([^;]+);base64,/);
2045
- if (dataUriMatch && dataUriMatch[1]) {
2046
- mimeType = dataUriMatch[1];
2047
- } else {
2048
- mimeType = "application/octet-stream";
2049
- }
2050
- base64Data = base64String.split(",")[1] || "";
2051
- } else {
2052
- mimeType = getMimeTypeFromFileName(fileName) || "application/octet-stream";
2053
- base64Data = base64String;
2054
- }
2055
- try {
2056
- const byteCharacters = atob(base64Data);
2057
- const byteNumbers = new Array(byteCharacters.length);
2058
- for (let i = 0; i < byteCharacters.length; i++) {
2059
- byteNumbers[i] = byteCharacters.charCodeAt(i);
2060
- }
2061
- const byteArray = new Uint8Array(byteNumbers);
2062
- const blob = new Blob([byteArray], { type: mimeType });
2063
- const url = window.URL.createObjectURL(blob);
2064
- const link2 = document.createElement("a");
2065
- link2.href = url;
2066
- link2.download = fileName;
2067
- document.body.appendChild(link2);
2068
- link2.click();
2069
- document.body.removeChild(link2);
2070
- window.URL.revokeObjectURL(url);
2071
- } catch (error2) {
2072
- console.error("Ошибка при обработке Base64:", error2);
2073
- }
2074
- };
2075
- const getMimeTypeFromFileName = (fileName) => {
2076
- var _a;
2077
- const extension = (_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase();
2078
- if (!extension) return void 0;
2079
- const mimeTypes = {
2080
- txt: "text/plain",
2081
- pdf: "application/pdf",
2082
- png: "image/png",
2083
- jpg: "image/jpeg",
2084
- jpeg: "image/jpeg",
2085
- gif: "image/gif",
2086
- svg: "image/svg+xml",
2087
- doc: "application/msword",
2088
- docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
2089
- xls: "application/vnd.ms-excel",
2090
- xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
2091
- ppt: "application/vnd.ms-powerpoint",
2092
- pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
2093
- json: "application/json",
2094
- zip: "application/zip",
2095
- mp3: "audio/mpeg",
2096
- mp4: "video/mp4"
2097
- };
2098
- return mimeTypes[extension];
2099
- };
2100
2194
  const preview$1 = "_preview_irgtv_1";
2101
2195
  const imageButton = "_imageButton_irgtv_7";
2102
2196
  const download = "_download_irgtv_27";
@@ -2228,7 +2322,8 @@ const FImagePreview = ({ src, alt = "", id, className, st, fileName }) => {
2228
2322
  selectedImg: 0,
2229
2323
  setSelectedImg: () => void 0,
2230
2324
  openAndClose: isOpen,
2231
- handleClose: () => setIsOpen(false)
2325
+ handleClose: () => setIsOpen(false),
2326
+ fileName
2232
2327
  }
2233
2328
  )
2234
2329
  ] });