From 439d17dbe38becc81221edf1afc337f251864641 Mon Sep 17 00:00:00 2001
From: Jose Manuel Serrano Amaut <a20122128@pucp.pe>
Date: Wed, 8 Mar 2023 13:51:57 -0500
Subject: [PATCH] [WIP]: Add FileCard Component, add upload layer, info layer,
 improve the close info button and tooltip for file card. Refactor FIle
 CardDemoPage darkmode section to wrap flex forw and minwidth

---
 .../DemoFileMosaicDarkMode.tsx                |  14 ++-
 .../components/file-card/FileCard.scss        |  18 ++-
 .../components/file-card/FileCard.tsx         |  95 +++++++-------
 .../components/FileCardInfoLayer.tsx          |  15 ++-
 .../components/FileCardUploadLayer.scss       |  44 +++++++
 .../components/FileCardUploadLayer.tsx        | 119 ++++++++++++++++++
 .../FileMosaicInfoLayer.tsx                   |   2 +-
 .../FileMosaicStatus/FileMosaicStatus.tsx     |  10 +-
 .../FileMosaicStatus/FileMosaicStatusProps.ts |   3 +
 .../components/file-mosaic/FileMosaic.scss    |  66 ----------
 .../components/file-status/ErrorStatus.tsx    |   2 +-
 .../tooltip/components/Tooltip.scss           |  61 +++++++++
 src/pages/demo/FileCardDemoPage.jsx           |   1 +
 13 files changed, 318 insertions(+), 132 deletions(-)
 create mode 100644 src/files-ui/components/file-card/components/FileCardUploadLayer.scss
 create mode 100644 src/files-ui/components/file-card/components/FileCardUploadLayer.tsx

diff --git a/src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx b/src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx
index a65af22..e1cbbec 100644
--- a/src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx
+++ b/src/components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode.tsx
@@ -6,6 +6,7 @@ const sampleFileProps: ExtFile = {
   size: 28 * 1024 * 1024,
   type: "text/plain",
   name: "file created from props.jsx",
+  valid: true,
 };
 const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
   const removeFile = (id: string | number | undefined) => {
@@ -18,9 +19,10 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
           style={{
             display: "flex",
             justifyContent: "center",
-            width: "50%",
+            minWidth: "50%",
             backgroundColor: "white",
             padding: "15px 0",
+            flexGrow:1
           }}
         >
           <FileCard {...sampleFileProps} info onDelete={removeFile} />
@@ -29,9 +31,10 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
           style={{
             display: "flex",
             justifyContent: "center",
-            width: "50%",
+            minWidth: "50%",
             backgroundColor: "#121212",
             padding: "15px 0",
+            flexGrow: 1,
           }}
         >
           <FileCard {...sampleFileProps} info darkMode onDelete={removeFile} />
@@ -44,9 +47,10 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
         style={{
           display: "flex",
           justifyContent: "center",
-          width: "50%",
+          minWidth: "50%",
           backgroundColor: "white",
           padding: "15px 0",
+          flexGrow: 1,
         }}
       >
         <FileMosaic {...sampleFileProps} info onDelete={removeFile} />
@@ -55,9 +59,11 @@ const DemoFileMosaicDarkMode = (props: { card?: boolean }) => {
         style={{
           display: "flex",
           justifyContent: "center",
-          width: "50%",
+          minWidth: "50%",
           backgroundColor: "#121212",
           padding: "15px 0",
+          flexGrow: 1,
+
         }}
       >
         <FileMosaic {...sampleFileProps} info darkMode onDelete={removeFile} />
diff --git a/src/files-ui/components/file-card/FileCard.scss b/src/files-ui/components/file-card/FileCard.scss
index 51b3b7d..0475dca 100644
--- a/src/files-ui/components/file-card/FileCard.scss
+++ b/src/files-ui/components/file-card/FileCard.scss
@@ -1,7 +1,7 @@
 @import url(https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700,900);
 .files-ui-file-card-main-container {
   border-radius: 8px;
-  overflow: hidden;
+  //overflow: hidden;
   color: rgba(0, 0, 0, 0.858);
   display: flex;
   flex-direction: row;
@@ -14,6 +14,8 @@
   font-weight: 400;
   width: 350px;
   .files-ui-file-card-main-layer-container {
+    border-radius: 8px;
+    overflow: hidden;
     width: 380px;
     box-sizing: border-box;
     height: 100px;
@@ -74,6 +76,13 @@
               }
             }
           }
+          .file-card-status-layer {
+            display: flex;
+            align-items: flex-end;
+            justify-content: flex-start;
+            padding: 5px;
+            box-sizing: border-box;
+          }
         }
         .file-card-data {
           line-height: 18px;
@@ -124,7 +133,7 @@
       //background-color: aquamarine;
       height: 100%;
     }
-    .file-card-upload-layer {
+    .file-card-upload-layer-container {
       display: flex;
       box-sizing: border-box;
       //background-color: rgba(0, 0, 0, 0.5);
@@ -147,6 +156,7 @@
       overflow: hidden;
       align-items: center;
       justify-content: flex-end;
+      height: 100%;
     }
     .file-card-info-layer-container {
       display: flex;
@@ -178,6 +188,7 @@
         scrollbar-width: thin;
         overflow: auto;
         scrollbar-color: #646c7fa9 transparent;
+       // position: relative;
 
         &::-webkit-scrollbar {
           width: 9px;
@@ -196,6 +207,9 @@
           flex-direction: row;
           align-items: center;
           justify-content: flex-end;
+         /*  position: absolute;
+          top: 5;
+          right: 5; */
         }
         .heading {
           font-weight: 600;
diff --git a/src/files-ui/components/file-card/FileCard.tsx b/src/files-ui/components/file-card/FileCard.tsx
index 7e19259..bb64438 100644
--- a/src/files-ui/components/file-card/FileCard.tsx
+++ b/src/files-ui/components/file-card/FileCard.tsx
@@ -12,6 +12,9 @@ import Layer from "../file-mosaic/components/file-mosaic-layer/Layer";
 import FileMosaicImageLayer from "../file-mosaic/components/FIleMosaicImageLayer/FileMosaicImageLayer";
 import FileCardRightLayer from "./components/FileCardRightLayer";
 import FileCardInfoLayer from "./components/FileCardInfoLayer";
+import FileMosaicStatus from "../file-mosaic/components/FileMosaicStatus/FileMosaicStatus";
+import FileCardUploadLayer from "./components/FileCardUploadLayer";
+import { Tooltip } from "../tooltip";
 
 const setFinalElevation = (elevation: string | number): number => {
   //  let finalElevation: number  = "";
@@ -35,7 +38,8 @@ const makeFileCardClassName = (
   className: string | undefined
 ): string => {
   console.log("FileCard makeFileCardClassName", elevation, darkMode, className);
-  let finalClassName: string = "files-ui-file-card-main-container";
+  let finalClassName: string = "files-ui-file-card-main-container files-ui-tooltip card";
+
   if (elevation) {
     finalClassName += " elevation-" + setFinalElevation(elevation);
   }
@@ -247,6 +251,7 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
         >
           <Layer className="file-card-main-layer" visible={true}>
             <div className="file-card-icon-plus-data">
+              {/** ICON + STATUS */}
               <div className="file-card-icon-container">
                 <LayerContainer className="file-card-icon-layer">
                   {/** IMAGE LAYER BLUR */}
@@ -270,19 +275,22 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
                       isBlur={false}
                     />
                   </Layer>
+                  <Layer className="file-card-status-layer" visible={true}>
+                    <FileMosaicStatus
+                      valid={valid}
+                      uploadStatus={uploadStatus}
+                      localization={localization}
+                    />
+                  </Layer>
                 </LayerContainer>
               </div>
-
+              {/**  DATA  */}
               <div
                 className={
                   darkMode ? "file-card-data dark-mode" : "file-card-data"
                 }
               >
-                <div className={"file-card-name"}>
-                  {/* {shrinkWord(localName, true)} */}
-                  {localName}
-                </div>
-
+                <div className={"file-card-name"}>{localName}</div>
                 <div className={"file-card-size"}>{sizeFormatted}</div>
                 <div className={"file-card-size"}>{shrinkWord(localType)}</div>
               </div>
@@ -313,6 +321,7 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
               isActive={alwaysActive || hovering}
             />
           </Layer>
+
           <Layer className="file-card-info-layer-container" visible={showInfo}>
             <FileCardInfoLayer
               onCloseInfo={handleCloseInfo}
@@ -323,47 +332,43 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
               localType={localType}
             />
           </Layer>
-          <Layer className="file-card-upload-layer" visible={isUploading}>
-            Upload Layer
+
+          {/** UPLOAD LAYER */}
+          <Layer
+            className="file-card-upload-layer-container"
+            visible={isUploading}
+          >
+            <div className="files-ui-file-card-upload-layer">
+              <FileCardUploadLayer
+                uploadStatus={uploadStatus}
+                progress={localProgress}
+                onCancel={onCancel ? () => onCancel?.(id) : undefined}
+                onAbort={
+                  onAbort
+                    ? () => {
+                        xhr?.abort();
+                        onAbort?.(id);
+                      }
+                    : undefined
+                }
+                localization={localization}
+              />
+            </div>
           </Layer>
         </LayerContainer>
-        {/* <FileItemImage
-          imageSource={imageSource}
-          url={url}
-          fileName={localName}
-          backgroundBlurImage={backgroundBlurImage as boolean}
-          card={true}
+       
+        <Tooltip
+          open={resultOnTooltip}
+          uploadStatus={uploadStatus}
+          valid={valid}
+          errors={errors}
+          uploadMessage={uploadMessage}
         />
-
-        <div
-          className={darkMode ? "file-card-data dark-mode" : "file-card-data"}
-        >
-          <div className={"file-card-name"}>{shrinkWord(localName, true)}</div>
-
-          <div className={"file-card-size"}>{sizeFormatted}</div>
-          <div className={"file-card-size"}>{shrinkWord(localType)}</div>
-        </div>
-
-        <div className="files-ui-file-card-right">
-          <Clear
-            style={{ position: "absolute", right: 0, top: 0 }}
-            className="dui-file-item-icon"
-            color="rgba(255,255,255,0.851)"
-            onClick={handleDelete}
-            size="small"
-            colorFill="transparent"
-          />
-          <MainLayerBodyNeo
-            hide={false}
-            uploadStatus={uploadStatus}
-            localization={localization}
-            progress={progress}
-            onAbort={onAbort}
-            valid={valid}
-            hovering={true}
-            onCancel={onCancel}
-          />
-        </div> */}
+        {downloadUrl && (
+          <a ref={downloadRef} href={downloadUrl} download={localName} hidden>
+            download_file
+          </a>
+        )}
       </div>
     );
   }
diff --git a/src/files-ui/components/file-card/components/FileCardInfoLayer.tsx b/src/files-ui/components/file-card/components/FileCardInfoLayer.tsx
index bd548c3..823437c 100644
--- a/src/files-ui/components/file-card/components/FileCardInfoLayer.tsx
+++ b/src/files-ui/components/file-card/components/FileCardInfoLayer.tsx
@@ -17,19 +17,18 @@ const FileCardInfoLayer: React.FC<FileCardInfoLayerProps> = (
   } = props;
   return (
     <div className="file-card-file-info">
-      <div className="files-ui-file-card-info-layer-header">
+      {/*   <FileMosaicStatus
+        style={{ margin: 0, right: 5, bottom: 0, position:"absolute" }}
+          valid={valid}
+          uploadStatus={uploadStatus}
+          localization={localization}
+        /> */}
         <Cancel
-          style={{ margin: 0, right: 0, top: 0 }}
+          style={{ margin: 0, right: 5, top: 0, position:"absolute" }}
           color="rgba(255,255,255,0.8)"
           onClick={onCloseInfo}
           colorFill="black"
         />
-        <FileMosaicStatus
-          valid={valid}
-          uploadStatus={uploadStatus}
-          localization={localization}
-        />
-      </div>
       <div className="heading">Name:</div>
       <div className="label">{localName}</div>
       <div className="heading">Size:</div>
diff --git a/src/files-ui/components/file-card/components/FileCardUploadLayer.scss b/src/files-ui/components/file-card/components/FileCardUploadLayer.scss
new file mode 100644
index 0000000..c84a6ef
--- /dev/null
+++ b/src/files-ui/components/file-card/components/FileCardUploadLayer.scss
@@ -0,0 +1,44 @@
+.files-ui-file-card-upload-layer {
+  width: 100px;
+  height: 100%;
+  //background-color: rgba(0, 0, 0, 0.5);
+  color: rgba(255, 255, 255, 0.8);
+  font-weight: 500;
+  font-size: 1em;
+  position: relative;
+  overflow: hidden;
+
+  .elevation-list-card {
+    transition: all 1.5s ease;
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+    .elevation-item-card {
+      width: 100%;
+      height: 100px;
+
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      flex-direction: column;
+      padding: 0 10px;
+      box-sizing: border-box;
+
+      span {
+        text-align: center;
+        word-break: break-word;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        display: -webkit-box;
+        -webkit-line-clamp: 2; /* number of lines to show */
+        line-clamp: 2;
+        -webkit-box-orient: vertical;
+      }
+    }
+  }
+}
diff --git a/src/files-ui/components/file-card/components/FileCardUploadLayer.tsx b/src/files-ui/components/file-card/components/FileCardUploadLayer.tsx
new file mode 100644
index 0000000..57f0c68
--- /dev/null
+++ b/src/files-ui/components/file-card/components/FileCardUploadLayer.tsx
@@ -0,0 +1,119 @@
+import * as React from "react";
+import { Localization, UPLOADSTATUS } from "../../../core";
+import {
+  AbortedStatus,
+  EmptyStatus,
+  ErrorStatus,
+  PreparingStatus,
+  SuccessStatus,
+  UploadingStatus,
+} from "../../file-status";
+import "./FileCardUploadLayer.scss";
+export interface FileCardUploadLayerPropsMap {
+  visible?: boolean;
+  uploadStatus?: UPLOADSTATUS;
+  onCancel?: Function;
+  onAbort?: Function;
+  progress?: number;
+  localization?: Localization;
+}
+
+export type FileCardUploadLayerProps = {
+  [T in keyof FileCardUploadLayerPropsMap]: FileCardUploadLayerPropsMap[T];
+};
+
+const FileCardUploadLayer: React.FC<FileCardUploadLayerProps> = (
+  props: FileCardUploadLayerProps
+) => {
+  const { uploadStatus, onCancel, onAbort, progress, localization } = props;
+  const elevationContainerRef = React.useRef<HTMLDivElement | null>(null);
+  const listContainerStoryRef = React.useRef<HTMLDivElement | null>(null);
+
+  const [statusHistory, setStatusHistory] = React.useState<
+    Array<UPLOADSTATUS | undefined>
+  >([undefined]);
+
+  React.useEffect(() => {
+    setStatusHistory((statusHistory: Array<UPLOADSTATUS | undefined>) => {
+      if (
+        statusHistory[statusHistory.length - 1] === "preparing" &&
+        uploadStatus === "uploading"
+      ) {
+        const tempStatusHistory = [...statusHistory];
+        tempStatusHistory[statusHistory.length - 1] = uploadStatus;
+        //replace
+        return [...tempStatusHistory];
+      }
+      return [...statusHistory, uploadStatus];
+    });
+  }, [uploadStatus]);
+
+  const elevate = () => {
+    const currentElevationContainer = elevationContainerRef.current;
+    const currentElevationList = listContainerStoryRef.current;
+    if (currentElevationContainer === null || currentElevationList === null)
+      return;
+
+    currentElevationList.style.top =
+      0 - (statusHistory.length - 1) * 100 + "px";
+  };
+  React.useEffect(() => {
+    if (statusHistory.length > 1) elevate();
+    // eslint-disable-next-line
+  }, [statusHistory.length]);
+
+  return (
+    <div className={"elevation-layer-container"} ref={elevationContainerRef}>
+      <div className="elevation-list-card" ref={listContainerStoryRef}>
+        {statusHistory.map((status, index) => {
+          switch (status) {
+            case "preparing":
+              return (
+                <div className="elevation-item-card" key={index + 1}>
+                  <PreparingStatus
+                    onCancel={onCancel}
+                    localization={localization}
+                  />
+                </div>
+              );
+            case "uploading":
+              return (
+                <div className="elevation-item-card" key={index + 1}>
+                  <UploadingStatus
+                    onAbort={onAbort}
+                    progress={progress}
+                    localization={localization}
+                  />
+                </div>
+              );
+            case "error":
+              return (
+                <div className="elevation-item-card" key={index + 1}>
+                  <ErrorStatus size={60} localization={localization} />
+                </div>
+              );
+            case "success":
+              return (
+                <div className="elevation-item-card" key={index + 1}>
+                  <SuccessStatus localization={localization} />
+                </div>
+              );
+            case "aborted":
+              return (
+                <div className="elevation-item-card" key={index + 1}>
+                  <AbortedStatus localization={localization} />
+                </div>
+              );
+            default:
+              return (
+                <div className="elevation-item-card" key={index + 1}>
+                  <EmptyStatus />
+                </div>
+              );
+          }
+        })}
+      </div>
+    </div>
+  );
+};
+export default FileCardUploadLayer;
diff --git a/src/files-ui/components/file-mosaic/components/FileMosaicInfoLayer/FileMosaicInfoLayer.tsx b/src/files-ui/components/file-mosaic/components/FileMosaicInfoLayer/FileMosaicInfoLayer.tsx
index 3e51566..21a2e6a 100644
--- a/src/files-ui/components/file-mosaic/components/FileMosaicInfoLayer/FileMosaicInfoLayer.tsx
+++ b/src/files-ui/components/file-mosaic/components/FileMosaicInfoLayer/FileMosaicInfoLayer.tsx
@@ -19,7 +19,7 @@ const FileMosaicInfoLayer: React.FC<FileMosaicInfoLayerProps> = (
     <React.Fragment>
       <div className="files-ui-file-mosaic-info-layer-header">
         <Cancel
-          style={{ margin: 0, right: 0, top: 0 }}
+          //style={{ margin: 0, right: 0, top: 0 }}
           color="rgba(255,255,255,0.8)"
           onClick={onCloseInfo}
           colorFill="black"
diff --git a/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatus.tsx b/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatus.tsx
index 8501bfb..66dd014 100644
--- a/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatus.tsx
+++ b/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatus.tsx
@@ -8,7 +8,7 @@ import { FileItemLocalizerSelector, LocalLabels } from "../../../../core";
 const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
   props: FileMosaicStatusProps
 ) => {
-  const { valid, uploadStatus, localization } = props;
+  const { valid, uploadStatus, localization, style } = props;
 
   const FileItemStatusLocalizer: LocalLabels = FileItemLocalizerSelector(
     localization
@@ -16,7 +16,7 @@ const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
 
   if (uploadStatus === "success") {
     return (
-      <div className="files-ui-file-item-status-container file-status-ok">
+      <div className="files-ui-file-item-status-container file-status-ok" style={style}>
         <CloudDone color="#4caf50" size="small" className="status-icon" />
         {FileItemStatusLocalizer.success as string}
       </div>
@@ -24,7 +24,7 @@ const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
   }
   if (uploadStatus === "error" || uploadStatus === "aborted") {
     return (
-      <div className="files-ui-file-item-status-container file-status-error">
+      <div className="files-ui-file-item-status-container file-status-error" style={style}>
         <UploadError
           color="#f44336"
           size="semi-medium"
@@ -37,14 +37,14 @@ const FileMosaicStatus: React.FC<FileMosaicStatusProps> = (
   if (valid !== undefined && valid !== null) {
     if (valid) {
       return (
-        <div className="files-ui-file-item-status-container file-status-ok">
+        <div className="files-ui-file-item-status-container file-status-ok" style={style}>
           <CheckCircle color="#4caf50" size="small" className="status-icon" />
           {FileItemStatusLocalizer.valid as string}
         </div>
       );
     } else {
       return (
-        <div className="files-ui-file-item-status-container file-status-error">
+        <div className="files-ui-file-item-status-container file-status-error" style={style}>
           <DoDisturb color="#f44336" size="small" className="status-icon" />
           {FileItemStatusLocalizer.denied as string}
         </div>
diff --git a/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatusProps.ts b/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatusProps.ts
index 577c58a..e449be6 100644
--- a/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatusProps.ts
+++ b/src/files-ui/components/file-mosaic/components/FileMosaicStatus/FileMosaicStatusProps.ts
@@ -22,4 +22,7 @@ export interface FileMosaicStatusProps {
     */
     localization?: Localization;
 
+
+    style?:React.CSSProperties;
+
 }
\ No newline at end of file
diff --git a/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.scss b/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.scss
index 78bf294..23e2942 100644
--- a/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.scss
+++ b/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.scss
@@ -163,73 +163,7 @@
     }
   }
 
-/*   &.files-ui-tooltip {
-    cursor: default;
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    // border-bottom: 1px dotted black;
-    &:hover {
-      z-index: 2;
-
-      .files-ui-tooltip-tooltiptext {
-        visibility: visible;
-        opacity: 1;
-        z-index: 2;
-      }
-    }
-
-    .files-ui-tooltip-tooltiptext {
-      box-sizing: border-box;
-      font-family: "Poppins", sans-serif;
-      font-size: 0.8rem;
-      visibility: hidden;
-      width: 132px;
-      // background-color: green;
-      color: #fff;
-      text-align: center;
-      border-radius: 6px;
-      padding: 2px 2px;
-      position: absolute;
-      //z-index: 2;
-      //top: 190px;
-      top: 180px;
-      left: 66px;
-      margin-left: -60px;
-
-      // Fade in tooltip - takes 1 second to go from 0% to 100% opac:
-      opacity: 0;
-      transition: opacity 1s;
 
-      &.not-valid-error {
-        background: linear-gradient(to top, #c62828, #d32f2f);
-
-        &::after {
-          border-color: transparent transparent #d32f2f transparent;
-        }
-      }
-
-      &.success {
-        //background-color: green;
-        background: linear-gradient(to top, #1b5e20, #2e7d32);
-
-        &::after {
-          border-color: transparent transparent #2e7d32 transparent;
-        }
-      }
-
-      &::after {
-        content: "";
-        position: absolute;
-        bottom: 100%;
-        left: 50%;
-        margin-left: -5px;
-        border-width: 5px;
-        border-style: solid;
-        //border-color: transparent transparent green transparent;
-      }
-    }
-  } */
 }
 
 //// ICONS
diff --git a/src/files-ui/components/file-status/ErrorStatus.tsx b/src/files-ui/components/file-status/ErrorStatus.tsx
index b17f6bd..e930203 100644
--- a/src/files-ui/components/file-status/ErrorStatus.tsx
+++ b/src/files-ui/components/file-status/ErrorStatus.tsx
@@ -17,7 +17,7 @@ const ErrorStatus: React.FC<ErrorStatusProps> = (props: ErrorStatusProps) => {
           backgroundColor: "rgba(244, 67, 54, 0.8)",
           borderRadius: "50%",
         }}
-        size={size || 65}
+        size={size || 65} 
       />
       <span> {FileItemStatusLocalizer.error as string}</span>
     </React.Fragment>
diff --git a/src/files-ui/components/tooltip/components/Tooltip.scss b/src/files-ui/components/tooltip/components/Tooltip.scss
index 0b35afd..1e18671 100644
--- a/src/files-ui/components/tooltip/components/Tooltip.scss
+++ b/src/files-ui/components/tooltip/components/Tooltip.scss
@@ -12,6 +12,66 @@
       z-index: 2;
     }
   }
+  &.card {
+    &:hover {
+      z-index: 2;
+      .files-ui-tooltiptext {
+        visibility: visible;
+        opacity: 1;
+        z-index: 2;
+      }
+    }
+    .files-ui-tooltiptext {
+      box-sizing: border-box;
+      font-family: "Poppins", sans-serif;
+
+      font-size: 0.8rem;
+      font-weight: 400;
+      visibility: hidden;
+      width: 200px;
+      // background-color: green;
+      color: #fff;
+      text-align: center;
+      border-radius: 6px;
+      padding: 2px 2px;
+      position: absolute;
+      z-index: 2;
+      left: calc(50% - 100px);
+      left: 0;
+      margin-top: 5px;
+      //top: calc(100% + 5px);
+      top: 100%;
+      // Fade in tooltip - takes 1 second to go from 0% to 100% opac:
+      opacity: 0;
+      transition: opacity 1s;
+
+      &.not-valid-error {
+        background: linear-gradient(to top, #c62828, #d32f2f);
+        &::after {
+          border-color: transparent transparent #d32f2f transparent;
+        }
+      }
+      &.success {
+        //background-color: green;
+        background: linear-gradient(to top, #1b5e20, #2e7d32);
+        &::after {
+          border-color: transparent transparent #2e7d32 transparent;
+        }
+      }
+
+      &::after {
+        content: "";
+        position: absolute;
+        bottom: 100%;
+        left: 50%;
+        margin-left: -5px;
+        border-width: 5px;
+        border-style: solid;
+        //border-color: transparent transparent green transparent;
+      }
+    }
+  }
+
   .files-ui-tooltiptext {
     box-sizing: border-box;
     font-family: "Poppins", sans-serif;
@@ -46,6 +106,7 @@
         border-color: transparent transparent #2e7d32 transparent;
       }
     }
+
     &::after {
       content: "";
       position: absolute;
diff --git a/src/pages/demo/FileCardDemoPage.jsx b/src/pages/demo/FileCardDemoPage.jsx
index ba70091..ad715dc 100644
--- a/src/pages/demo/FileCardDemoPage.jsx
+++ b/src/pages/demo/FileCardDemoPage.jsx
@@ -235,6 +235,7 @@ const FileCardDemoPage = (props) => {
               alignItems: "center",
               justifyContent: "center",
               width: "100%",
+              flexWrap:"wrap"
             }}
           >
             <DemoFileMosaicDarkMode card />
-- 
GitLab