Skip to content

Commit

Permalink
Fiks drag-effekt og dra ut i egne sub-komponenter
Browse files Browse the repository at this point in the history
  • Loading branch information
torkjels committed Nov 23, 2023
1 parent e5bc40a commit df47411
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 98 deletions.
14 changes: 7 additions & 7 deletions @navikt/core/css/form/file-upload.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
text-align: center
}

.navds-fileuploadbutton {
.navds-fileupload__button {
position: relative;
cursor: pointer;
background-color: var(--ac-file-upload-button-bg, var(--a-bg-default));
transition: 0.2s ease all;
}

.navds-fileupload:hover .navds-fileuploadbutton {
.navds-fileupload:hover .navds-fileupload__button {
background-color: var(--ac-file-upload-action-hover-bg, var(--a-surface-action-subtle-hover));
}

Expand All @@ -35,22 +35,22 @@
}

.navds-fileupload--dragover,
.navds-fileuploadbutton--dragover {
.navds-fileupload--dragover .navds-fileupload__button {
background-color: var(--ac-file-upload-dragover-bg, var(--a-surface-action-subtle-hover));
}

.navds-fileupload--error:not(:hover):not(.navds-fileupload--dragover) .navds-fileuploadbutton {
.navds-fileupload--error:not(:hover):not(.navds-fileupload--dragover) .navds-fileupload__button {
box-shadow: inset 0 0 0 2px var(--ac-file-upload-error-border, var(--a-surface-danger))
}

.navds-fileupload:focus:not(.navds-fileupload--dragover) .navds-fileuploadbutton,
.navds-fileupload:focus-within:not(.navds-fileupload--dragover) .navds-fileuploadbutton {
.navds-fileupload:focus:not(.navds-fileupload--dragover) .navds-fileupload__button,
.navds-fileupload:focus-within:not(.navds-fileupload--dragover) .navds-fileupload__button {
box-shadow: inset 0 0 0 2px
var(--ac-button-secondary-focus-border, var(--__ac-button-secondary-focus-border, var(--a-border-action))),
var(--a-shadow-focus);
}

.navds-fileuploadinput {
.navds-fileupload__input {
position: absolute;
top: 0;
right: 0;
Expand Down
85 changes: 85 additions & 0 deletions @navikt/core/react/src/form/file-upload/BoxVariant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { ChangeEvent, useRef, useState } from "react";
import { useClientLayoutEffect } from "../../util";
import { BodyShort } from "../../typography";
import Wrapper from "./Wrapper";
import UploadButton from "./UploadButton";

interface Props {
label: string;
className: string | undefined;
divRef: React.Ref<HTMLDivElement>;
error: string | undefined;
inputId: string;
multiple: boolean;
accept: string | undefined;
handleUpload: (event: ChangeEvent<HTMLInputElement>) => void;
onDragEnter: () => void;
onDragEnd: () => void;
isDraggingOver: boolean;
}

const BoxVariant = ({
label,
className,
onDragEnter,
onDragEnd,
divRef,
error,
isDraggingOver,
inputId,
multiple,
accept,
handleUpload,
}: Props) => {
const labelRef = useRef<HTMLLabelElement | null>(null)
const [widthOverride, setWidthOverride] = useState<number>()
const [heightOverride, setHeightOverride] = useState<number>()

useClientLayoutEffect(() => {
if (isDraggingOver) {
const requestID = window.requestAnimationFrame(() => {
const boundingClientRect = labelRef?.current?.getBoundingClientRect()
setWidthOverride(boundingClientRect?.width)
setHeightOverride(boundingClientRect?.height)
});
return () => {
setWidthOverride(undefined);
setHeightOverride(undefined);
cancelAnimationFrame(requestID);
};
} else {
setWidthOverride(undefined);
setHeightOverride(undefined);
}
}, [isDraggingOver]);

return (<Wrapper
divRef={divRef}
className={className}
labelClassName="navds-fileupload--box"
onDragEnter={onDragEnter}
onDragEnd={onDragEnd}
labelRef={labelRef}
style={{
width: widthOverride,
height: heightOverride
}}
error={error}
isDraggingOver={isDraggingOver}
inputId={inputId}
multiple={multiple}
accept={accept}
handleUpload={handleUpload}
>
{widthOverride
? <BodyShort as="span">Slipp</BodyShort>
: (<>
<BodyShort as="span">Dra og slipp</BodyShort>
<BodyShort as="span">eller</BodyShort>
<UploadButton label={label} />
</>)
}
</Wrapper>)
}

export default BoxVariant
48 changes: 48 additions & 0 deletions @navikt/core/react/src/form/file-upload/ButtonVariant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { ChangeEvent } from "react";
import Wrapper from "./Wrapper";
import UploadButton from "./UploadButton";

interface Props {
label: string;
className: string | undefined;
divRef: React.Ref<HTMLDivElement>;
error: string | undefined;
inputId: string;
multiple: boolean;
accept: string | undefined;
handleUpload: (event: ChangeEvent<HTMLInputElement>) => void;
onDragEnter: () => void;
onDragEnd: () => void;
isDraggingOver: boolean;
}

const ButtonVariant = ({
label,
className,
onDragEnter,
onDragEnd,
divRef,
error,
isDraggingOver,
inputId,
multiple,
accept,
handleUpload
}: Props) => (
<Wrapper
divRef={divRef}
className={className}
error={error}
inputId={inputId}
multiple={multiple}
accept={accept}
handleUpload={handleUpload}
onDragEnter={onDragEnter}
onDragEnd={onDragEnd}
isDraggingOver={isDraggingOver}
>
<UploadButton label={label} />
</Wrapper>
)

export default ButtonVariant
122 changes: 31 additions & 91 deletions @navikt/core/react/src/form/file-upload/FileUpload.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { UploadIcon } from "@navikt/aksel-icons";
import cl from "clsx";
import React, { forwardRef, ChangeEvent, useState, useRef } from "react";
import { BodyShort, ErrorMessage } from "../../typography";
import React, { forwardRef, ChangeEvent, useState } from "react";
import { partitionFiles } from "./partition-files";
import { useClientLayoutEffect } from "../../util";
import ButtonVariant from "./ButtonVariant";
import BoxVariant from "./BoxVariant";

export interface OnUploadProps {
allFiles: File[],
Expand Down Expand Up @@ -90,32 +88,7 @@ export const FileUpload = forwardRef<HTMLDivElement, FileUploadProps>(
},
ref
) => {
const isBoxVariant = variant === "box"
const errorId = `${inputId}-error`
const ariaDescribedby = error ? errorId : undefined

const labelRef = useRef<HTMLLabelElement | null>(null)
const [isDraggingOver, setIsDraggingOver] = useState<boolean>(false)
const [widthOverride, setWidthOverride] = useState<number>()
const [heightOverride, setHeightOverride] = useState<number>()

useClientLayoutEffect(() => {
if (isBoxVariant && isDraggingOver) {
const requestID = window.requestAnimationFrame(() => {
const boundingClientRect = labelRef?.current?.getBoundingClientRect()
setWidthOverride(boundingClientRect?.width)
setHeightOverride(boundingClientRect?.height)
});
return () => {
setWidthOverride(undefined);
setHeightOverride(undefined);
cancelAnimationFrame(requestID);
};
} else {
setWidthOverride(undefined);
setHeightOverride(undefined);
}
}, [isDraggingOver, variant]);

const onDragEnter = () => setIsDraggingOver(true)
const onDragEnd = () => setIsDraggingOver(false)
Expand All @@ -134,68 +107,35 @@ export const FileUpload = forwardRef<HTMLDivElement, FileUploadProps>(
event.target.value = ""
}

return (
<div
className={cl("navds-form-field", className)}
onDragOver={onDragEnter}
onDragLeave={onDragEnd}
if (variant === "button") {
return <ButtonVariant
label={label}
divRef={ref}
className={className}
error={error}
inputId={inputId}
multiple={multiple}
accept={accept}
handleUpload={handleUpload}
onDragEnter={onDragEnter}
onDragEnd={onDragEnd}
onDrop={onDragEnd}
ref={ref}
>
<label
style={{
width: widthOverride,
height: heightOverride
}}
ref={labelRef}
className={
cl("navds-fileupload", {
'navds-fileupload--box': isBoxVariant,
"navds-fileupload--error": !!error,
"navds-fileupload--dragover": isDraggingOver
})
}
>
{widthOverride
? <BodyShort as="span">Slipp</BodyShort>
: (<>
{isBoxVariant && (<>
<BodyShort as="span">Dra og slipp</BodyShort>
<BodyShort as="span">eller</BodyShort>
</>)}
<span
className={cl(
"navds-button",
"navds-button--secondary",
"navds-fileuploadbutton",
{ "navds-fileuploadbutton--dragover": isDraggingOver }
)}
>
<UploadIcon fontSize="1.5rem" focusable={false} aria-hidden={true} className="navds-fileupload__icon" />
{label}
</span>
</>)
}
<input
type="file"
className="navds-fileuploadinput"
id={inputId}
multiple={multiple}
aria-describedby={ariaDescribedby}
accept={accept}
onChange={handleUpload}
/>
</label>
<div
className="navds-form-field__error"
id={errorId}
aria-relevant="additions removals"
aria-live="polite"
>
{error && <ErrorMessage>{error}</ErrorMessage>}
</div>
</div>)
isDraggingOver={isDraggingOver}
/>
} else {
return <BoxVariant
label={label}
divRef={ref}
className={className}
error={error}
inputId={inputId}
multiple={multiple}
accept={accept}
handleUpload={handleUpload}
onDragEnter={onDragEnter}
onDragEnd={onDragEnd}
isDraggingOver={isDraggingOver}
/>
}
}
);

Expand Down
15 changes: 15 additions & 0 deletions @navikt/core/react/src/form/file-upload/UploadButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { UploadIcon } from "@navikt/aksel-icons";
import React from "react";

interface Props {
label: string
}

const UploadButton = ({ label }: Props) => (
<span className="navds-button navds-button--secondary navds-fileupload__button">
<UploadIcon fontSize="1.5rem" focusable={false} aria-hidden={true} className="navds-fileupload__icon" />
{label}
</span>
)

export default UploadButton
Loading

0 comments on commit df47411

Please sign in to comment.