Skip to content
Snippets Groups Projects
Commit c4ace6da authored by Jose Manuel Serrano Amaut's avatar Jose Manuel Serrano Amaut
Browse files

[WIP]: Add FileCard component and FileCard demo page. Missing to add upload...

[WIP]: Add FileCard component and FileCard demo page. Missing to add upload layer in component. Also missing to decide to delete rightlayer and set abosulte positions for delete button and others. Missing to refactopr some grids flexbox for displaying filecard properly since they are horizontal higher.
parent 21a13ad8
No related branches found
No related tags found
No related merge requests found
Showing
with 292 additions and 59 deletions
...@@ -4,9 +4,10 @@ import { ...@@ -4,9 +4,10 @@ import {
useFakeProgress, useFakeProgress,
ExtFile, ExtFile,
UPLOADSTATUS, UPLOADSTATUS,
FileCard,
} from "../../../files-ui"; } from "../../../files-ui";
const DemoFileMosaicUploadStatus = () => { const DemoFileMosaicUploadStatus = (props:{card?:boolean}) => {
const progress = useFakeProgress(); const progress = useFakeProgress();
const [status1, setStatus1] = React.useState<UPLOADSTATUS>("uploading"); const [status1, setStatus1] = React.useState<UPLOADSTATUS>("uploading");
...@@ -35,6 +36,32 @@ const DemoFileMosaicUploadStatus = () => { ...@@ -35,6 +36,32 @@ const DemoFileMosaicUploadStatus = () => {
const handleAbort = (id: string | number | undefined) => { const handleAbort = (id: string | number | undefined) => {
console.log("Upload aborted in file: " + id); console.log("Upload aborted in file: " + id);
}; };
if(props.card)
return (
<>
<FlexRowContainer card>
<FileCard {...preparingFile} />
<FileCard {...preparingFile} onCancel={handleCancel} />
</FlexRowContainer>
<FlexRowContainer card>
<FileCard {...uploadingFile} />
<FileCard {...uploadingFile} progress={progress} />
<FileCard {...uploadingFile} onAbort={handleAbort} />
<FileCard
{...uploadingFile}
onAbort={handleAbort}
progress={progress}
/>
</FlexRowContainer>
<FlexRowContainer card>
<FileCard {...uploadResultFiles[0]} uploadStatus={status1} />
<FileCard {...uploadResultFiles[1]} uploadStatus={status2} />
<FileCard {...uploadResultFiles[2]} uploadStatus={status3} />
</FlexRowContainer>
</>
)
return ( return (
<> <>
<FlexRowContainer> <FlexRowContainer>
...@@ -63,7 +90,7 @@ const DemoFileMosaicUploadStatus = () => { ...@@ -63,7 +90,7 @@ const DemoFileMosaicUploadStatus = () => {
}; };
export default DemoFileMosaicUploadStatus; export default DemoFileMosaicUploadStatus;
const FlexRowContainer = (props: { children: React.ReactNode }) => { const FlexRowContainer = (props: { children: React.ReactNode, card?:boolean }) => {
return ( return (
<div <div
style={{ style={{
...@@ -71,6 +98,7 @@ const FlexRowContainer = (props: { children: React.ReactNode }) => { ...@@ -71,6 +98,7 @@ const FlexRowContainer = (props: { children: React.ReactNode }) => {
flexWrap: "wrap", flexWrap: "wrap",
justifyContent: "space-evenly", justifyContent: "space-evenly",
width: "100%", width: "100%",
flexDirection:props.card?"column":"row"
}} }}
> >
{props.children} {props.children}
......
import * as React from "react"; import * as React from "react";
import { FileMosaic } from "../../../files-ui"; import { FileCard, FileMosaic } from "../../../files-ui";
const sampleFilesProps = [ const sampleFilesProps = [
{ {
...@@ -14,7 +14,7 @@ const sampleFilesProps = [ ...@@ -14,7 +14,7 @@ const sampleFilesProps = [
type: "image/png", type: "image/png",
name: "valid file created from props.png", name: "valid file created from props.png",
valid: false, valid: false,
errors: ["File is too big", "File type is not allowed"] errors: ["File is too big", "File type is not allowed"],
}, },
{ {
id: "fileId-3", id: "fileId-3",
...@@ -25,7 +25,16 @@ const sampleFilesProps = [ ...@@ -25,7 +25,16 @@ const sampleFilesProps = [
}, },
]; ];
const DemoFileMosaicValidation = () => { const DemoFileMosaicValidation = ({ card }) => {
if (card)
return (
<>
{sampleFilesProps.map((extFile) => (
<FileCard key={extFile.id} {...extFile} info />
))}
</>
);
return ( return (
<> <>
{sampleFilesProps.map((extFile) => ( {sampleFilesProps.map((extFile) => (
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
position: relative; position: relative;
font-size: 15px; font-size: 15px;
font-weight: 400; font-weight: 400;
width: 380px; width: 350px;
.files-ui-file-card-main-layer-container { .files-ui-file-card-main-layer-container {
width: 380px; width: 380px;
box-sizing: border-box; box-sizing: border-box;
...@@ -120,16 +120,11 @@ ...@@ -120,16 +120,11 @@
justify-content: space-between; justify-content: space-between;
flex-direction: column; flex-direction: column;
padding: 3px; padding: 3px;
width: 60px; width: 36px;
//background-color: aquamarine; //background-color: aquamarine;
height: 100%; height: 100%;
} }
.file-card-upload-layer { .file-card-upload-layer {
position: absolute;
left: 0;
right: 0;
width: 100%;
height: 100%;
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;
//background-color: rgba(0, 0, 0, 0.5); //background-color: rgba(0, 0, 0, 0.5);
...@@ -153,5 +148,64 @@ ...@@ -153,5 +148,64 @@
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
} }
.file-card-info-layer-container {
display: flex;
box-sizing: border-box;
//background-color: rgba(0, 0, 0, 0.5);
background: linear-gradient(
to right,
rgba(0, 0, 0, 0.3),
rgba(0, 0, 0, 0.5),
rgba(0, 0, 0, 0.75),
rgba(0, 0, 0, 0.9),
rgba(0, 0, 0, 0.9),
rgba(0, 0, 0, 0.9),
rgba(0, 0, 0, 0.9),
rgba(0, 0, 0, 0.9),
rgba(0, 0, 0, 0.9)
);
color: rgba(255, 255, 255, 0.8);
font-weight: 500;
font-size: 1em;
overflow: hidden;
align-items: center;
justify-content: flex-end;
.file-card-file-info {
width: 250px;
height: 100px;
text-align: left;
scrollbar-width: thin;
overflow: auto;
scrollbar-color: #646c7fa9 transparent;
&::-webkit-scrollbar {
width: 9px;
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background-color: #646c7fa9;
border-radius: 20px;
border: transparent;
}
.files-ui-file-card-info-layer-header {
display: flex;
width: 100%;
flex-direction: row;
align-items: center;
justify-content: flex-end;
}
.heading {
font-weight: 600;
padding: 0 5px;
}
.label {
padding: 0 5px;
font-weight: 399;
}
}
}
} }
} }
import * as React from "react"; import * as React from "react";
import { FileCardProps, FileCardPropsDefault } from "./FileCardProps"; import { FileCardProps } from "./FileCardProps";
import "./FileCard.scss"; import "./FileCard.scss";
import "./FileCardPaper.scss"; import "./components/FileCardPaper.scss";
import FileItemImage from "../file-item/components/FileItemImage/FileItemImage";
import useFileItemInitializer from "../file-item/hooks/useFileItemInitializer";
import { getLocalFileItemData } from "../file-item/utils/getLocalFileItemData"; import { getLocalFileItemData } from "../file-item/utils/getLocalFileItemData";
import { Clear } from "../icons";
import { fileSizeFormater, shrinkWord } from "../../core"; import { fileSizeFormater, shrinkWord } from "../../core";
import { mergeProps } from "../overridable";
import { showFileItemComponent } from "../file-item/utils/showFileItemComponent";
import useFileItemProgress from "../file-item/hooks/useFileItemProgress";
import MainLayerBodyNeo from "../file-item/components/FileItemMainLayer/MainLayerBody/MainLayerBodyNeo";
import useProgress from "../file-mosaic/hooks/useProgress"; import useProgress from "../file-mosaic/hooks/useProgress";
import useFileMosaicInitializer from "../file-mosaic/hooks/useFileMosaicInitializer"; import useFileMosaicInitializer from "../file-mosaic/hooks/useFileMosaicInitializer";
import { useIsUploading } from "../file-mosaic/hooks/useIsUploading"; import { useIsUploading } from "../file-mosaic/hooks/useIsUploading";
import LayerContainer from "../file-mosaic/components/file-mosaic-layer/LayerContainer"; import LayerContainer from "../file-mosaic/components/file-mosaic-layer/LayerContainer";
import Layer from "../file-mosaic/components/file-mosaic-layer/Layer"; import Layer from "../file-mosaic/components/file-mosaic-layer/Layer";
import FileMosaicImageLayer from "../file-mosaic/components/FIleMosaicImageLayer/FileMosaicImageLayer"; import FileMosaicImageLayer from "../file-mosaic/components/FIleMosaicImageLayer/FileMosaicImageLayer";
import FileCardRightLayer from "./FileCardRightLayer"; import FileCardRightLayer from "./components/FileCardRightLayer";
import FileCardInfoLayer from "./components/FileCardInfoLayer";
const setFinalElevation = (elevation: string | number): number => { const setFinalElevation = (elevation: string | number): number => {
// let finalElevation: number = ""; // let finalElevation: number = "";
...@@ -319,6 +313,16 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => { ...@@ -319,6 +313,16 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => {
isActive={alwaysActive || hovering} isActive={alwaysActive || hovering}
/> />
</Layer> </Layer>
<Layer className="file-card-info-layer-container" visible={showInfo}>
<FileCardInfoLayer
onCloseInfo={handleCloseInfo}
valid={valid}
localization={localization}
localName={localName}
sizeFormatted={sizeFormatted}
localType={localType}
/>
</Layer>
<Layer className="file-card-upload-layer" visible={isUploading}> <Layer className="file-card-upload-layer" visible={isUploading}>
Upload Layer Upload Layer
</Layer> </Layer>
......
import * as React from "react";
import { FileMosaicInfoLayerProps } from "../../file-mosaic/components/FileMosaicInfoLayer/FileMosaicInfoLayerProps";
import FileMosaicStatus from "../../file-mosaic/components/FileMosaicStatus/FileMosaicStatus";
import { Cancel } from "../../icons";
type FileCardInfoLayerProps = FileMosaicInfoLayerProps;
const FileCardInfoLayer: React.FC<FileCardInfoLayerProps> = (
props: FileCardInfoLayerProps
) => {
const {
valid,
localization,
onCloseInfo,
uploadStatus,
localName,
sizeFormatted,
localType,
} = props;
return (
<div className="file-card-file-info">
<div className="files-ui-file-card-info-layer-header">
<Cancel
style={{ margin: 0, right: 0, top: 0 }}
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>
<div className="label">{sizeFormatted}</div>
<div className="heading">Type:</div>
<div className="label">{localType}</div>
</div>
);
};
export default FileCardInfoLayer;
import * as React from "react"; import * as React from "react";
import { Localization, UPLOADSTATUS } from "../../core"; import { Localization, UPLOADSTATUS } from "../../../core";
import { import {
Clear, Clear,
DownloadFile, DownloadFile,
InfoDisney, InfoDisney,
PlayIcon, PlayIcon,
Visibility, Visibility,
} from "../icons"; } from "../../icons";
import "./FileMosaicRightLayer.scss"; import "./FileMosaicRightLayer.scss";
declare type FileCardRightLayerProps = { declare type FileCardRightLayerProps = {
darkMode?: boolean; darkMode?: boolean;
......
import { Localization, UPLOADSTATUS } from "../../../../core"; import { Localization, UPLOADSTATUS } from "../../../../core";
export interface FileMosaicInfoLayerProps{ export type FileMosaicInfoLayerProps = {
valid: boolean | null | undefined; valid: boolean | null | undefined;
uploadStatus?: UPLOADSTATUS; uploadStatus?: UPLOADSTATUS;
localization?: Localization; localization?: Localization;
......
...@@ -7,7 +7,6 @@ import Stack from "@mui/material/Stack"; ...@@ -7,7 +7,6 @@ import Stack from "@mui/material/Stack";
import Alert from "@mui/material/Alert"; import Alert from "@mui/material/Alert";
import CodeHighlight from "../../components/codeHighlight/CodeHighlight"; import CodeHighlight from "../../components/codeHighlight/CodeHighlight";
import DescParagraph from "../../components/demo-components/desc-paragraph/DescParagraph"; import DescParagraph from "../../components/demo-components/desc-paragraph/DescParagraph";
import BasicFileMosaicDemo from "../../components/demo-components/filemosaic-demo/DemoFileMosaicBasic";
import SubTitle from "../../components/demo-components/sub-title/SubTitle"; import SubTitle from "../../components/demo-components/sub-title/SubTitle";
import TypeHighlight from "../../components/typeHighlight/TypeHighlight"; import TypeHighlight from "../../components/typeHighlight/TypeHighlight";
import MainTitle from "../../components/main-title/MainTitle"; import MainTitle from "../../components/main-title/MainTitle";
...@@ -21,6 +20,10 @@ import DemoContainerFileMosaic from "../../components/demo-components/filemosaic ...@@ -21,6 +20,10 @@ import DemoContainerFileMosaic from "../../components/demo-components/filemosaic
import DemoFileMosaicDarkMode from "../../components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode"; import DemoFileMosaicDarkMode from "../../components/demo-components/filemosaic-demo/DemoFileMosaicDarkMode";
import CodeJSFileMosaicDarkMode from "../../components/demo-components/filemosaic-demo/CodeJSFileMosaicDarkMode"; import CodeJSFileMosaicDarkMode from "../../components/demo-components/filemosaic-demo/CodeJSFileMosaicDarkMode";
import AnchorToTab from "../../components/util-components/AnchorToTab"; import AnchorToTab from "../../components/util-components/AnchorToTab";
import DemoFileMosaicValidation from "../../components/demo-components/filemosaic-demo/DemoFileMosaicValidation";
import CodeJSFileMosaicValidation from "../../components/demo-components/filemosaic-demo/CodeJSFileMosaicValidation";
import DemoFileMosaicUploadStatus from "../../components/demo-components/filemosaic-demo/DemoFileMosaicUploadStatus";
import CodeJSFileMosaicUploadStatus from "../../components/demo-components/filemosaic-demo/CodeJSFileMosaicUploadStatus";
const FileCardDemoPage = (props) => { const FileCardDemoPage = (props) => {
return ( return (
...@@ -28,42 +31,42 @@ const FileCardDemoPage = (props) => { ...@@ -28,42 +31,42 @@ const FileCardDemoPage = (props) => {
<MainContentContainer> <MainContentContainer>
<MainTitle>FileCard</MainTitle> <MainTitle>FileCard</MainTitle>
<MainParagraph> <MainParagraph>
File cards, as well as file mosaics, are compact elements that File cards are compact elements that represent a file in the UI. They
represent a file in the UI. They can be used for just showing general can be used for just showing general info of the file, or either to
info of the file, or either allow the user to interact with them. allow the user to interact with them.
</MainParagraph> </MainParagraph>
<DescParagraph> <DescParagraph>
This widget allow users to see information of Files and / or trigger This widget allow users to see information of{" "}
actions. <TypeHighlight> Files</TypeHighlight> and / or trigger actions.
</DescParagraph> </DescParagraph>
<Alert severity="info"> <Alert severity="info">
While included here as a standalone component, the most common use While included here as a standalone component, the most common use
will be as a result of the "onChange" event of {"<Dropzone/>"} or{" "} will be to display the result of the "onChange" event of{" "}
{"<InputButton/>"} components, so some of the behavior demonstrated <CodeHighlight>{"<Dropzone/>"}</CodeHighlight> or{" "}
here is not shown in context.{" "} <CodeHighlight>{"<InputButton/>"}</CodeHighlight> components, so some
of the behavior demonstrated here is not totally shown in context.{" "}
</Alert> </Alert>
<section id="basic-filecard"> <section id="basic-filecard">
<SubTitle content="Basic FileCard" /> <SubTitle content="Basic FileCard" />
<DescParagraph> <DescParagraph>
The <CodeHighlight>FileCard</CodeHighlight> supports displaying The <CodeHighlight>FileCard</CodeHighlight> component supports
information from <TypeHighlight>File</TypeHighlight> object or displaying information from a{" "}
individual props. <TypeHighlight>
<AnchorToTab href="https://developer.mozilla.org/en-US/docs/Web/API/File">
File
</AnchorToTab>
</TypeHighlight>{" "}
object or from given props.
<br />
Also, the <TypeHighlight>onDelete</TypeHighlight> prop is used to
remove the file selection.
</DescParagraph> </DescParagraph>
<Paper <DemoContainerFileMosaic>
variant="outlined"
style={{
padding: "25px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Stack spacing={2} direction="row" alignItems={"center"}>
<DemoFileCardBasic /> <DemoFileCardBasic />
</Stack> </DemoContainerFileMosaic>
</Paper>
<CodeJSFileCardBasic /> <CodeJSFileCardBasic />
<Alert severity="info"> <Alert severity="info">
<AlertTitle> FileInputButton </AlertTitle> <AlertTitle> FileInputButton </AlertTitle>
For completeness, some of these examples include{" "} For completeness, some of these examples include{" "}
...@@ -120,12 +123,107 @@ const FileCardDemoPage = (props) => { ...@@ -120,12 +123,107 @@ const FileCardDemoPage = (props) => {
</Alert> </Alert>
</section> </section>
{/** VALIDATION UPLOAD AND MORE */} {/** VALIDATION UPLOAD AND MORE */}
<section id="validation">
<SubTitle content="Validation" />
<DescParagraph>
The <CodeHighlight>valid</CodeHighlight> prop can be set to{" "}
<TypeHighlight>true</TypeHighlight>,{" "}
<TypeHighlight>false</TypeHighlight> or{" "}
<TypeHighlight>undefined</TypeHighlight>.
</DescParagraph>
<DemoContainerFileMosaic>
<DemoFileMosaicValidation card />
</DemoContainerFileMosaic>
<CodeJSFileMosaicValidation />
<Alert severity="info">
Typically, <CodeHighlight>{"<Dropzone/>"}</CodeHighlight> or{" "}
<CodeHighlight>{"<FileInputButton/>"}</CodeHighlight> components set
this prop when validating the input from a given criteria. You can
see the behaviour mentioned in the following demos:
<ul>
<li>
<AnchorToTab href="/components/dropzone#validation">
Dropzone validation
</AnchorToTab>
</li>
<li>
<AnchorToTab href="/components/fileinputbutton#validation">
FileInputButton validation
</AnchorToTab>
</li>
</ul>
</Alert>
</section>
<section id="uploading">
<SubTitle content="Uploading status" />
<DescParagraph>
The <CodeHighlight>uploadStatus</CodeHighlight> prop can be set to{" "}
<TypeHighlight>"preparing"</TypeHighlight>,{" "}
<TypeHighlight>"uploading"</TypeHighlight>,{" "}
<TypeHighlight>"aborted"</TypeHighlight>,{" "}
<TypeHighlight>"error"</TypeHighlight> or{" "}
<TypeHighlight>"success"</TypeHighlight>. Also the{" "}
<CodeHighlight>uploadMessage</CodeHighlight> prop is used for
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 />
Each of the following examples demonstrates one state combination of
the FileMosaic component.
</DescParagraph>
<Paper
variant="outlined"
style={{
padding: "25px",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "row",
gap: "7px",
flexWrap: "wrap",
}}
>
<DemoFileMosaicUploadStatus card />
</Paper>
<CodeJSFileMosaicUploadStatus card />
<Alert severity="info">
As you can see, you have full control of the FileCard 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{" "}
<CodeHighlight>{"<Dropzone/>"}</CodeHighlight> and{" "}
<CodeHighlight>{"<FileInputButton/>"}</CodeHighlight> components
since they also manage the{" "}
<TypeHighlight>{"uploadStatus"}</TypeHighlight>
prop for you when upload is enabled. You can see the behaviour
mentioned in the following demos:
<ul>
<li>
<AnchorToTab href="/components/dropzone#uploading">
Dropzone upload
</AnchorToTab>
</li>
<li>
<AnchorToTab href="/components/fileinputbutton#uploading">
FileInputButton upload
</AnchorToTab>
</li>
</ul>
</Alert>
</section>
<section id="dark-mode"> <section id="dark-mode">
<SubTitle content="Dark mode" /> <SubTitle content="Dark mode" />
<DescParagraph> <DescParagraph>
The <CodeHighlight>FileCard</CodeHighlight> component supports The <CodeHighlight>FileCard</CodeHighlight> component supports dark
dark mode by setting the prop{" "} mode by setting the prop <TypeHighlight>darkMode</TypeHighlight> to{" "}
<TypeHighlight>darkMode</TypeHighlight> to{" "}
<TypeHighlight>true</TypeHighlight>. <TypeHighlight>true</TypeHighlight>.
</DescParagraph> </DescParagraph>
...@@ -217,9 +315,7 @@ const FileCardDemoPage = (props) => { ...@@ -217,9 +315,7 @@ const FileCardDemoPage = (props) => {
</DescParagraph> </DescParagraph>
<ul> <ul>
<li> <li>
<AnchorToTab href="/api/filecard"> <AnchorToTab href="/api/filecard">{"<FileMosaic/>"}</AnchorToTab>
{"<FileMosaic/>"}
</AnchorToTab>
</li> </li>
<li> <li>
<AnchorToTab href="/api/fileinputbuttom"> <AnchorToTab href="/api/fileinputbuttom">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment