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

[REF]: Refactor Drop layer, ripple container, header and footer in style and props

parent 53d42cc5
No related branches found
No related tags found
No related merge requests found
Showing
with 322 additions and 179 deletions
......@@ -27,7 +27,7 @@ const useDropLayerClassName = (
isDragging?: boolean
) => {
let finalClassName: string = "";
let styleSheet: DynamicSheet = dropLayerDynamicStyle(DROP_LAYER_STYLE_ID, color);
let styleSheet: DynamicSheet = dropLayerDynamicStyle(DROP_LAYER_STYLE_ID, color, isDragging);
let idStyle: string = "";
if (!styleInjected) {
......
import { asureColor, colourNameToHex, hexColorToRGB } from "../../../core";
import { DEFAULT_BORDER_RADIUS } from "../../dropzone/components/dropzone/DropzoneProps";
export const dropLayerDynamicStyle = (styleId:string, color: string | undefined) => {
export const dropLayerDynamicStyle = (styleId: string, color: string | undefined, isDragging: boolean | undefined) => {
return {
id: "files-ui-styles-drop-layer",
......@@ -8,20 +9,22 @@ export const dropLayerDynamicStyle = (styleId:string, color: string | undefined)
{
className: `dropzone-ui-layer`,
rules: {
backgroundColor: hexColorToRGB(
asureColor(colourNameToHex(color)),
0.4
),
), borderRadius: DEFAULT_BORDER_RADIUS,
position: "absolute",
left: 0,
top: 0,
width: "0%",
height: "0%",
border: `2px dashed ${hexColorToRGB(
border: isDragging ? `2px dashed ${hexColorToRGB(
asureColor(colourNameToHex(color)),
1
)}`,
)}` : undefined,
zIndex: 20,
},
},
{
......
// RIPPLE
.dropzone-ui-base-ripple-absolute {
position: absolute;
display: none;
// RIPPLE
.dropzone-ui-base-ripple-absolute {
position: absolute;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
box-sizing: border-box;
border-radius: 8px;
overflow: hidden;
.dropzone-ui-base-ripple-relative {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: relative;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
.dropzone-ui-base-ripple-relative {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
span.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple 500ms linear;
background-color: rgba(255, 255, 255, 0.7);
}
//
span.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple 500ms linear;
background-color: rgba(255, 255, 255, 0.7);
}
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
\ No newline at end of file
}
}
......@@ -6,6 +6,6 @@
justify-content: center;
gap: 8px;
flex-wrap: wrap;
//padding: 5px 0;
background-color: brown;
padding: 5px 0;
//background-color: brown;
}
import * as React from "react";
import {
addClassName,
DropzoneLocalizerSelector,
FunctionLabel,
handleClickUtil,
Localization,
LocalLabels,
} from "../../../../core";
import { FooterConfig } from "../dropzone/DropzoneProps";
export interface DropzoneFooterNeoProps {
export interface DropzoneFooterProps extends FooterConfig {
accept?: string;
message?: string;
localization?: Localization;
borderRadius?: string | number;
style?: React.CSSProperties;
className?: string;
resetStyles?: boolean;
}
const DropzoneFooter: React.FC<DropzoneFooterNeoProps> = (
props: DropzoneFooterNeoProps
const DropzoneFooter: React.FC<DropzoneFooterProps> = (
props: DropzoneFooterProps
) => {
const { accept, message, localization } = props;
const {
accept,
message,
localization,
borderRadius,
style,
className = "",
resetStyles = false,
allowedTypesLabel = true,
} = props;
const DropzoneFooterLocalizer: LocalLabels = DropzoneLocalizerSelector(
localization
).footer as LocalLabels;
const accepCustomMessenger: FunctionLabel =
DropzoneFooterLocalizer.acceptCustom as FunctionLabel;
function handleClick<T extends HTMLDivElement>(
evt: React.MouseEvent<T, MouseEvent>
): void {
handleClickUtil(evt);
}
const finalClassName = resetStyles
? className
: addClassName("files-ui-footer files-ui-footer-border", className);
const finalStyle = resetStyles
? style
: {
...style,
borderBotomLeftRadius: borderRadius,
borderBotomRightRadius: borderRadius,
};
console.log("files-ui-footer", finalStyle);
return (
<div className="files-ui-footer" onClick={handleClick}>
<div className={finalClassName} onClick={handleClick} style={finalStyle}>
<>
{message
? message
: !accept
? DropzoneFooterLocalizer.acceptAll
? allowedTypesLabel
? DropzoneFooterLocalizer.acceptAll
: undefined
: accepCustomMessenger(accept)}
</>
</div>
......
import * as React from "react";
import {
addClassName,
DropzoneLocalizerSelector,
fileSizeFormater,
FunctionLabel,
......@@ -7,8 +8,9 @@ import {
LocalLabels,
} from "../../../../core";
import { UploadingProcess, Clean, Cancel, Upload } from "../../../icons";
import { HeaderConfig } from "../dropzone/DropzoneProps";
export interface DropzoneHeaderProps {
export type DropzoneHeaderProps = {
maxFileSize?: number;
numberOfValidFiles?: number;
maxFiles?: number;
......@@ -17,13 +19,12 @@ export interface DropzoneHeaderProps {
urlPresent?: boolean;
onClean?: Function;
isUploading?: boolean;
/**
* language to be used
* for now
* only English and Spanish is supported
*/
localization?: Localization;
}
borderRadius?: string | number;
style?: React.CSSProperties;
className?: string;
resetStyles?: boolean;
};
const DropzoneHeader: React.FC<DropzoneHeaderProps> = (
props: DropzoneHeaderProps
......@@ -38,6 +39,10 @@ const DropzoneHeader: React.FC<DropzoneHeaderProps> = (
isUploading,
urlPresent,
localization,
borderRadius,
style,
className = "",
resetStyles,
} = props;
const DropzoneHeaderLocalizer: LocalLabels = DropzoneLocalizerSelector(
......@@ -64,20 +69,13 @@ const DropzoneHeader: React.FC<DropzoneHeaderProps> = (
</React.Fragment>
);
}
result.push(<React.Fragment>{","}&nbsp;</React.Fragment>);
}
const maxFileSizeMessenger: FunctionLabel =
DropzoneHeaderLocalizer.maxSizeMessage as FunctionLabel;
if (maxFileSize) {
result.push(
maxFileSizeMessenger(fileSizeFormater(maxFileSize))
/* localization === "ES-es"
? `Tam. máximo de archivo ${fileSizeFormater(maxFileSize)} | `
: `Max File size: ${fileSizeFormater(maxFileSize)} | `, */
);
result.push(maxFileSizeMessenger(fileSizeFormater(maxFileSize)));
result.push(<React.Fragment>{","}&nbsp;</React.Fragment>);
}
const validFileSizeMessenger: FunctionLabel =
......@@ -86,9 +84,6 @@ const DropzoneHeader: React.FC<DropzoneHeaderProps> = (
if (maxFiles) {
result.push(
validFileSizeMessenger(numberOfValidFiles as number, maxFiles)
/* localization === "ES-es"
? `Archivos ${numberOfValidFiles}/${maxFiles} | Válidos: ${numberOfValidFiles} | `
: `Files ${numberOfValidFiles}/${maxFiles} | Valid: ${numberOfValidFiles} | `, */
);
result.push(<React.Fragment>{","}&nbsp;</React.Fragment>);
}
......@@ -103,19 +98,31 @@ const DropzoneHeader: React.FC<DropzoneHeaderProps> = (
<Cancel
color="#646c7f"
onClick={() => onReset?.()}
// colorFill="rgba(255,255,255,0.8)"
// colorFill="rgba(255,255,255,0.8)"
/>
);
}
return result;
};
function handleClick<T extends HTMLDivElement>(
evt: React.MouseEvent<T, MouseEvent>
): void {
evt.stopPropagation();
}
const finalClassName = resetStyles
? className
: addClassName("files-ui-header files-ui-header-border", className);
const finalStyle = resetStyles
? style
: {
...style,
borderTopLeftRadius: borderRadius,
borderTopRightRadius: borderRadius,
};
return (
<div
className="files-ui-header"
onClick={(e) => {
e.stopPropagation();
}}
>
<div className={finalClassName} onClick={handleClick} style={finalStyle}>
{makeHeader().map((HeaderItem, index) => (
<span key={index} style={{ display: "flex" }}>
{HeaderItem}
......
......@@ -65,6 +65,7 @@
font-family: inherit;
//padding-right: 10px;
font-size: 1rem;
background-color: rgba(0, 128, 128, 0.249);
@media (max-width: 960px) {
//width: calc(100% - 1px);
//padding-right: 1px;
......@@ -73,8 +74,8 @@
}
.files-ui-footer {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
/* border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px; */
box-sizing: border-box;
cursor: text;
/* height: 23px;
......@@ -100,7 +101,10 @@
-webkit-line-clamp: 1; /* number of lines to show */
line-clamp: 1;
-webkit-box-orient: vertical;
//background-color: brown;
background-color: rgba(0, 128, 128, 0.249);
@media (max-width: 960px) {
//width: calc(100% - 1px);
......
......@@ -32,6 +32,7 @@ import { mergeProps } from "../../../overridable";
import InputHidden from "../../../input-hidden/InputHidden";
import {
defaultDrozoneProps,
DEFAULT_BORDER_RADIUS,
//DropzoneActionButton,
DropzoneActions,
DropzoneProps,
......@@ -55,45 +56,60 @@ import DropzoneButtons from "../DropzoneButtons/DropzoneButtons";
const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
const {
//basic
onChange,
value = [],
//validation
accept,
behaviour,
children,
className,
clickable,
color,
disabled,
dropOnLayer,
label,
localization,
maxFileSize,
maxFiles,
onChange,
onDragEnter,
onDragLeave,
style,
textColor,
validator,
value = [],
uploadConfig,
backgroundColor,
disableRipple,
fakeUpload,
footer,
header,
minHeight,
cleanFiles,
onClean,
autoClean,
//uploading
uploadConfig,
fakeUpload,
onUploadStart,
onUploadFinish,
//styling
backgroundColor,
minHeight,
color,
style,
textColor,
className,
//label
label,
//localization
localization,
//ripple
disableRipple,
//drag operations
onDragEnter,
onDragLeave,
//action butotns
actionButtons,
//drop layer
dropOnLayer,
//header and footer
header,
footer,
headerConfig = {},
footerConfg = {},
//disabled
disabled,
//open file dialog
clickable,
//add or replace
behaviour,
//content
children,
//advancedConfig,
...rest
} = mergeProps(props, defaultDrozoneProps);
console.log("Dropzone props", children);
console.log("Dropzone value", value);
const {
url,
method,
......@@ -113,24 +129,27 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
style: containerStyle,
className: containerClassName,
} = actionButtons as DropzoneActions;
const styleBorderRadius: string | number | undefined = style?.borderRadius;
/* const {
cleanFiles: cleanFilesHeader,
deleteFiles,
maxFileSize: maxFileSizeHeader,
uploadFiles,
uploading,
validFilesCount,
const {
cleanFiles: cleanFilesHeader = true,
deleteFiles: deleteFilesHeader = true,
maxFileSize: maxFileSizeHeader = true,
uploadFiles: uploadFilesHeader = true,
uploadingIcon: uploadingIconHedaer = true,
validFilesCount: validFilesCountHeader = true,
customHeader,
className: classNameHeader,
resetStyles: resetStylesHeader = false,
style: styleHeader,
}: HeaderConfig = headerConfig;
const {
allowedTypesLabel,
noMissingFilesLabel,
uploadProgressMessage,
uploadResultMessage,
customFooter,
}: FooterConfig = footerConfg; */
noMissingFilesLabel = true,
uploadProgressMessage = true,
uploadResultMessage = true,
}: FooterConfig = footerConfg;
//console.log("Dropzone props", dropOnLayer);
//localizers
const DropzoneLocalizer: LocalLabels =
......@@ -232,12 +251,15 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
if (!(missingUpload > 0)) {
console.log("upload start: noFilesMessage", missingUpload);
setLocalMessage(DropzoneLocalizer.noFilesMessage as string);
if (noMissingFilesLabel)
setLocalMessage(DropzoneLocalizer.noFilesMessage as string);
setIsUploading(false);
return;
}
setLocalMessage(uploadingMessenger(`${missingUpload}/${totalNumber}`));
if (uploadProgressMessage)
setLocalMessage(uploadingMessenger(`${missingUpload}/${totalNumber}`));
// setIsUploading(true);
//PREPARING stage
console.log("validateFilesFlag", validateFilesFlag);
......@@ -293,9 +315,10 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
instantPreparingToUploadOne(currentExtFileInstance);
//messge in footer
setLocalMessage(
uploadingMessenger(`${++currentCountUpload}/${missingUpload}`)
);
if (uploadProgressMessage)
setLocalMessage(
uploadingMessenger(`${++currentCountUpload}/${missingUpload}`)
);
//CHANGE FILES
handleFilesChange(sanitizeArrExtFile(arrOfExtFilesInstances), true);
......@@ -391,9 +414,10 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
const finishUploadMessenger: FunctionLabel =
DropzoneLocalizer.uploadFinished as FunctionLabel;
setLocalMessage(
finishUploadMessenger(missingUpload - totalRejected, totalRejected)
);
if (uploadResultMessage)
setLocalMessage(
finishUploadMessenger(missingUpload - totalRejected, totalRejected)
);
setTimeout(() => {
setIsUploading(false);
}, 2000);
......@@ -421,10 +445,11 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
//the final className
const dropzoneClassName: string | undefined = useDropzoneClassName(
className,
isDragging,
header,
footer,
isDragging && Boolean(dropOnLayer),
// header,
// footer,
color,
//style?.borderRadius || borderRadius,
backgroundColor,
minHeight
);
......@@ -666,6 +691,8 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
<div
ref={fuiRippleRefAbs}
className="dropzone-ui-base-ripple-absolute"
style={{borderRadius:style?.borderRadius}}
>
<div
ref={fuiRippleRefRel}
......@@ -673,42 +700,72 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
></div>
</div>
)}
{header && (
<DropzoneHeader
onReset={!isUploading ? handleReset : undefined}
maxFileSize={maxFileSize}
maxFiles={maxFiles}
localization={localization}
urlPresent={url !== undefined}
onUploadStart={
!autoUpload && !uploadButton
? () => uploadfiles(localFiles)
: undefined
}
numberOfValidFiles={numberOfValidFiles}
//onClean={autoClean ? undefined : cleanButton ? undefined : onClean}
onClean={
isUploading || cleanButton || autoClean
? undefined
: (cleanFiles || onClean) && validateFilesFlag
? handleClean
: undefined
}
/>
)}
<React.Fragment>
{header ? (
<>
{customHeader ? (
<>{customHeader}</>
) : (
<DropzoneHeader
style={styleHeader}
className={classNameHeader}
resetStyles={resetStylesHeader}
borderRadius={styleBorderRadius}
isUploading={isUploading && uploadingIconHedaer}
onReset={
!isUploading && deleteFilesHeader ? handleReset : undefined
}
maxFileSize={
maxFileSize && maxFileSizeHeader ? maxFileSize : undefined
}
maxFiles={
maxFiles && validFilesCountHeader ? maxFiles : undefined
}
localization={localization}
urlPresent={url !== undefined && uploadFilesHeader}
onUploadStart={
!autoUpload && !uploadButton
? () => uploadfiles(localFiles)
: undefined
}
numberOfValidFiles={numberOfValidFiles}
//onClean={autoClean ? undefined : cleanButton ? undefined : onClean}
onClean={
!cleanFilesHeader || isUploading || cleanButton || autoClean
? undefined
: (cleanFiles || onClean) && validateFilesFlag
? handleClean
: undefined
}
/>
)}
</>
) : (
<></>
)}
</React.Fragment>
<DropzoneChildren label={label} localization={localization}>
{children}
</DropzoneChildren>
{footer && (
<DropzoneFooter
accept={accept}
message={isUploading ? localMessage : undefined}
localization={localization}
/>
)}
<React.Fragment>
{customFooter ? (
<>{customFooter}</>
) : (
<>
{footer && (
<DropzoneFooter
borderRadius={styleBorderRadius}
accept={accept}
message={isUploading ? localMessage : undefined}
localization={localization}
{...footerConfg}
/>
)}
</>
)}
</React.Fragment>
{dropOnLayer && (
<DropLayer
......@@ -716,6 +773,7 @@ const Dropzone: React.FC<DropzoneProps> = (props: DropzoneProps) => {
className={dropLayerClassName}
onDragLeave={handleDragLeave}
onDrop={kamui}
style={{borderRadius:style?.borderRadius}}
/>
)}
......
......@@ -114,7 +114,8 @@ export interface DropzoneFullProps extends OverridableComponentProps {
onUploadFinish?: (extFiles: ExtFile[]) => void;
/////////////// STYLING ///////////
/////////////// STYLING ///////////
//borderRadius?: string | number;
/**
* The background color for dropzone container,
* @default 'transparent'
......@@ -132,7 +133,8 @@ export interface DropzoneFullProps extends OverridableComponentProps {
* "1rem"
*/
minHeight?: string | number;
// LABEL
///////////////// LABEL ///////////////
/**
* The label to place when no files were selected
*/
......@@ -227,9 +229,12 @@ export type HeaderConfig = {
deleteFiles?: boolean;
cleanFiles?: boolean;
uploadFiles?: boolean;
uploading?: boolean;
uploadingIcon?: boolean;
maxFileSize?: boolean;
validFilesCount?: boolean;
style?: React.CSSProperties;
className?:string;
resetStyles?:boolean;
}
export type FooterConfig = {
......@@ -294,8 +299,10 @@ export const defaultDrozoneProps: DropzoneProps =
header: true,
footer: true,
value: [],
//borderRadius: "8px"
}
export const DEFAULT_BORDER_RADIUS = "8px";
/*
......
import { DynamicSheet, DynamiCSS } from "@dynamicss/dynamicss";
import { DynamicSheet, DynamicSheetRule, DynamiCSS } from "@dynamicss/dynamicss";
import * as React from "react";
import { asureColor, colourNameToHex, hexColorToRGB } from "../../core";
import { DEFAULT_BORDER_RADIUS } from "./components/dropzone/DropzoneProps";
export default function useDropzoneClassName(
className: string | undefined,
isDragging: boolean,
header: boolean | undefined = false,
footer: boolean | undefined = false,
//header: boolean | undefined = false,
//footer: boolean | undefined = false,
color: string | undefined,
//borderRadius: string | number | undefined,
backgroundColor: string | undefined,
minHeight: string | number | undefined
): string | undefined {
......@@ -17,13 +19,14 @@ export default function useDropzoneClassName(
const [styleInjected, setStyleInjected] = React.useState<boolean>(false);
const [finalClassName, setFinalClassName] = React.useState<string | undefined>(undefined);
const [offset, setOffset] = React.useState<number>(0);
//const [offset, setOffset] = React.useState<number>(0);
const makeClassName = (
className: string | undefined,
isDragging: boolean,
// offset: number,
color: string | undefined,
//borderRadius: string | number | undefined,
backgroundColor: string | undefined,
minHeight: string | number | undefined
......@@ -32,9 +35,11 @@ export default function useDropzoneClassName(
let styleSheet: DynamicSheet = makeDynamicDropzoneStyleSheet(
// offset,
isDragging,
color,
backgroundColor,
minHeight
minHeight,
//borderRadius
);
let idStyle: string = "";
if (!styleInjected) {
......@@ -60,18 +65,21 @@ export default function useDropzoneClassName(
React.useEffect(() => {
makeClassName(className, isDragging,
//offset,
color, backgroundColor, minHeight);
color,
// borderRadius,
backgroundColor, minHeight);
// eslint-disable-next-line
}, [className, isDragging,
// offset,
color, backgroundColor, minHeight]);
React.useEffect(() => {
setOffset(header && footer ? 50 : !header && footer ? 23 : header && !footer ? 22 : 0);
}, [header, footer]);
color,
//borderRadius,
backgroundColor, minHeight]);
/* React.useEffect(() => {
setOffset(header && footer ? 50 : !header && footer ? 23 : header && !footer ? 22 : 0);
}, [header, footer]);
*/
return finalClassName;
}
......@@ -79,25 +87,49 @@ export default function useDropzoneClassName(
const makeDynamicDropzoneStyleSheet = (
// offset: number,
isDragging: boolean,
color: string | undefined,
backgroundColor: string | undefined,
minHeight: string | number | undefined
minHeight: string | number | undefined,
// borderRadius: string | number | undefined,
): DynamicSheet => {
const rootColorBorderStyle: DynamicSheetRule = {
className: `files-ui-dropzone-extra`,
rules: {
border: `1px dashed ${isDragging?"transparent":hexColorToRGB(
asureColor(colourNameToHex(color)),
1
)}`,
borderRadius: DEFAULT_BORDER_RADIUS,
backgroundColor: backgroundColor,
minHeight: typeof minHeight === "number" ? `${minHeight}px` : minHeight,
},
};
const footerBorderStyle: DynamicSheetRule = {
className: `files-ui-footer-border`,
rules: {
"border-bottom-left-radius": DEFAULT_BORDER_RADIUS,
"border-bottom-right-radius": DEFAULT_BORDER_RADIUS,
},
};
const headerBorderStyle: DynamicSheetRule = {
className: `files-ui-header-border`,
rules: {
"border-top-left-radius": DEFAULT_BORDER_RADIUS,
"border-top-right-radius": DEFAULT_BORDER_RADIUS,
},
};
const sheetRules: DynamicSheetRule[] = [rootColorBorderStyle];
if (footerBorderStyle !== undefined) {
sheetRules.push(footerBorderStyle);
}
if (headerBorderStyle !== undefined) {
sheetRules.push(headerBorderStyle);
}
return {
id: "files-dropzone-ui-style-id",
sheetRules: [
{
className: `files-ui-dropzone-extra`,
rules: {
border: `1px dashed ${hexColorToRGB(
asureColor(colourNameToHex(color)),
1
)}`,
borderRadius: "8px",
backgroundColor: backgroundColor,
minHeight: typeof minHeight === "number" ? `${minHeight}px` : minHeight,
},
}
],
sheetRules: sheetRules
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment