From 706226858f8cebaf4622fbc2c4d5cf865850922b Mon Sep 17 00:00:00 2001
From: Jose Manuel Serrano Amaut <a20122128@pucp.pe>
Date: Mon, 6 Mar 2023 21:46:16 -0500
Subject: [PATCH] [WIP]: Add FIleMosaic Demo Localization, upload, darkmode and
 file icons. Missing to properly set the right menu. Also missing to decide
 whether to keep the extensive list in FIle mosaic demo page and replicate in
 File card or to create a new page for the list of icons

---
 .../CodeJSFileMosaicDarkMode.tsx              | 111 ++++++
 .../CodeJSFileMosaicLocalization.jsx          | 266 ++++++++++++++
 .../CodeJSFileMosaicUploadStatus.jsx          | 327 ++++++++++++------
 .../CodeJSFileMosaicValidation.jsx            |  64 ++--
 .../DemoFileMosaicDarkMode.tsx                |  41 +++
 .../DemoFileMosaicFileIcons.jsx               |  37 ++
 .../DemoFileMosaicLocalization.tsx            | 126 +++++++
 .../DemoFileMosaicUploadStatus.tsx            | 254 +++++---------
 .../DemoFileMosaicValidation.jsx              |   3 +-
 .../show-demo-code/ShowDemoCode.tsx           | 136 ++++----
 .../components/file-mosaic/FileMosaic.tsx     |   2 +-
 src/files-ui/hooks/index.ts                   |   5 +-
 src/files-ui/hooks/useFakeProgress.ts         |  38 ++
 src/files-ui/index.ts                         |   8 +-
 src/pages/demo/FileMosaicDemoPage.jsx         | 108 +++++-
 15 files changed, 1154 insertions(+), 372 deletions(-)
 create mode 100644 src/components/demo-components/filemosaic-demo/CodeJSFileMosaicDarkMode.tsx
 create mode 100644 src/components/demo-components/filemosaic-demo/CodeJSFileMosaicLocalization.jsx
 create mode 100644 src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx
 create mode 100644 src/components/demo-components/filemosaic-demo/DemoFileMosaicFileIcons.jsx
 create mode 100644 src/components/demo-components/filemosaic-demo/DemoFileMosaicLocalization.tsx
 create mode 100644 src/files-ui/hooks/useFakeProgress.ts

diff --git a/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicDarkMode.tsx b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicDarkMode.tsx
new file mode 100644
index 0000000..bdcbb48
--- /dev/null
+++ b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicDarkMode.tsx
@@ -0,0 +1,111 @@
+import * as React from "react";
+import ShowDemoCode from "../../show-demo-code/ShowDemoCode";
+
+const CodeJSFileMosaicDarkMode = () => {
+  return (
+    <ShowDemoCode
+      codeCompleteJS={completeCodeJS}
+      codeCompleteTS={completeCodeTS}
+      codeSandboxJS="https://codesandbox.io/s/dropzone-ui-basic-3j01v"
+      codeSandboxTS="https://codesandbox.io/s/dropzone-ui-basic-3j01v"
+      codeSplittedJS={splittedCodeJS}
+      codeSplittedTS={splittedCodeTS}
+    />
+  );
+};
+export default CodeJSFileMosaicDarkMode;
+
+const splittedCodeJS = `<>
+  <FileMosaic {...sampleFileProps} info onDelete={removeFile} />
+  <FileMosaic {...sampleFileProps} info onDelete={removeFile} darkMode/>
+</>`;
+const splittedCodeTS = `<>
+<FileMosaic {...sampleFileProps} info onDelete={removeFile} />
+<FileMosaic {...sampleFileProps} info onDelete={removeFile} darkMode/>
+</>`;
+
+const completeCodeJS = `import * as React from "react";
+import { FileMosaic } from "@files-ui/react";
+
+const sampleFileProps = {
+  id: "fileId",
+  size: 28 * 1024 * 1024,
+  type: "text/plain",
+  name: "file created from props.jsx",
+};
+const DemoFileMosaicDarkMode = () => {
+  const removeFile = (id) => {
+    console.log("delete button clicked on file: " + id);
+  };
+  return (
+    <>
+      <div
+        style={{
+          display: "flex",
+          justifyContent: "center",
+          width: "50%",
+          backgroundColor: "white",
+          padding: "10px 0",
+        }}
+      >
+        <FileMosaic {...sampleFileProps} info onDelete={removeFile} />
+      </div>
+      <div
+        style={{
+          display: "flex",
+          justifyContent: "center",
+          width: "50%",
+          backgroundColor: "#121212",
+          padding: "10px 0",
+        }}
+      >
+        <FileMosaic {...sampleFileProps} info darkMode onDelete={removeFile} />
+      </div>
+    </>
+  );
+};
+export default DemoFileMosaicDarkMode;
+`;
+
+const completeCodeTS = `import * as React from "react";
+import { ExtFile, FileMosaic } from "@files-ui/react";
+
+const sampleFileProps: ExtFile = {
+  id: "fileId",
+  size: 28 * 1024 * 1024,
+  type: "text/plain",
+  name: "file created from props.jsx",
+};
+const DemoFileMosaicDarkMode = () => {
+  const removeFile = (id: string | number | undefined) => {
+    console.log("delete button clicked on file: " + id);
+  };
+  return (
+    <>
+      <div
+        style={{
+          display: "flex",
+          justifyContent: "center",
+          width: "50%",
+          backgroundColor: "white",
+          padding: "10px 0",
+        }}
+      >
+        <FileMosaic {...sampleFileProps} info onDelete={removeFile} />
+      </div>
+      <div
+        style={{
+          display: "flex",
+          justifyContent: "center",
+          width: "50%",
+          backgroundColor: "#121212",
+          padding: "10px 0",
+        }}
+      >
+        <FileMosaic {...sampleFileProps} info darkMode onDelete={removeFile} />
+      </div>
+    </>
+  );
+};
+export default DemoFileMosaicDarkMode;
+`;
diff --git a/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicLocalization.jsx b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicLocalization.jsx
new file mode 100644
index 0000000..a4d570d
--- /dev/null
+++ b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicLocalization.jsx
@@ -0,0 +1,266 @@
+import * as React from "react";
+import ShowDemoCode from "../../show-demo-code/ShowDemoCode";
+
+const CodeJSFileMosaicLocalization = (props) => {
+  return (
+    <ShowDemoCode
+      codeCompleteJS={completeCodeJS}
+      codeCompleteTS={completeCodeTS}
+      codeSandboxJS="https://codesandbox.io/s/dropzone-ui-basic-3j01v"
+      codeSandboxTS="https://codesandbox.io/s/dropzone-ui-basic-3j01v"
+      codeSplittedJS={splittedCodeJS}
+      codeSplittedTS={splittedCodeTS}
+    />
+  );
+};
+export default CodeJSFileMosaicLocalization;
+
+const splittedCodeJS = ``;
+const splittedCodeTS = ``;
+
+
+const completeCodeJS = `import * as React from "react";
+import { FileMosaic } from "@files-ui/react";
+import { Autocomplete, TextField } from "@mui/material";
+
+const DemoFileMosaicLocalization = () => {
+  const [localization, setLocalization] = React.useState(undefined);
+
+  const hadleSelect = (value) => {
+    console.log(value);
+    setLocalization(value?.value);
+ };
+  return (
+    <>
+      <Autocomplete
+        disablePortal
+        autoSelect
+        size="small"
+        onChange={(e, value) => hadleSelect(value)}
+        id="combo-box-demo"
+        options={languages}
+        sx={{ width: 300 }}
+        getOptionLabel={(option) => option.language}
+        renderInput={(params) => <TextField {...params} label="Localization" />}
+      />
+      <div
+        style={{
+          display: "flex",
+          flexWrap: "wrap",
+          justifyContent: "space-evenly",
+          width: "100%",
+          gap: "50px",
+        }}
+      >
+        {extFiles.map((extFile, index) => (
+          <FileMosaic
+            key={index}
+            {...extFile}
+            localization={localization}
+            onDelete={() => {}}
+            info
+          />
+        ))}
+      </div>
+    </>
+  );
+};
+export default DemoFileMosaicLocalization;
+
+const languages = [
+  { language: "Español: ES-es", value: "ES-es" },
+  { language: "English: EN-en", value: "EN-en" },
+  { language: "French: FR-fr", value: "FR-fr" },
+  { language: "Italian: IT-it", value: "IT-it" },
+  { language: "Portuguese: PT-pt", value: "PT-pt" },
+  { language: "Russian: RU-ru", value: "RU-ru" },
+  { language: "Chinese(simplified): ZH-cn", value: "ZH-cn" },
+  { language: "Chinese(traditional): ZH-hk", value: "ZH-hk" },
+];
+const extFiles = [
+  {
+    id: 0,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    errors: ["pdf not allowed", "file is too big"],
+  },
+  {
+    id: 1,
+    valid: false,
+    name: "file_localization.docx",
+
+    size: 28 * 1024,
+    errors: ["pdf not allowed", "file is too big"],
+  },
+  {
+    id: 2,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+  },
+  {
+    id: 3,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "preparing",
+  },
+  {
+    id: 4,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "uploading",
+    progress: 28,
+  },
+  {
+    id: 5,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "aborted",
+    uploadMessage: "Upload was aborted",
+  },
+  {
+    id: 6,
+    valid: false,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "error",
+    uploadMessage: "there was an error on the server",
+  },
+  {
+    id: 7,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "success",
+    uploadMessage: "files-ui <3",
+  },
+];`;
+
+const completeCodeTS = `import * as React from "react";
+import { ExtFile, FileMosaic, Localization } from "@files-ui/react";
+import { Autocomplete, TextField } from "@mui/material";
+
+const DemoFileMosaicLocalization = () => {
+  const [localization, setLocalization] = React.useState<
+    Localization | undefined
+  >(undefined);
+
+  const hadleSelect = (value: LanguageItem | null) => {
+    console.log(value);
+    setLocalization(value?.value);
+ };
+
+  return (
+    <>
+      <Autocomplete
+        disablePortal
+        autoSelect
+        size="small"
+        onChange={(e, value) => hadleSelect(value as LanguageItem)}
+        id="combo-box-demo"
+        options={languages}
+        sx={{ width: 300 }}
+        getOptionLabel={(option) => option.language}
+        renderInput={(params) => <TextField {...params} label="Localization" />}
+      />
+      <div
+        style={{
+          display: "flex",
+          flexWrap: "wrap",
+          justifyContent: "space-evenly",
+          width: "100%",
+          gap: "50px",
+        }}
+      >
+        {extFiles.map((extFile, index) => (
+          <FileMosaic
+            key={index}
+            {...extFile}
+            localization={localization}
+            onDelete={() => {}}
+            info
+          />
+        ))}
+      </div>
+    </>
+  );
+};
+export default DemoFileMosaicLocalization;
+
+interface LanguageItem {
+  language: string;
+  value: Localization;
+}
+
+const languages = [
+  { language: "Español: ES-es", value: "ES-es" },
+  { language: "English: EN-en", value: "EN-en" },
+  { language: "French: FR-fr", value: "FR-fr" },
+  { language: "Italian: IT-it", value: "IT-it" },
+  { language: "Portuguese: PT-pt", value: "PT-pt" },
+  { language: "Russian: RU-ru", value: "RU-ru" },
+  { language: "Chinese(simplified): ZH-cn", value: "ZH-cn" },
+  { language: "Chinese(traditional): ZH-hk", value: "ZH-hk" },
+];
+const extFiles: ExtFile[] = [
+  {
+    id: 0,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    errors: ["pdf not allowed", "file is too big"],
+  },
+  {
+    id: 1,
+    valid: false,
+    name: "file_localization.docx",
+
+    size: 28 * 1024,
+    errors: ["pdf not allowed", "file is too big"],
+  },
+  {
+    id: 2,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+  },
+  {
+    id: 3,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "preparing",
+  },
+  {
+    id: 4,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "uploading",
+    progress: 28,
+  },
+  {
+    id: 5,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "aborted",
+    uploadMessage: "Upload was aborted",
+  },
+  {
+    id: 6,
+    valid: false,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "error",
+    uploadMessage: "there was an error on the server",
+  },
+  {
+    id: 7,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "success",
+    uploadMessage: "files-ui <3",
+  },
+];`;
diff --git a/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicUploadStatus.jsx b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicUploadStatus.jsx
index 855cda4..0ee9725 100644
--- a/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicUploadStatus.jsx
+++ b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicUploadStatus.jsx
@@ -15,135 +15,254 @@ const CodeJSFileMosaicUploadStatus = () => {
 };
 export default CodeJSFileMosaicUploadStatus;
 
-const splittedCodeJS = `<>
-  {sampleFilesProps.map((extFile) => (
-    <FileMosaic key={extFile.id} {...extFile} alwaysActive info preview />
-  ))}
-</>
-
-// file props
-const sampleFilesProps = [
-    {
-        id: "fileId-1",
-        size: 28 * 1024 * 1024,
-        type: "text/plain",
-        name: "file created from props.jsx",
-    },
-    {
-        id: "fileId-2",
-        size: 28 * 1024 * 1024,
-        type: "image/png",
-        name: "valid file created from props.png",
-        valid: true,
-    },
-    {
-        id: "fileId-3",
-        size: 28 * 1024 * 1024,
-        type: "image/jpeg",
-        name: "non valid file created from props.jpg",
-        valid: false,
-    },
-];`;
+const splittedCodeJS = ``;
+
+const splittedCodeTS = ``;
 
 const completeCodeJS = `import * as React from "react";
-import { FileMosaic } from "../../../files-ui";
+import {
+  FileMosaic,
+  useFakeProgress,
+} from "@files-ui/react";
 
-const sampleFilesProps = [
-  {
-    id: "fileId-1",
-    size: 28 * 1024 * 1024,
-    type: "text/plain",
-    name: "file created from props.jsx",
-  },
+const DemoFileMosaicUploadStatus = () => {
+  const progress = useFakeProgress();
+
+  const [status1, setStatus1] = React.useState("uploading");
+  const [status2, setStatus2] = React.useState("uploading");
+  const [status3, setStatus3] = React.useState("uploading");
+
+  React.useEffect(() => {
+    //schedule an interval
+    const _myInterval = setInterval(() => {
+      //set the uploadstatus result
+      setStatus1((_status) => setNextUploadState(_status, "aborted"));
+      setStatus2((_status) => setNextUploadState(_status, "error"));
+      setStatus3((_status) => setNextUploadState(_status, "success"));
+    }, 5000);
+
+    //clean
+    return () => {
+      console.log("clear interval", _myInterval);
+      clearInterval(_myInterval);
+    };
+  }, []);
+
+  const handleCancel = (id) => {
+    console.log("Upload canceled in file: " + id);
+  };
+  const handleAbort = (id) => {
+    console.log("Upload aborted in file: " + id);
+  };
+  return (
+    <>
+      <FlexRowContainer>
+        <FileMosaic {...preparingFile} />
+        <FileMosaic {...preparingFile} onCancel={handleCancel} />
+      </FlexRowContainer>
+
+      <FlexRowContainer>
+        <FileMosaic {...uploadingFile} />
+        <FileMosaic {...uploadingFile} progress={progress} />
+        <FileMosaic {...uploadingFile} onAbort={handleAbort} />
+        <FileMosaic {...uploadingFile} onAbort={handleAbort} progress={progress} />
+      </FlexRowContainer>
+
+      <FlexRowContainer>
+        <FileMosaic {...uploadResultFiles[0]} uploadStatus={status1} />
+        <FileMosaic {...uploadResultFiles[1]} uploadStatus={status2} />
+        <FileMosaic {...uploadResultFiles[2]} uploadStatus={status3} />
+      </FlexRowContainer>
+    </>
+  );
+};
+export default DemoFileMosaicUploadStatus;
+
+const FlexRowContainer = ({ children }) => {
+  return (
+    <div
+      style={{
+        display: "flex",
+        flexWrap: "wrap",
+        justifyContent: "space-evenly",
+        width: "100%",
+      }}
+    >
+      {children}
+    </div>
+  );
+};
+
+const setNextUploadState = (
+  prevState,
+  nextStatus
+) => {
+  if (prevState === "uploading") return nextStatus;
+  else return "uploading";
+};
+
+const preparingFile = {
+  id: "fileId-0",
+  size: 28 * 1024 * 1024,
+  type: "text/plain",
+  name: "preparing file.jsx",
+  uploadStatus: "preparing",
+};
+
+const uploadingFile = {
+  id: "fileId-1",
+  size: 28 * 1024 * 1024,
+  type: "image/png",
+  name: "uploading file.png",
+  uploadStatus: "uploading",
+};
+
+const uploadResultFiles = [
   {
     id: "fileId-2",
     size: 28 * 1024 * 1024,
-    type: "image/png",
-    name: "valid file created from props.png",
-    valid: true,
+    type: "image/gif",
+    name: "upload aborted file.gif",
+    uploadMessage: "Upload was aborted by the user",
   },
   {
     id: "fileId-3",
     size: 28 * 1024 * 1024,
     type: "image/jpeg",
-    name: "non valid file created from props.jpg",
-    valid: false,
+    name: "upload with error file.jpg",
+    uploadMessage:
+      "File couldn't be uploaded to Files-ui earthquakes. File was too big.",
+  },
+  {
+    id: "fileId-4",
+    size: 28 * 1024 * 1024,
+    type: "image/png",
+    name: "successfully uploaded file.png",
+    uploadMessage: "File was uploaded correctly to Files-ui earthquakes",
   },
-];
+];`;
+
+const completeCodeTS = `import * as React from "react";
+import {
+  FileMosaic,
+  useFakeProgress,
+  ExtFile,
+  UPLOADSTATUS,
+} from "@files-ui/react";
+
+const DemoFileMosaicUploadStatus = () => {
+  const progress = useFakeProgress();
+
+  const [status1, setStatus1] = React.useState<UPLOADSTATUS>("uploading");
+  const [status2, setStatus2] = React.useState<UPLOADSTATUS>("uploading");
+  const [status3, setStatus3] = React.useState<UPLOADSTATUS>("uploading");
+
+  React.useEffect(() => {
+    //schedule an interval
+    const _myInterval = setInterval(() => {
+      //set the uploadstatus result
+      setStatus1((_status) => setNextUploadState(_status, "aborted"));
+      setStatus2((_status) => setNextUploadState(_status, "error"));
+      setStatus3((_status) => setNextUploadState(_status, "success"));
+    }, 5000);
+
+    //clean
+    return () => {
+      console.log("clear interval", _myInterval);
+      clearInterval(_myInterval as NodeJS.Timer);
+    };
+  }, []);
 
-const DemoFileMosaicValidation = () => {
+  const handleCancel = (id: string | number | undefined) => {
+    console.log("Upload canceled in file: " + id);
+  };
+  const handleAbort = (id: string | number | undefined) => {
+    console.log("Upload aborted in file: " + id);
+  };
   return (
     <>
-      {sampleFilesProps.map((extFile) => (
-        <FileMosaic key={extFile.id} {...extFile} alwaysActive info preview />
-      ))}
+      <FlexRowContainer>
+        <FileMosaic {...preparingFile} />
+        <FileMosaic {...preparingFile} onCancel={handleCancel} />
+      </FlexRowContainer>
+
+      <FlexRowContainer>
+        <FileMosaic {...uploadingFile} />
+        <FileMosaic {...uploadingFile} progress={progress} />
+        <FileMosaic {...uploadingFile} onAbort={handleAbort} />
+        <FileMosaic {...uploadingFile} onAbort={handleAbort} progress={progress} />
+      </FlexRowContainer>
+
+      <FlexRowContainer>
+        <FileMosaic {...uploadResultFiles[0]} uploadStatus={status1} />
+        <FileMosaic {...uploadResultFiles[1]} uploadStatus={status2} />
+        <FileMosaic {...uploadResultFiles[2]} uploadStatus={status3} />
+      </FlexRowContainer>
     </>
   );
 };
-export default DemoFileMosaicValidation;`;
-
-const splittedCodeTS = `<>
-  {sampleFilesProps.map((extFile:ExtFile) => (
-    <FileMosaic key={extFile.id} {...extFile} alwaysActive info preview />
-  ))}
-</>
-
-// file props
-const sampleFilesProps:ExtFile[] = [
-    {
-        id: "fileId-1",
-        size: 28 * 1024 * 1024,
-        type: "text/plain",
-        name: "file created from props.jsx",
-    },
-    {
-        id: "fileId-2",
-        size: 28 * 1024 * 1024,
-        type: "image/png",
-        name: "valid file created from props.png",
-        valid: true,
-    },
-    {
-        id: "fileId-3",
-        size: 28 * 1024 * 1024,
-        type: "image/jpeg",
-        name: "non valid file created from props.jpg",
-        valid: false,
-    },
-];`;
-const completeCodeTS = `import * as React from "react";
-import { FileMosaic, ExtFile } from "../../../files-ui";
+export default DemoFileMosaicUploadStatus;
 
-const sampleFilesProps: ExtFile[] = [
-  {
-    id: "fileId-1",
-    size: 28 * 1024 * 1024,
-    type: "text/plain",
-    name: "file created from props.jsx",
-  },
+const FlexRowContainer = (props: { children: React.ReactNode }) => {
+  return (
+    <div
+      style={{
+        display: "flex",
+        flexWrap: "wrap",
+        justifyContent: "space-evenly",
+        width: "100%",
+      }}
+    >
+      {props.children}
+    </div>
+  );
+};
+
+const setNextUploadState = (
+  prevState: UPLOADSTATUS,
+  nextStatus: UPLOADSTATUS
+): UPLOADSTATUS => {
+  if (prevState === "uploading") return nextStatus;
+  else return "uploading";
+};
+
+const preparingFile: ExtFile = {
+  id: "fileId-0",
+  size: 28 * 1024 * 1024,
+  type: "text/plain",
+  name: "preparing file.jsx",
+  uploadStatus: "preparing",
+};
+
+const uploadingFile: ExtFile = {
+  id: "fileId-1",
+  size: 28 * 1024 * 1024,
+  type: "image/png",
+  name: "uploading file.png",
+  uploadStatus: "uploading",
+};
+
+const uploadResultFiles: ExtFile[] = [
   {
     id: "fileId-2",
     size: 28 * 1024 * 1024,
-    type: "image/png",
-    name: "valid file created from props.png",
-    valid: true,
+    type: "image/gif",
+    name: "upload aborted file.gif",
+    uploadMessage: "Upload was aborted by the user",
   },
   {
     id: "fileId-3",
     size: 28 * 1024 * 1024,
     type: "image/jpeg",
-    name: "non valid file created from props.jpg",
-    valid: false,
+    name: "upload with error file.jpg",
+    uploadMessage:
+      "File couldn't be uploaded to Files-ui earthquakes. File was too big.",
   },
-];
-
-const DemoFileMosaicValidation = () => {
-  return (
-    <>
-      {sampleFilesProps.map((extFile: ExtFile) => (
-        <FileMosaic key={extFile.id} {...extFile} alwaysActive info preview />
-      ))}
-    </>
-  );
-};
-export default DemoFileMosaicValidation;`;
+  {
+    id: "fileId-4",
+    size: 28 * 1024 * 1024,
+    type: "image/png",
+    name: "successfully uploaded file.png",
+    uploadMessage: "File was uploaded correctly to Files-ui earthquakes",
+  },
+];`;
diff --git a/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicValidation.jsx b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicValidation.jsx
index c368ea5..435488c 100644
--- a/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicValidation.jsx
+++ b/src/components/demo-components/filemosaic-demo/CodeJSFileMosaicValidation.jsx
@@ -15,15 +15,23 @@ const CodeJSFileMosaicValidation = () => {
 };
 export default CodeJSFileMosaicValidation;
 
-const splittedCodeJS = `<>
-  {sampleFilesProps.map((extFile) => (
-    <FileMosaic key={extFile.id} {...extFile} info/>
-  ))}
-</>`;
+const splittedCodeJS = ``;
+const splittedCodeTS = ``;
 
 const completeCodeJS = `import * as React from "react";
 import { FileMosaic } from "../../../files-ui";
 
+const DemoFileMosaicValidation = () => {
+  return (
+    <div style={{display:"flex", gap:"10px"}}>
+      {sampleFilesProps.map((extFile) => (
+        <FileMosaic key={extFile.id} valid={extFile.valid} {...extFile} info/>
+      ))}
+    </div>
+  );
+};
+export default DemoFileMosaicValidation;
+
 const sampleFilesProps = [
   {
     id: "fileId-1",
@@ -36,35 +44,31 @@ const sampleFilesProps = [
     size: 28 * 1024 * 1024,
     type: "image/png",
     name: "valid file created from props.png",
-    valid: true,
+    valid: false,
+    errors: ["File is too big", "File type is not allowed"]
   },
   {
     id: "fileId-3",
     size: 28 * 1024 * 1024,
     type: "image/jpeg",
     name: "non valid file created from props.jpg",
-    valid: false,
+    valid: true,
   },
-];
+];`;
+
+const completeCodeTS = `import * as React from "react";
+import { FileMosaic, ExtFile } from "../../../files-ui";
 
 const DemoFileMosaicValidation = () => {
   return (
-    <>
-      {sampleFilesProps.map((extFile) => (
-        <FileMosaic key={extFile.id} {...extFile} info/>
+    <div style={{display:"flex", gap:"10px"}}>
+      {sampleFilesProps.map((extFile: ExtFile) => (
+        <FileMosaic key={extFile.id} valid={extFile.valid} {...extFile} info/>
       ))}
-    </>
+    </div>
   );
 };
-export default DemoFileMosaicValidation;`;
-
-const splittedCodeTS = `<>
-  {sampleFilesProps.map((extFile:ExtFile) => (
-    <FileMosaic key={extFile.id} {...extFile} info/>
-  ))}
-</>`;
-const completeCodeTS = `import * as React from "react";
-import { FileMosaic, ExtFile } from "../../../files-ui";
+export default DemoFileMosaicValidation;
 
 const sampleFilesProps: ExtFile[] = [
   {
@@ -78,24 +82,14 @@ const sampleFilesProps: ExtFile[] = [
     size: 28 * 1024 * 1024,
     type: "image/png",
     name: "valid file created from props.png",
-    valid: true,
+    valid: false,
+    errors: ["File is too big", "File type is not allowed"]
   },
   {
     id: "fileId-3",
     size: 28 * 1024 * 1024,
     type: "image/jpeg",
     name: "non valid file created from props.jpg",
-    valid: false,
+    valid: true,
   },
-];
-
-const DemoFileMosaicValidation = () => {
-  return (
-    <>
-      {sampleFilesProps.map((extFile: ExtFile) => (
-        <FileMosaic key={extFile.id} {...extFile} info/>
-      ))}
-    </>
-  );
-};
-export default DemoFileMosaicValidation;`;
+];`;
diff --git a/src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx b/src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx
new file mode 100644
index 0000000..565af61
--- /dev/null
+++ b/src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx
@@ -0,0 +1,41 @@
+import * as React from "react";
+import { ExtFile, FileMosaic } from "../../../files-ui";
+
+const sampleFileProps: ExtFile = {
+  id: "fileId",
+  size: 28 * 1024 * 1024,
+  type: "text/plain",
+  name: "file created from props.jsx",
+};
+const DemoFileMosaicDarkMode = () => {
+  const removeFile = (id: string | number | undefined) => {
+    console.log("delete button clicked on file: " + id);
+  };
+  return (
+    <>
+      <div
+        style={{
+          display: "flex",
+          justifyContent: "center",
+          width: "50%",
+          backgroundColor: "white",
+          padding: "10px 0",
+        }}
+      >
+        <FileMosaic {...sampleFileProps} info onDelete={removeFile} />
+      </div>
+      <div
+        style={{
+          display: "flex",
+          justifyContent: "center",
+          width: "50%",
+          backgroundColor: "#121212",
+          padding: "10px 0",
+        }}
+      >
+        <FileMosaic {...sampleFileProps} info darkMode onDelete={removeFile} />
+      </div>
+    </>
+  );
+};
+export default DemoFileMosaicDarkMode;
diff --git a/src/components/demo-components/filemosaic-demo/DemoFileMosaicFileIcons.jsx b/src/components/demo-components/filemosaic-demo/DemoFileMosaicFileIcons.jsx
new file mode 100644
index 0000000..3432c4c
--- /dev/null
+++ b/src/components/demo-components/filemosaic-demo/DemoFileMosaicFileIcons.jsx
@@ -0,0 +1,37 @@
+import * as React from "react";
+import { FileMosaic,createListOfMultiTypeFile } from "../../../files-ui";
+
+/* const sampleFileProps = {
+  id: "fileId",
+  size: 28 * 1024 * 1024,
+  type: "text/plain",
+  name: "file created from props.jsx",
+}; */
+const DemoFileMosaicFileIcons = () => {
+  const [files, setFiles] = React.useState([]);
+
+  const removeFile = (id) => {
+    console.log("delete button clicked on file: " + id);
+  };
+
+  React.useEffect(() => {
+    const validateFiles = createListOfMultiTypeFile(28*1024*1024).map((x, index) => {
+      return {
+        id:index,
+        size: 28 * 1024 * 1024,
+        type: x.type,
+        name: x.name,
+      };
+    });
+    //console.log(validateFiles);
+    setFiles(validateFiles);
+  }, []);
+  return (
+    <>
+      {files.map((f, index) => (
+        <FileMosaic {...f} key={f.id} onDelete={removeFile} info />
+      ))}
+    </>
+  );
+};
+export default DemoFileMosaicFileIcons;
diff --git a/src/components/demo-components/filemosaic-demo/DemoFileMosaicLocalization.tsx b/src/components/demo-components/filemosaic-demo/DemoFileMosaicLocalization.tsx
new file mode 100644
index 0000000..6354a3d
--- /dev/null
+++ b/src/components/demo-components/filemosaic-demo/DemoFileMosaicLocalization.tsx
@@ -0,0 +1,126 @@
+import * as React from "react";
+import { ExtFile, FileMosaic, Localization } from "../../../files-ui";
+import { Autocomplete, TextField } from "@mui/material";
+
+const DemoFileMosaicLocalization = () => {
+  const [localization, setLocalization] = React.useState<
+    Localization | undefined
+  >(undefined);
+
+  const hadleSelect = (value: LanguageItem | null) => {
+    console.log(value);
+    setLocalization(value?.value);
+  };
+
+  return (
+    <>
+      <Autocomplete
+        disablePortal
+        autoSelect
+        size="small"
+        onChange={(e, value) => hadleSelect(value as LanguageItem)}
+        id="combo-box-demo"
+        options={languages}
+        sx={{ width: 300 }}
+        getOptionLabel={(option) => option.language}
+        renderInput={(params) => <TextField {...params} label="Localization" />}
+      />
+      <div
+        style={{
+          display: "flex",
+          flexWrap: "wrap",
+          justifyContent: "space-evenly",
+          width: "100%",
+          gap: "50px",
+        }}
+      >
+        {extFiles.map((extFile, index) => (
+          <FileMosaic
+            key={index}
+            {...extFile}
+            localization={localization}
+            onDelete={() => {}}
+            info
+          />
+        ))}
+      </div>
+    </>
+  );
+};
+export default DemoFileMosaicLocalization;
+
+interface LanguageItem {
+  language: string;
+  value: Localization;
+}
+
+const languages = [
+  { language: "Español: ES-es", value: "ES-es" },
+  { language: "English: EN-en", value: "EN-en" },
+  { language: "French: FR-fr", value: "FR-fr" },
+  { language: "Italian: IT-it", value: "IT-it" },
+  { language: "Portuguese: PT-pt", value: "PT-pt" },
+  { language: "Russian: RU-ru", value: "RU-ru" },
+  { language: "Chinese(simplified): ZH-cn", value: "ZH-cn" },
+  { language: "Chinese(traditional): ZH-hk", value: "ZH-hk" },
+];
+const extFiles: ExtFile[] = [
+  {
+    id: 0,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    errors: ["pdf not allowed", "file is too big"],
+  },
+  {
+    id: 1,
+    valid: false,
+    name: "file_localization.docx",
+
+    size: 28 * 1024,
+    errors: ["pdf not allowed", "file is too big"],
+  },
+  {
+    id: 2,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+  },
+  {
+    id: 3,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "preparing",
+  },
+  {
+    id: 4,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "uploading",
+    progress: 28,
+  },
+  {
+    id: 5,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "aborted",
+    uploadMessage: "Upload was aborted",
+  },
+  {
+    id: 6,
+    valid: false,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "error",
+    uploadMessage: "there was an error on the server",
+  },
+  {
+    id: 7,
+    valid: true,
+    name: "file_localization.docx",
+    size: 28 * 1024,
+    uploadStatus: "success",
+    uploadMessage: "files-ui <3",
+  },
+];
diff --git a/src/components/demo-components/filemosaic-demo/DemoFileMosaicUploadStatus.tsx b/src/components/demo-components/filemosaic-demo/DemoFileMosaicUploadStatus.tsx
index 4763b93..ed044df 100644
--- a/src/components/demo-components/filemosaic-demo/DemoFileMosaicUploadStatus.tsx
+++ b/src/components/demo-components/filemosaic-demo/DemoFileMosaicUploadStatus.tsx
@@ -1,196 +1,128 @@
 import * as React from "react";
-import { FileMosaic } from "../../../files-ui";
-import { ExtFile, getRandomInt, UPLOADSTATUS } from "../../../files-ui/core";
-const preparingFiles: ExtFile[] = [
-  {
-    id: "fileId-1",
-    size: 28 * 1024 * 1024,
-    type: "text/plain",
-    name: "default preparing file.jsx",
-    uploadStatus: "preparing",
-  },
-  {
-    id: "fileId-2",
-    size: 28 * 1024 * 1024,
-    type: "text/plain",
-    name: "preparing file that can be stopped.jsx",
-    uploadStatus: "preparing",
-  },
-];
-const uploadingFiles: ExtFile[] = [
-  {
-    size: 28 * 1024 * 1024,
-    type: "image/png",
-    name: "non abortable with no specific progress.png",
-    valid: true,
-    uploadStatus: "uploading",
-  },
-  {
-    size: 28 * 1024 * 1024,
-    type: "image/png",
-    name: "non abortable with specific progress.png",
-    valid: true,
-    uploadStatus: "uploading",
-    progress: 56,
-  },
-  {
-    size: 28 * 1024 * 1024,
-    type: "image/png",
-    name: "abortable with no specific progress.png",
-    valid: true,
-    uploadStatus: "uploading",
-  },
-  {
-    size: 28 * 1024 * 1024,
-    type: "image/png",
-    name: "abortable with specific progress.png",
-    valid: true,
-    uploadStatus: "uploading",
-    progress: 56,
-  },
-];
-const uploadResulFiles: ExtFile[] = [
-  {
-    size: 28 * 1024 * 1024,
-    type: "image/gif",
-    name: "non valid file created from props.gif",
-    //uploadStatus: "aborted",
-    uploadMessage: "Upload was aborted by the user",
-  },
-  {
-    size: 28 * 1024 * 1024,
-    type: "image/jpeg",
-    name: "non valid file created from props.jpg",
-    //uploadStatus: "error",
-    uploadMessage:
-      "File couldn't be uploaded to Files-ui earthquakes. File was too big.",
-  },
-  {
-    size: 28 * 1024 * 1024,
-    type: "image/png",
-    name: "non valid file created from props.png",
-    //uploadStatus: "success",
-    uploadMessage: "File was uploaded correctly to Files-ui earthquakes",
-  },
-];
+import {
+  FileMosaic,
+  useFakeProgress,
+  ExtFile,
+  UPLOADSTATUS,
+} from "../../../files-ui";
 
-const FlexRowContainer = (props: { children: React.ReactNode }) => {
-  return (
-    <div
-      style={{
-        display: "flex",
-        flexWrap: "wrap",
-        justifyContent: "space-evenly",
-        width: "100%",
-      }}
-    >
-      {props.children}
-    </div>
-  );
-};
 const DemoFileMosaicUploadStatus = () => {
-  const [progress, setProgress] = React.useState(28);
-  const [progress2, setProgress2] = React.useState(28);
-  const [status1, setStatus1] = React.useState<UPLOADSTATUS | undefined>(
-    "uploading"
-  );
-  const [status2, setStatus2] = React.useState<UPLOADSTATUS | undefined>(
-    "uploading"
-  );
-  const [status3, setStatus3] = React.useState<UPLOADSTATUS | undefined>(
-    "uploading"
-  );
+  const progress = useFakeProgress();
+
+  const [status1, setStatus1] = React.useState<UPLOADSTATUS>("uploading");
+  const [status2, setStatus2] = React.useState<UPLOADSTATUS>("uploading");
+  const [status3, setStatus3] = React.useState<UPLOADSTATUS>("uploading");
 
   React.useEffect(() => {
-    const _myInterval2 = setInterval(() => {
+    //schedule an interval
+    const _myInterval = setInterval(() => {
       //set the uploadstatus result
       setStatus1((_status) => setNextUploadState(_status, "aborted"));
       setStatus2((_status) => setNextUploadState(_status, "error"));
       setStatus3((_status) => setNextUploadState(_status, "success"));
     }, 5000);
-    const _myInterval = setInterval(() => {
-      setProgress((_progress) => {
-        if (_progress === 100) {
-          return 0;
-        }
-        const offset = getRandomInt(5, 14);
-        const newProgress = _progress + offset;
-        if (newProgress > 100) {
-          return 100;
-        } else {
-          return newProgress;
-        }
-      });
-      setProgress2((_progress) => {
-        if (_progress === 100) {
-          return 0;
-        }
-        const offset = getRandomInt(10, 24);
-        const newProgress = _progress + offset;
-        if (newProgress > 100) {
-          return 100;
-        } else {
-          return newProgress;
-        }
-      });
-    }, 2000);
 
+    //clean
     return () => {
       console.log("clear interval", _myInterval);
-      console.log("clear interval", _myInterval2);
       clearInterval(_myInterval as NodeJS.Timer);
-      clearInterval(_myInterval2 as NodeJS.Timer);
     };
   }, []);
+
+  const handleCancel = (id: string | number | undefined) => {
+    console.log("Upload canceled in file: " + id);
+  };
+  const handleAbort = (id: string | number | undefined) => {
+    console.log("Upload aborted in file: " + id);
+  };
   return (
     <>
       <FlexRowContainer>
-        <FileMosaic {...preparingFiles[0]} />
-        <FileMosaic {...preparingFiles[1]} onCancel={() => {}} />
+        <FileMosaic {...preparingFile} />
+        <FileMosaic {...preparingFile} onCancel={handleCancel} />
       </FlexRowContainer>
 
       <FlexRowContainer>
-        <FileMosaic {...uploadingFiles[0]} />
-        <FileMosaic {...uploadingFiles[0]} progress={progress} />
-        <FileMosaic {...uploadingFiles[2]} onAbort={() => {}} />
+        <FileMosaic {...uploadingFile} />
+        <FileMosaic {...uploadingFile} progress={progress} />
+        <FileMosaic {...uploadingFile} onAbort={handleAbort} />
         <FileMosaic
-          {...uploadingFiles[3]}
-          onAbort={() => {}}
-          progress={progress2}
+          {...uploadingFile}
+          onAbort={handleAbort}
+          progress={progress}
         />
       </FlexRowContainer>
 
       <FlexRowContainer>
-        <FileMosaic
-          {...uploadResulFiles[0]}
-          resultOnTooltip
-          uploadStatus={status1}
-        />
-        <FileMosaic
-          {...uploadResulFiles[1]}
-          resultOnTooltip
-          uploadStatus={status2}
-        />
-        <FileMosaic
-          {...uploadResulFiles[2]}
-          resultOnTooltip
-          uploadStatus={status3}
-        />
+        <FileMosaic {...uploadResultFiles[0]} uploadStatus={status1} />
+        <FileMosaic {...uploadResultFiles[1]} uploadStatus={status2} />
+        <FileMosaic {...uploadResultFiles[2]} uploadStatus={status3} />
       </FlexRowContainer>
     </>
   );
 };
 export default DemoFileMosaicUploadStatus;
 
+const FlexRowContainer = (props: { children: React.ReactNode }) => {
+  return (
+    <div
+      style={{
+        display: "flex",
+        flexWrap: "wrap",
+        justifyContent: "space-evenly",
+        width: "100%",
+      }}
+    >
+      {props.children}
+    </div>
+  );
+};
+
 const setNextUploadState = (
-  prevState: UPLOADSTATUS | undefined,
-  nextStatus: UPLOADSTATUS | undefined
-): UPLOADSTATUS | undefined => {
-  if (prevState === "uploading") {
-    return nextStatus;
-  } else if (prevState === nextStatus) {
-    return undefined;
-  } else {
-    return "uploading";
-  }
+  prevState: UPLOADSTATUS,
+  nextStatus: UPLOADSTATUS
+): UPLOADSTATUS => {
+  if (prevState === "uploading") return nextStatus;
+  else return "uploading";
+};
+
+const preparingFile: ExtFile = {
+  id: "fileId-0",
+  size: 28 * 1024 * 1024,
+  type: "text/plain",
+  name: "preparing file.jsx",
+  uploadStatus: "preparing",
+};
+
+const uploadingFile: ExtFile = {
+  id: "fileId-1",
+  size: 28 * 1024 * 1024,
+  type: "image/png",
+  name: "uploading file.png",
+  uploadStatus: "uploading",
 };
+
+const uploadResultFiles: ExtFile[] = [
+  {
+    id: "fileId-2",
+    size: 28 * 1024 * 1024,
+    type: "image/gif",
+    name: "upload aborted file.gif",
+    uploadMessage: "Upload was aborted by the user",
+  },
+  {
+    id: "fileId-3",
+    size: 28 * 1024 * 1024,
+    type: "image/jpeg",
+    name: "upload with error file.jpg",
+    uploadMessage:
+      "File couldn't be uploaded to Files-ui earthquakes. File was too big.",
+  },
+  {
+    id: "fileId-4",
+    size: 28 * 1024 * 1024,
+    type: "image/png",
+    name: "successfully uploaded file.png",
+    uploadMessage: "File was uploaded correctly to Files-ui earthquakes",
+  },
+];
diff --git a/src/components/demo-components/filemosaic-demo/DemoFileMosaicValidation.jsx b/src/components/demo-components/filemosaic-demo/DemoFileMosaicValidation.jsx
index 9b23115..0c3d1a9 100644
--- a/src/components/demo-components/filemosaic-demo/DemoFileMosaicValidation.jsx
+++ b/src/components/demo-components/filemosaic-demo/DemoFileMosaicValidation.jsx
@@ -14,6 +14,7 @@ const sampleFilesProps = [
     type: "image/png",
     name: "valid file created from props.png",
     valid: false,
+    errors: ["File is too big", "File type is not allowed"]
   },
   {
     id: "fileId-3",
@@ -28,7 +29,7 @@ const DemoFileMosaicValidation = () => {
   return (
     <>
       {sampleFilesProps.map((extFile) => (
-        <FileMosaic key={extFile.id} {...extFile} alwaysActive info preview />
+        <FileMosaic key={extFile.id} {...extFile} info />
       ))}
     </>
   );
diff --git a/src/components/show-demo-code/ShowDemoCode.tsx b/src/components/show-demo-code/ShowDemoCode.tsx
index 6920473..5de73c8 100644
--- a/src/components/show-demo-code/ShowDemoCode.tsx
+++ b/src/components/show-demo-code/ShowDemoCode.tsx
@@ -13,22 +13,24 @@ interface ShowDemoCodeProps {
   codeSplittedTS?: string;
   codeCompleteJS?: string;
   codeCompleteTS?: string;
-  splittedOnly?:boolean;
+  splittedOnly?: boolean;
 }
-const ShowDemoCode: React.FC<ShowDemoCodeProps> = (props: ShowDemoCodeProps) => {
+const ShowDemoCode: React.FC<ShowDemoCodeProps> = (
+  props: ShowDemoCodeProps
+) => {
   const {
     codeSandboxJS = "https://codesandbox.io/s/dropzone-ui-basic-3j01v",
     codeSandboxTS = "https://codesandbox.io/s/dropzone-ui-basic-3j01v",
-    codeCompleteJS,
-    codeCompleteTS,
-    codeSplittedJS,
-    codeSplittedTS,
-    splittedOnly=false
+    codeCompleteJS = "",
+    codeCompleteTS = "",
+    codeSplittedJS = "",
+    codeSplittedTS = "",
+    splittedOnly = false,
   } = props;
   const [showComplete, setShowComplete] = React.useState(false);
   const [showJS, setShowJS] = React.useState(true);
 
-  const code = showComplete
+  const code: string = showComplete
     ? showJS
       ? codeCompleteJS
       : codeCompleteTS
@@ -38,61 +40,73 @@ const ShowDemoCode: React.FC<ShowDemoCodeProps> = (props: ShowDemoCodeProps) =>
 
   return (
     <React.Fragment>
-     {!splittedOnly && <Stack
-        direction={"row"}
-        justifyContent="space-between"
-        style={{ marginTop: "20px" }}
-      >
-        <Stack direction={"row"} justifyContent="flex-start">
-          <ButtonGroup variant="outlined" aria-label="outlined button group">
-            <Button
-              size="small"
-              style={showJS ? { backgroundColor: "rgba(4, 35, 84, 0.09)" } : {}}
-              //startIcon={}
-              onClick={() => setShowJS(true)}
-            >
-              <JSIcon />
-            </Button>
-            <Button
-              size="small"
-              style={
-                !showJS ? { backgroundColor: "rgba(4, 35, 84, 0.09)" } : {}
-              }
-              //  endIcon={}
-              onClick={() => setShowJS(false)}
-            >
-              <TSIcon />
-            </Button>
-          </ButtonGroup>
-        </Stack>
+      {!splittedOnly && (
+        <Stack
+          direction={"row"}
+          justifyContent="space-between"
+          style={{ margin: "20px 0" }}
+        >
+          <Stack direction={"row"} justifyContent="flex-start">
+            {code.length > 0 && (
+              <ButtonGroup
+                variant="outlined"
+                aria-label="outlined button group"
+              >
+                <Button
+                  size="small"
+                  style={
+                    showJS ? { backgroundColor: "rgba(4, 35, 84, 0.09)" } : {}
+                  }
+                  //startIcon={}
+                  onClick={() => setShowJS(true)}
+                >
+                  <JSIcon />
+                </Button>
+                <Button
+                  size="small"
+                  style={
+                    !showJS ? { backgroundColor: "rgba(4, 35, 84, 0.09)" } : {}
+                  }
+                  //  endIcon={}
+                  onClick={() => setShowJS(false)}
+                >
+                  <TSIcon />
+                </Button>
+              </ButtonGroup>
+            )}
+          </Stack>
 
-        <Stack direction={"row"} justifyContent="flex-end">
-          <Tooltip title={showComplete ? "Hide full code" : "Show full code"}>
-            <IconButton
-              style={{ borderRadius: "50%", border: "0.5px solid #eaeef3" }}
-              onClick={() => setShowComplete((showComplete) => !showComplete)}
-              //color="secondary"
-              aria-label="upload picture"
-              component="label"
-            >
-              <CodeIcon /* htmlColor="white" */ />
-            </IconButton>
-          </Tooltip>
-          <Tooltip title={"Edit in CodeSandBox"}>
-            <IconButton
-              style={{ borderRadius: "50%", border: "0.5px solid #eaeef3" }}
-              onClick={() => {
-                window?.open(showJS ? codeSandboxJS : codeSandboxTS, "_blank");
-              }}
-              //color="secondary"
-              aria-label="upload picture"
-              component="label"
-            >
-              <ViewInArIcon /* htmlColor="white" */ />
-            </IconButton>
-          </Tooltip>
+          <Stack direction={"row"} justifyContent="flex-end" spacing={1}>
+            <Tooltip title={showComplete ? "Hide full code" : "Show full code"}>
+              <IconButton
+                style={{ borderRadius: "50%", border: "0.5px solid #eaeef3" }}
+                onClick={() => setShowComplete((showComplete) => !showComplete)}
+                //color="secondary"
+                aria-label="upload picture"
+                component="label"
+              >
+                <CodeIcon /* htmlColor="white" */ />
+              </IconButton>
+            </Tooltip>
+            <Tooltip title={"Edit in CodeSandBox"}>
+              <IconButton
+                style={{ borderRadius: "50%", border: "0.5px solid #eaeef3" }}
+                onClick={() => {
+                  window?.open(
+                    showJS ? codeSandboxJS : codeSandboxTS,
+                    "_blank"
+                  );
+                }}
+                //color="secondary"
+                aria-label="upload picture"
+                component="label"
+              >
+                <ViewInArIcon /* htmlColor="white" */ />
+              </IconButton>
+            </Tooltip>
+          </Stack>
         </Stack>
-      </Stack>}
+      )}
       <Highlighter
         onCopyToClipboard={(code_) => {
           console.log("code copied to clipboard: ");
diff --git a/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx b/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx
index 7de77ce..0ce3160 100644
--- a/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx
+++ b/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx
@@ -43,7 +43,7 @@ const FileMosaic: React.FC<FileMosaicProps> = (props: FileMosaicProps) => {
 
     alwaysActive = true,
 
-    resultOnTooltip,
+    resultOnTooltip = true,
 
     downloadUrl,
 
diff --git a/src/files-ui/hooks/index.ts b/src/files-ui/hooks/index.ts
index f3cc8be..2125e76 100644
--- a/src/files-ui/hooks/index.ts
+++ b/src/files-ui/hooks/index.ts
@@ -1,2 +1,5 @@
 import {useDropzoneValidation} from "./useDropzoneValidation";
-export {useDropzoneValidation};
\ No newline at end of file
+export {useDropzoneValidation};
+
+
+export {useFakeProgress} from "./useFakeProgress";
\ No newline at end of file
diff --git a/src/files-ui/hooks/useFakeProgress.ts b/src/files-ui/hooks/useFakeProgress.ts
new file mode 100644
index 0000000..9660e29
--- /dev/null
+++ b/src/files-ui/hooks/useFakeProgress.ts
@@ -0,0 +1,38 @@
+import * as React from "react";
+import { getRandomInt } from "../core";
+
+export const useFakeProgress = (time = 1500) => {
+    const [progress, setProgress] = React.useState(28);
+
+    React.useEffect(() => {
+
+        const updateProgress = (currProgress: number): number => {
+            if (currProgress === 100) {
+                return 0;
+            }
+            const offset = getRandomInt(5, 24);
+
+            const newProgress = currProgress + offset;
+            if (newProgress > 100) {
+                return 100;
+            } else {
+                return newProgress;
+            }
+        };
+
+        const _myInterval = setInterval(() => {
+            setProgress((_progress) => updateProgress(_progress));
+        }, time);
+        console.log("useFakeProgress SET interval", _myInterval);
+
+        return () => {
+            console.log("useFakeProgress CLEAR interval", _myInterval);
+            clearInterval(_myInterval as NodeJS.Timer);
+        };
+        // eslint-disable-next-line
+    }, []);
+
+    return progress;
+}
+
+
diff --git a/src/files-ui/index.ts b/src/files-ui/index.ts
index bcd99d8..b158ee2 100644
--- a/src/files-ui/index.ts
+++ b/src/files-ui/index.ts
@@ -21,4 +21,10 @@ export { ImagePreview } from "./components/previews";
 export * from "./components/previews";
 
 export { VideoPreview } from "./components/previews";
-export * from "./components/previews";
\ No newline at end of file
+export * from "./components/previews";
+
+export { useFakeProgress } from "./hooks";
+
+
+export {createListOfMultiTypeFile} from "./core";
+export type { ExtFile, ExtFileInstance, ExtFileListMap, ExtFileManager, UPLOADSTATUS, Localization } from "./core";
\ No newline at end of file
diff --git a/src/pages/demo/FileMosaicDemoPage.jsx b/src/pages/demo/FileMosaicDemoPage.jsx
index 5d5d253..c203bff 100644
--- a/src/pages/demo/FileMosaicDemoPage.jsx
+++ b/src/pages/demo/FileMosaicDemoPage.jsx
@@ -1,6 +1,5 @@
 import Alert from "@mui/material/Alert";
 import Paper from "@mui/material/Paper";
-import Stack from "@mui/material/Stack";
 import AlertTitle from "@mui/material/AlertTitle";
 import * as React from "react";
 import CodeHighlight from "../../components/codeHighlight/CodeHighlight";
@@ -23,6 +22,11 @@ import CodeJSFileMosaicValidation from "../../components/demo-components/filemos
 import DemoFileMosaicValidation from "../../components/demo-components/filemosaic-demo/DemoFileMosaicValidation";
 import CodeJSFileMosaicUploadStatus from "../../components/demo-components/filemosaic-demo/CodeJSFileMosaicUploadStatus";
 import DemoFileMosaicUploadStatus from "../../components/demo-components/filemosaic-demo/DemoFileMosaicUploadStatus";
+import DemoFileMosaicLocalization from "../../components/demo-components/filemosaic-demo/DemoFileMosaicLocalization";
+import CodeJSFileMosaicLocalization from "../../components/demo-components/filemosaic-demo/CodeJSFileMosaicLocalization";
+import DemoFileMosaicDarkMode from "../../components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode";
+import CodeJSFileMosaicDarkMode from "../../components/demo-components/filemosaic-demo/CodeJSFileMosaicDarkMode";
+import DemoFileMosaicFileIcons from "../../components/demo-components/filemosaic-demo/DemoFileMosaicFileIcons";
 
 const FileMosaicDemoPage = (props) => {
   return (
@@ -92,7 +96,7 @@ const FileMosaicDemoPage = (props) => {
           <DescParagraph>
             By setting the <CodeHighlight>preview</CodeHighlight> prop to{" "}
             <TypeHighlight>true</TypeHighlight> the component will show an image
-            preview instead of a file icons. To acomplish this task this
+            preview instead of a file icon. To acomplish this task this
             component will take the <CodeHighlight>imageUrl</CodeHighlight>
             prop or will read the <TypeHighlight>File</TypeHighlight> object if
             given and if it is an image.
@@ -160,7 +164,7 @@ const FileMosaicDemoPage = (props) => {
             <TypeHighlight>"error"</TypeHighlight> or{" "}
             <TypeHighlight>"success"</TypeHighlight>. Also the{" "}
             <CodeHighlight>uploadMessage</CodeHighlight> prop is used for
-            displaying the error or success message and the{" "}
+            displaying the error or success message. Finally, the{" "}
             <CodeHighlight>progress</CodeHighlight> prop can be used to show the
             current progress of the upload process.
             <br />
@@ -188,8 +192,7 @@ const FileMosaicDemoPage = (props) => {
             As you can see, you have full control of the FileMosaic upload
             props. You can take advantage of them to ake your own upload
             function and show the user the progress.
-            <br />{" "}
-            On the other hand, you can also leverage the capability of{" "}
+            <br /> On the other hand, you can also leverage the capability of{" "}
             <CodeHighlight>{"<Dropzone/>"}</CodeHighlight> and{" "}
             <CodeHighlight>{"<FileInputButton/>"}</CodeHighlight> components
             since they also manage the{" "}
@@ -198,18 +201,109 @@ const FileMosaicDemoPage = (props) => {
             mentioned in the following demos:
             <ul>
               <li>
-                <AnchorToTab href="/components/dropzone#">
+                <AnchorToTab href="/components/dropzone#uploading">
                   Dropzone upload
                 </AnchorToTab>
               </li>
               <li>
-                <AnchorToTab href="/components/fileinputbutton#validation">
+                <AnchorToTab href="/components/fileinputbutton#uploading">
                   FileInputButton upload
                 </AnchorToTab>
               </li>
             </ul>
           </Alert>
         </section>
+        <section id="dark mode">
+          <SubTitle content="Dark mode" />
+          <DescParagraph>
+            The <CodeHighlight>FileMosaic</CodeHighlight> component supports
+            dark mode by setting the prop{" "}
+            <TypeHighlight>darkMode</TypeHighlight> to{" "}
+            <TypeHighlight>true</TypeHighlight>.
+          </DescParagraph>
+
+          <Paper
+            variant="outlined"
+            style={{
+              padding: "25px",
+              display: "flex",
+              alignItems: "center",
+              justifyContent: "center",
+              width: "100%",
+            }}
+          >
+            <DemoFileMosaicDarkMode />
+          </Paper>
+
+          <CodeJSFileMosaicDarkMode />
+        </section>
+        <section id="localization">
+          <SubTitle content="Localization" />
+          <DescParagraph>
+            The <CodeHighlight>FileMosaic</CodeHighlight> component has
+            multilanguage support. You can change the language in wich labels
+            are displayed by setting the{" "}
+            <CodeHighlight>{"localization"}</CodeHighlight> prop. So far only
+            the following languages are supported:
+            <ul>
+              <li>
+                <TypeHighlight>English</TypeHighlight>
+              </li>
+              <li>
+                <TypeHighlight>Spanish</TypeHighlight>
+              </li>
+              <li>
+                <TypeHighlight>French</TypeHighlight>
+              </li>
+              <li>
+                <TypeHighlight>Italian</TypeHighlight>
+              </li>
+              <li>
+                <TypeHighlight>Portuguese</TypeHighlight>
+              </li>
+              <li>
+                <TypeHighlight>Russian</TypeHighlight>
+              </li>
+              <li>
+                <TypeHighlight>Chinnese (simplified)</TypeHighlight>
+              </li>
+              <li>
+                <TypeHighlight>Chinnese (traditional)</TypeHighlight>
+              </li>
+            </ul>
+          </DescParagraph>
+
+          <Paper
+            variant="outlined"
+            style={{
+              padding: "25px",
+              display: "flex",
+              alignItems: "center",
+              justifyContent: "center",
+              flexDirection: "column",
+              gap: "20px",
+            }}
+          >
+            <DemoFileMosaicLocalization />
+          </Paper>
+
+          <CodeJSFileMosaicLocalization />
+        </section>
+
+        <section id="file icon">
+          <SubTitle content="File Icons (extensive list)" />
+          <DescParagraph>
+            The <CodeHighlight>FileMosaic</CodeHighlight> component supports
+            aseveral file types to properly set a file icon. The complete list of file icons is the following:
+          </DescParagraph>
+
+          <DemoContainerFileMosaic
+          >
+            <DemoFileMosaicFileIcons />
+          </DemoContainerFileMosaic>
+
+        
+        </section>
       </MainContentContainer>
       <RightMenuContainer>
         <RightMenu width="240px" items={rightMenuItems} />
-- 
GitLab