diff --git a/@navikt/core/css/form/file-upload.css b/@navikt/core/css/form/file-upload.css index 629ce59262..3d33484887 100644 --- a/@navikt/core/css/form/file-upload.css +++ b/@navikt/core/css/form/file-upload.css @@ -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)); } @@ -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; diff --git a/@navikt/core/react/src/form/file-upload/BoxVariant.tsx b/@navikt/core/react/src/form/file-upload/BoxVariant.tsx new file mode 100644 index 0000000000..6191c64bc7 --- /dev/null +++ b/@navikt/core/react/src/form/file-upload/BoxVariant.tsx @@ -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; + error: string | undefined; + inputId: string; + multiple: boolean; + accept: string | undefined; + handleUpload: (event: ChangeEvent) => void; + onDragEnter: () => void; + onDragEnd: () => void; + isDraggingOver: boolean; +} + +const BoxVariant = ({ + label, + className, + onDragEnter, + onDragEnd, + divRef, + error, + isDraggingOver, + inputId, + multiple, + accept, + handleUpload, +}: Props) => { + const labelRef = useRef(null) + const [widthOverride, setWidthOverride] = useState() + const [heightOverride, setHeightOverride] = useState() + + 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 ( + {widthOverride + ? Slipp + : (<> + Dra og slipp + eller + + ) + } + ) +} + +export default BoxVariant diff --git a/@navikt/core/react/src/form/file-upload/ButtonVariant.tsx b/@navikt/core/react/src/form/file-upload/ButtonVariant.tsx new file mode 100644 index 0000000000..a4d23d2bdc --- /dev/null +++ b/@navikt/core/react/src/form/file-upload/ButtonVariant.tsx @@ -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; + error: string | undefined; + inputId: string; + multiple: boolean; + accept: string | undefined; + handleUpload: (event: ChangeEvent) => void; + onDragEnter: () => void; + onDragEnd: () => void; + isDraggingOver: boolean; +} + +const ButtonVariant = ({ + label, + className, + onDragEnter, + onDragEnd, + divRef, + error, + isDraggingOver, + inputId, + multiple, + accept, + handleUpload +}: Props) => ( + + + +) + +export default ButtonVariant diff --git a/@navikt/core/react/src/form/file-upload/FileUpload.tsx b/@navikt/core/react/src/form/file-upload/FileUpload.tsx index 90b658ae67..9fdfffb7d2 100644 --- a/@navikt/core/react/src/form/file-upload/FileUpload.tsx +++ b/@navikt/core/react/src/form/file-upload/FileUpload.tsx @@ -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[], @@ -90,32 +88,7 @@ export const FileUpload = forwardRef( }, ref ) => { - const isBoxVariant = variant === "box" - const errorId = `${inputId}-error` - const ariaDescribedby = error ? errorId : undefined - - const labelRef = useRef(null) const [isDraggingOver, setIsDraggingOver] = useState(false) - const [widthOverride, setWidthOverride] = useState() - const [heightOverride, setHeightOverride] = useState() - - 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) @@ -134,68 +107,35 @@ export const FileUpload = forwardRef( event.target.value = "" } - return ( -
- -
- {error && {error}} -
-
) + isDraggingOver={isDraggingOver} + /> + } else { + return + } } ); diff --git a/@navikt/core/react/src/form/file-upload/UploadButton.tsx b/@navikt/core/react/src/form/file-upload/UploadButton.tsx new file mode 100644 index 0000000000..f8656a7eef --- /dev/null +++ b/@navikt/core/react/src/form/file-upload/UploadButton.tsx @@ -0,0 +1,15 @@ +import { UploadIcon } from "@navikt/aksel-icons"; +import React from "react"; + +interface Props { + label: string +} + +const UploadButton = ({ label }: Props) => ( + + + {label} + +) + +export default UploadButton diff --git a/@navikt/core/react/src/form/file-upload/Wrapper.tsx b/@navikt/core/react/src/form/file-upload/Wrapper.tsx new file mode 100644 index 0000000000..fb393f4f83 --- /dev/null +++ b/@navikt/core/react/src/form/file-upload/Wrapper.tsx @@ -0,0 +1,84 @@ +import cl from "clsx"; +import { ErrorMessage } from "../../typography"; +import React from "react"; + +interface Props { + className?: string, + labelClassName?: string, + onDragEnter?: () => void; + onDragEnd?: () => void; + divRef: any; + labelRef?: any; + style?: any; + error: any; + isDraggingOver: any; + children: any; + inputId: any; + multiple: any; + accept: any; + handleUpload: any; +} + +const Wrapper = ({ + className, + labelClassName, + onDragEnter, + onDragEnd, + divRef, + labelRef, + style, + error, + isDraggingOver, + children, + inputId, + multiple, + accept, + handleUpload +}: Props) => { + const errorId = `${inputId}-error` + const ariaDescribedby = error ? errorId : undefined + + return
+ +
+ {error && {error}} +
+
} + +export default Wrapper