@drivy/cobalt 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/Modal/ModalHeader.js.map +1 -1
- package/components/Modal/MultiStepModal.js +49 -0
- package/components/Modal/MultiStepModal.js.map +1 -0
- package/components/Modal/index.js.map +1 -1
- package/components/PhotoDropzone/index.js +4 -2
- package/components/PhotoDropzone/index.js.map +1 -1
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components/PhotoDropzone/index.scss +2 -0
- package/types/src/components/Modal/ModalHeader.d.ts +1 -1
- package/types/src/components/Modal/MultiStepModal.d.ts +24 -0
- package/types/src/components/Modal/index.d.ts +2 -1
- package/types/src/components/PhotoDropzone/index.d.ts +3 -2
- package/types/src/index.d.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalHeader.js","sources":["../../../src/components/Modal/ModalHeader.tsx"],"sourcesContent":["import React from \"react\"\nimport { Dialog } from \"@ark-ui/react\"\n\nimport { Icon } from \"../Icon\"\n\nconst ModalHeader = ({\n title,\n close,\n}: {\n title?:
|
|
1
|
+
{"version":3,"file":"ModalHeader.js","sources":["../../../src/components/Modal/ModalHeader.tsx"],"sourcesContent":["import React from \"react\"\nimport { Dialog } from \"@ark-ui/react\"\n\nimport { Icon } from \"../Icon\"\n\nconst ModalHeader = ({\n title,\n close,\n}: {\n title?: React.ReactNode\n close?: () => void\n}) => {\n if (!title && !close) return null\n\n return (\n <div className=\"cobalt-modal-header\">\n <Dialog.Title className=\"cobalt-modal-header__title\">\n {title}\n </Dialog.Title>\n {close && (\n <Dialog.CloseTrigger className=\"cobalt-modal-header__close-button\">\n <span aria-hidden>\n <Icon source=\"close\" color=\"subdued\" />\n </span>\n </Dialog.CloseTrigger>\n )}\n </div>\n )\n}\n\nexport default ModalHeader\n"],"names":[],"mappings":";;;;AAKM,MAAA,WAAW,GAAG,CAAC,EACnB,KAAK,EACL,KAAK,GAIN,KAAI;AACH,IAAA,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI,CAAA;AAEjC,IAAA,QACE,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,qBAAqB,EAAA;QAClC,KAAC,CAAA,aAAA,CAAA,MAAM,CAAC,KAAK,EAAA,EAAC,SAAS,EAAC,4BAA4B,EACjD,EAAA,KAAK,CACO;QACd,KAAK,KACJ,KAAC,CAAA,aAAA,CAAA,MAAM,CAAC,YAAY,EAAA,EAAC,SAAS,EAAC,mCAAmC,EAAA;AAChE,YAAA,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAA,aAAA,EAAA,IAAA,EAAA;AACE,gBAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAC,MAAM,EAAC,OAAO,EAAC,KAAK,EAAC,SAAS,GAAG,CAClC,CACa,CACvB,CACG,EACP;AACH;;;;"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React, { useRef, useState, useEffect } from 'react';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import Modal from './index.js';
|
|
4
|
+
|
|
5
|
+
const MultiStepModal = ({ stepData = null, close, steps, onHidden, useMidSizeHeight = true, ...modalProps }) => {
|
|
6
|
+
const bodyScrollContentRef = useRef(null);
|
|
7
|
+
const [currentStep, setCurrentStep] = useState(0);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
(_b = (_a = bodyScrollContentRef.current) === null || _a === void 0 ? void 0 : _a.children.item(currentStep)) === null || _b === void 0 ? void 0 : _b.scrollIntoView({
|
|
11
|
+
behavior: "smooth",
|
|
12
|
+
});
|
|
13
|
+
}, [currentStep]);
|
|
14
|
+
const handleNextStep = () => {
|
|
15
|
+
setCurrentStep(currentStep >= steps.length - 1 ? currentStep : currentStep + 1);
|
|
16
|
+
};
|
|
17
|
+
const handlePreviousStep = () => {
|
|
18
|
+
setCurrentStep(currentStep <= 0 ? 0 : currentStep - 1);
|
|
19
|
+
};
|
|
20
|
+
const onModalClosed = () => {
|
|
21
|
+
onHidden === null || onHidden === void 0 ? void 0 : onHidden(currentStep);
|
|
22
|
+
setCurrentStep(0);
|
|
23
|
+
};
|
|
24
|
+
const navigation = {
|
|
25
|
+
nextStep: handleNextStep,
|
|
26
|
+
previousStep: handlePreviousStep,
|
|
27
|
+
closeModal: close,
|
|
28
|
+
};
|
|
29
|
+
const CurrentStepComponents = steps[currentStep];
|
|
30
|
+
const stepProps = { data: stepData, navigation };
|
|
31
|
+
const minimumScale = useMidSizeHeight
|
|
32
|
+
? "c-opacity-0 c-grid-rows-[0.5fr]"
|
|
33
|
+
: "c-opacity-0 c-grid-rows-[0fr]";
|
|
34
|
+
return (React.createElement(Modal, { ...modalProps, title: React.createElement(CurrentStepComponents.title, { ...stepProps }), close: close, onHidden: onModalClosed },
|
|
35
|
+
React.createElement("div", { className: "c-w-full c-overflow-x-hidden" },
|
|
36
|
+
React.createElement("div", { className: "c-py-sm", ref: bodyScrollContentRef, style: { width: `${steps.length * 100}%` } }, steps.map((StepComponents, index) => {
|
|
37
|
+
return (React.createElement("div", { key: "modal_step_" + index, className: cx("c-inline-grid c-align-top c-transition-all c-duration-500", {
|
|
38
|
+
"c-opacity-100 c-grid-rows-[1fr]": index === currentStep,
|
|
39
|
+
[minimumScale]: index !== currentStep,
|
|
40
|
+
}), style: { width: `${100 / steps.length}%` } },
|
|
41
|
+
React.createElement("div", { className: "c-overflow-hidden" },
|
|
42
|
+
React.createElement(StepComponents.content, { ...stepProps }))));
|
|
43
|
+
}))),
|
|
44
|
+
CurrentStepComponents.footer && (React.createElement(Modal.Footer, null,
|
|
45
|
+
React.createElement(CurrentStepComponents.footer, { ...stepProps })))));
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { MultiStepModal as default };
|
|
49
|
+
//# sourceMappingURL=MultiStepModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiStepModal.js","sources":["../../../src/components/Modal/MultiStepModal.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\"\nimport cx from \"classnames\"\nimport Modal, { ModalPropsType } from \".\"\n\ntype StepComponentType<T> = (props: {\n navigation: {\n nextStep: () => void\n previousStep: () => void\n closeModal: () => void\n }\n data: T\n}) => React.ReactNode\n\nexport type ModalStepType<T> = {\n title: StepComponentType<T>\n content: StepComponentType<T>\n footer?: StepComponentType<T>\n}\n\ntype MultiStepsModalProps<T = null> = {\n stepData?: T\n close: () => void\n onHidden?: (currentStepIndex: number) => void\n steps: ModalStepType<T>[]\n useMidSizeHeight?: boolean\n} & Omit<ModalPropsType, \"children\" | \"onHidden\" | \"close\">\n\nconst MultiStepModal = <T,>({\n stepData = null as T,\n close,\n steps,\n onHidden,\n useMidSizeHeight = true,\n ...modalProps\n}: MultiStepsModalProps<T>) => {\n const bodyScrollContentRef = useRef<HTMLDivElement>(null)\n const [currentStep, setCurrentStep] = useState(0)\n\n useEffect(() => {\n bodyScrollContentRef.current?.children.item(currentStep)?.scrollIntoView({\n behavior: \"smooth\",\n })\n }, [currentStep])\n\n const handleNextStep = () => {\n setCurrentStep(\n currentStep >= steps.length - 1 ? currentStep : currentStep + 1\n )\n }\n\n const handlePreviousStep = () => {\n setCurrentStep(currentStep <= 0 ? 0 : currentStep - 1)\n }\n\n const onModalClosed = () => {\n onHidden?.(currentStep)\n setCurrentStep(0)\n }\n\n const navigation = {\n nextStep: handleNextStep,\n previousStep: handlePreviousStep,\n closeModal: close,\n }\n\n const CurrentStepComponents = steps[currentStep]\n const stepProps = { data: stepData, navigation }\n\n const minimumScale = useMidSizeHeight\n ? \"c-opacity-0 c-grid-rows-[0.5fr]\"\n : \"c-opacity-0 c-grid-rows-[0fr]\"\n\n return (\n <Modal\n {...modalProps}\n title={<CurrentStepComponents.title {...stepProps} />}\n close={close}\n onHidden={onModalClosed}\n >\n <div className=\"c-w-full c-overflow-x-hidden\">\n <div\n className=\"c-py-sm\"\n ref={bodyScrollContentRef}\n style={{ width: `${steps.length * 100}%` }}\n >\n {steps.map((StepComponents, index) => {\n return (\n <div\n key={\"modal_step_\" + index}\n className={cx(\n \"c-inline-grid c-align-top c-transition-all c-duration-500\",\n {\n \"c-opacity-100 c-grid-rows-[1fr]\": index === currentStep,\n [minimumScale]: index !== currentStep,\n }\n )}\n style={{ width: `${100 / steps.length}%` }}\n >\n <div className=\"c-overflow-hidden\">\n <StepComponents.content {...stepProps} />\n </div>\n </div>\n )\n })}\n </div>\n </div>\n {CurrentStepComponents.footer && (\n <Modal.Footer>\n <CurrentStepComponents.footer {...stepProps} />\n </Modal.Footer>\n )}\n </Modal>\n )\n}\n\nexport default MultiStepModal\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/Modal/index.tsx"],"sourcesContent":["import React, { isValidElement, useEffect, forwardRef } from \"react\"\nimport { Dialog, Portal } from \"@ark-ui/react\"\nimport cx from \"classnames\"\n\nimport ModalHeader from \"./ModalHeader\"\nimport ModalFooter, { ModalFooterPropsType } from \"./ModalFooter\"\n\nexport type ModalPropsType = {\n /**\n * mandatory for A11y\n */\n [\"aria-label\"]: string\n /**\n * Function called to close the modal, providing it make the modal closeable\n */\n close?: () => void\n /**\n * React.ref of the element to focus first when the modal opens\n */\n initialFocusRef?: React.RefObject<HTMLElement>\n /**\n * State to show or hide the modal/dialog\n */\n isOpen: boolean\n /**\n * Custom css classes to add to the modal\n */\n className?: string\n /**\n * Action to fire if the user try to dismiss when the modal is not closeable\n */\n onDismissAttempt?: () => void\n /**\n * Listener called when the modal has been fully hidden\n */\n onHidden?: () => void\n /**\n * Listener called when the modal begins to show\n */\n onShow?: () => void\n /**\n * Modal title\n */\n title?:
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/Modal/index.tsx"],"sourcesContent":["import React, { isValidElement, useEffect, forwardRef } from \"react\"\nimport { Dialog, Portal } from \"@ark-ui/react\"\nimport cx from \"classnames\"\n\nimport ModalHeader from \"./ModalHeader\"\nimport ModalFooter, { ModalFooterPropsType } from \"./ModalFooter\"\n\nexport type ModalPropsType = {\n /**\n * mandatory for A11y\n */\n [\"aria-label\"]: string\n /**\n * Function called to close the modal, providing it make the modal closeable\n */\n close?: () => void\n /**\n * React.ref of the element to focus first when the modal opens\n */\n initialFocusRef?: React.RefObject<HTMLElement>\n /**\n * State to show or hide the modal/dialog\n */\n isOpen: boolean\n /**\n * Custom css classes to add to the modal\n */\n className?: string\n /**\n * Action to fire if the user try to dismiss when the modal is not closeable\n */\n onDismissAttempt?: () => void\n /**\n * Listener called when the modal has been fully hidden\n */\n onHidden?: () => void\n /**\n * Listener called when the modal begins to show\n */\n onShow?: () => void\n /**\n * Modal title\n */\n title?: React.ReactNode\n /**\n * Disable/Enable body paddings (enabled by default)\n */\n bodySpacing?: boolean\n /**\n * Disable/Enable hidding overflowing absolute elements (enabled by default)\n */\n overflowHidden?: boolean\n /**\n * Disable enter/leave animation (animation enabled by default)\n */\n skipAnimation?: {\n enter: boolean\n leave: boolean\n }\n /**\n * Disable modal max-width limit\n */\n fullWidth?: boolean\n /**\n * Always take the full height of the screen\n */\n fullHeight?: boolean\n /**\n * Remove the modal from the DOM on hidden (enabled by default)\n */\n unmountOnHidden?: boolean\n /**\n * Modal body content\n */\n children: React.ReactNode\n}\n\n// Only for the API, render nothing, we use ModalFooterInternal internally\nexport const ModalFooterAPI = (_props: ModalFooterPropsType) => null\n\nexport const isModalFooterAPIComponent = (\n component: React.ReactNode\n): component is React.ReactElement<ModalFooterPropsType> =>\n React.isValidElement(component) && component.type === ModalFooterAPI\n\nconst Modal = forwardRef<HTMLDivElement, ModalPropsType>(\n (\n {\n isOpen,\n close,\n className,\n initialFocusRef,\n [\"aria-label\"]: ariaLabel,\n title,\n children,\n overflowHidden = true,\n bodySpacing = true,\n fullWidth,\n fullHeight,\n onHidden,\n onShow,\n skipAnimation,\n onDismissAttempt,\n unmountOnHidden = true,\n }: ModalPropsType,\n ref\n ) => {\n useEffect(() => {\n isOpen && onShow?.()\n }, [onShow, isOpen])\n\n const modalFooter = React.Children.toArray(children).find((c) =>\n isModalFooterAPIComponent(c)\n )\n const hasFooter = isValidElement(modalFooter)\n\n return (\n <Dialog.Root\n aria-label={ariaLabel}\n open={isOpen}\n onOpenChange={(e) => {\n e.open ? onShow?.() : close?.()\n }}\n onExitComplete={onHidden}\n initialFocusEl={initialFocusRef && (() => initialFocusRef.current)}\n onPointerDownOutside={close ? undefined : onDismissAttempt}\n lazyMount\n unmountOnExit={unmountOnHidden}\n >\n <Portal>\n <Dialog.Backdrop\n className={cx(\"cobalt-modal__overlay\", {\n \"cobalt-modal--skipAnimation__enter\": skipAnimation?.enter,\n \"cobalt-modal--skipAnimation__leave\": skipAnimation?.leave,\n })}\n >\n <Dialog.Positioner\n className={cx(\"cobalt-modal\", {\n \"cobalt-modal--overflowHidden\": overflowHidden,\n \"cobalt-modal--fullHeight\": fullHeight,\n \"cobalt-modal--fullWidth\": fullWidth,\n })}\n ref={ref}\n >\n <Dialog.Content\n className={cx(\"cobalt-modal__content\", className, {\n \"cobalt-modal--skipAnimation__enter\": skipAnimation?.enter,\n \"cobalt-modal--skipAnimation__leave\": skipAnimation?.leave,\n })}\n >\n <ModalHeader title={title} close={close} />\n <Dialog.Description className=\"cobalt-modal-body__wrapper\">\n <div\n className={cx(\"cobalt-modal-body\", {\n \"cobalt-modal-body--bodySpacing\": bodySpacing,\n \"cobalt-modal-body--hasFooter\": hasFooter,\n })}\n >\n {children}\n </div>\n {hasFooter && <ModalFooter {...modalFooter.props} />}\n </Dialog.Description>\n </Dialog.Content>\n </Dialog.Positioner>\n </Dialog.Backdrop>\n </Portal>\n </Dialog.Root>\n )\n }\n)\n\nModal.displayName = \"Modal\"\n\nexport default Object.assign(Modal, { Footer: ModalFooterAPI })\n\nexport { default as MultiStepModal, type ModalStepType } from \"./MultiStepModal\"\n"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import cx from 'classnames';
|
|
|
3
3
|
import '../Icon/index.js';
|
|
4
4
|
import { validateFile } from '../utils/validateFile.js';
|
|
5
5
|
import Popover from '../Popover/index.js';
|
|
6
|
+
import Modal from '../Modal/index.js';
|
|
6
7
|
import BinIcon from '../Icon/__generated__/BinIcon.js';
|
|
7
8
|
import PlusIcon from '../Icon/__generated__/PlusIcon.js';
|
|
8
9
|
import ContextualWarningCircleFilledIcon from '../Icon/__generated__/ContextualWarningCircleFilledIcon.js';
|
|
@@ -17,7 +18,7 @@ const preventEventDefaults = (e) => {
|
|
|
17
18
|
e.stopPropagation && e.stopPropagation();
|
|
18
19
|
};
|
|
19
20
|
const isEnterOrSpaceKey = (event) => event.key === "Enter" || event.key === " ";
|
|
20
|
-
const PhotoDropzone = ({ className, description,
|
|
21
|
+
const PhotoDropzone = ({ className, description, deleteContent, errorContent, onDropped, onPhotoDelete, deleteContentMode = "popover", initialImageUrl = "", }) => {
|
|
21
22
|
const fileInputRef = useRef(null);
|
|
22
23
|
const deleteButtonRef = useRef(null);
|
|
23
24
|
const [isDragging, setIsDragging] = useState(false);
|
|
@@ -161,7 +162,8 @@ const PhotoDropzone = ({ className, description, deletePopoverContent, errorCont
|
|
|
161
162
|
// in order to have the correct events bubbling
|
|
162
163
|
onTouchEnd: onDeleteButtonClick, onMouseUp: onDeleteButtonClick, onKeyUp: onDeleteKey },
|
|
163
164
|
React.createElement(BinIcon, { color: "indigo" })),
|
|
164
|
-
React.createElement(
|
|
165
|
+
deleteContentMode === "modal" && (React.createElement(Modal, { isOpen: showDeletePopover, "aria-label": "delete", bodySpacing: false }, deleteContent(onDelete, closeDeletePopover))),
|
|
166
|
+
deleteContentMode === "popover" && (React.createElement(Popover, { targetRef: deleteButtonRef, isOpen: showDeletePopover, close: closeDeletePopover, placement: "left-start", distance: 12, bodySpacing: false, arrow: true }, deleteContent(onDelete, closeDeletePopover)))))) : (React.createElement("div", { className: "cobalt-photo-dropzone__description cobalt-photo-dropzone__description--strong" },
|
|
165
167
|
description && React.createElement("div", null, description),
|
|
166
168
|
React.createElement(PlusIcon, null)))),
|
|
167
169
|
React.createElement("input", { ref: fileInputRef, className: "cobalt-photo-dropzone__hidden-input", type: "file", onChange: onFileInputChanged, accept: ACCEPTED_PHOTOS_TYPES.map((ext) => `.${ext}`).join(","), multiple: false })));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/PhotoDropzone/index.tsx"],"sourcesContent":["import React, {\n useState,\n DragEvent as ReactDragEvent,\n useRef,\n TouchEvent as ReactTouchEvent,\n ChangeEvent as ReactChangeEvent,\n MouseEvent as ReactMouseEvent,\n KeyboardEvent as ReactKeyboardEvent,\n ReactNode,\n} from \"react\"\nimport cx from \"classnames\"\nimport {\n PlusIcon,\n BinIcon,\n LoadingIcon,\n ContextualWarningCircleFilledIcon,\n} from \"../Icon\"\nimport { validateFile } from \"../utils/validateFile\"\nimport Popover from \"../Popover\"\n\nconst ACCEPTED_MAX_SIZE_MB = 10\nconst ACCEPTED_PHOTOS_TYPES = [\"jpg\", \"jpeg\", \"png\", \"gif\"]\nconst ERROR_DISPLAY_TIME = 6000\nconst ACCEPTED_TYPES_LOCALE_STRING = ACCEPTED_PHOTOS_TYPES.join(\", \")\n\nexport type PhotoDropzonePropsType = {\n className?: string\n description?: string\n deletePopoverContent: (onDelete: () => void, close: () => void) => ReactNode\n errorContent: (acceptedTypes: string, maxFileSize: number) => ReactNode\n onDropped: (file: File) => Promise<void> | void\n onPhotoDelete?: () => void\n initialImageUrl?: string\n}\n\nconst preventEventDefaults = (\n e: ReactDragEvent | ReactMouseEvent | ReactKeyboardEvent | ReactTouchEvent\n) => {\n e.preventDefault && e.preventDefault()\n e.stopPropagation && e.stopPropagation()\n}\n\nconst isEnterOrSpaceKey = (event: ReactKeyboardEvent) =>\n event.key === \"Enter\" || event.key === \" \"\n\nconst PhotoDropzone = ({\n className,\n description,\n deletePopoverContent,\n errorContent,\n onDropped,\n onPhotoDelete,\n initialImageUrl = \"\",\n}: PhotoDropzonePropsType) => {\n const fileInputRef = useRef<HTMLInputElement>(null)\n const deleteButtonRef = useRef<HTMLButtonElement>(null)\n const [isDragging, setIsDragging] = useState(false)\n const [isLoading, setIsLoading] = useState(false)\n const [isErrored, setIsErrored] = useState(false)\n const [imagePreviewUrl, setImagePreviewUrl] = useState(initialImageUrl)\n const [displayDeletion, setDisplayDeletion] = useState(false)\n const [showDeletePopover, setShowDeletePopover] = useState(false)\n\n const openDeletePopover = (\n event?: ReactMouseEvent | ReactKeyboardEvent | ReactTouchEvent\n ) => {\n event && preventEventDefaults(event)\n setShowDeletePopover(true)\n }\n const closeDeletePopover = (event?: ReactMouseEvent | ReactTouchEvent) => {\n event && preventEventDefaults(event)\n setShowDeletePopover(false)\n }\n\n const onDropzoneMouseEnter = (event?: ReactMouseEvent) => {\n event && preventEventDefaults(event)\n if (imagePreviewUrl) setDisplayDeletion(true)\n }\n\n const onDropzoneMouseLeave = (event?: ReactMouseEvent) => {\n event && preventEventDefaults(event)\n if (displayDeletion && !showDeletePopover) setDisplayDeletion(false)\n }\n\n const onDropzoneClick = (event?: ReactMouseEvent | ReactTouchEvent) => {\n event && preventEventDefaults(event)\n if (isLoading) return\n if (isErrored) setIsErrored(false)\n if (imagePreviewUrl) {\n if (showDeletePopover) closeDeletePopover()\n return setDisplayDeletion(!displayDeletion)\n }\n fileInputRef.current?.click()\n }\n\n const onDropzoneKey = (event: ReactKeyboardEvent) => {\n if (showDeletePopover) return\n if (isEnterOrSpaceKey(event)) {\n onDropzoneClick()\n }\n }\n\n const onDeleteKey = (event: ReactKeyboardEvent) => {\n if (isEnterOrSpaceKey(event)) {\n openDeletePopover(event)\n }\n }\n\n const onDelete = () => {\n if (fileInputRef.current) fileInputRef.current.value = \"\"\n closeDeletePopover()\n setImagePreviewUrl(\"\")\n onPhotoDelete && onPhotoDelete()\n }\n\n const onDragEnter = (event: ReactDragEvent) => {\n preventEventDefaults(event)\n if (isErrored) setIsErrored(false)\n !imagePreviewUrl && setIsDragging(true)\n }\n\n const onDragLeave = (event: ReactDragEvent) => {\n preventEventDefaults(event)\n setIsDragging(false)\n }\n\n const processFile = async (fileToProcess: File) => {\n setIsDragging(false)\n setIsErrored(false)\n setIsLoading(true)\n\n const isValidFile = await validateFile(\n fileToProcess,\n (fileToValidate, extension) => {\n const maxFileSize = ACCEPTED_MAX_SIZE_MB * 1000 * 1000\n const acceptedFileTypes = ACCEPTED_PHOTOS_TYPES\n\n if (fileToValidate.size > maxFileSize) {\n return false\n } else if (!extension || !acceptedFileTypes.includes(extension)) {\n return false\n } else {\n return true\n }\n }\n )\n\n if (isValidFile) {\n const imageSrc = URL.createObjectURL(fileToProcess)\n setImagePreviewUrl(imageSrc)\n await onDropped(fileToProcess)\n setIsLoading(false)\n } else {\n setIsLoading(false)\n setIsErrored(true)\n setTimeout(() => {\n setIsErrored(false)\n }, ERROR_DISPLAY_TIME)\n }\n }\n\n const onFileInputChanged = (event: ReactChangeEvent<HTMLInputElement>) => {\n if (event.target.files?.length) {\n processFile(event.target.files[0])\n }\n }\n\n const onDrop = (event: ReactDragEvent<HTMLDivElement>) => {\n preventEventDefaults(event)\n if (event.dataTransfer?.files?.length && !imagePreviewUrl) {\n processFile(event.dataTransfer.files[0])\n }\n }\n\n const onDeleteButtonClick = showDeletePopover\n ? closeDeletePopover\n : openDeletePopover\n\n return (\n <div\n tabIndex={0}\n className={cx(\"cobalt-photo-dropzone\", className, {\n \"cobalt-photo-dropzone--filled\": imagePreviewUrl,\n \"cobalt-photo-dropzone--dragging\": isDragging,\n \"cobalt-photo-dropzone--loading\": isLoading,\n \"cobalt-photo-dropzone--errored\": isErrored,\n })}\n onMouseEnter={onDropzoneMouseEnter}\n onMouseLeave={onDropzoneMouseLeave}\n onDragEnter={onDragEnter}\n onDragLeave={onDragLeave}\n // Not on click because we also use mouseEnter listener\n onMouseUp={onDropzoneClick}\n onTouchEnd={onDropzoneClick}\n onKeyUp={onDropzoneKey}\n onDrop={onDrop}\n // Need to reset those listeners to avoid default browser behaviour\n onDragStart={preventEventDefaults}\n onDragEnd={preventEventDefaults}\n onDragOver={preventEventDefaults}\n >\n {isErrored && (\n <div className=\"cobalt-photo-dropzone__description\">\n <ContextualWarningCircleFilledIcon color=\"red\" />\n {errorContent(ACCEPTED_TYPES_LOCALE_STRING, ACCEPTED_MAX_SIZE_MB)}\n </div>\n )}\n {isLoading && (\n <div className=\"cobalt-photo-dropzone__description\">\n <LoadingIcon />\n </div>\n )}\n {!isLoading &&\n !isErrored &&\n (imagePreviewUrl ? (\n <>\n <img\n className=\"cobalt-photo-dropzone__preview\"\n src={imagePreviewUrl}\n />\n <div>\n <button\n className={cx(\"cobalt-photo-dropzone__delete-button\", {\n \"cobalt-photo-dropzone__delete-button--triggered\":\n displayDeletion,\n })}\n ref={deleteButtonRef}\n // Must follow the click listeners on the dropzone,\n // in order to have the correct events bubbling\n onTouchEnd={onDeleteButtonClick}\n onMouseUp={onDeleteButtonClick}\n onKeyUp={onDeleteKey}\n >\n <BinIcon color=\"indigo\" />\n </button>\n <Popover\n targetRef={deleteButtonRef}\n isOpen={showDeletePopover}\n close={closeDeletePopover}\n placement=\"left-start\"\n distance={12}\n bodySpacing={false}\n arrow\n >\n {deletePopoverContent(onDelete, closeDeletePopover)}\n </Popover>\n </div>\n </>\n ) : (\n <div className=\"cobalt-photo-dropzone__description cobalt-photo-dropzone__description--strong\">\n {description && <div>{description}</div>}\n <PlusIcon />\n </div>\n ))}\n <input\n ref={fileInputRef}\n className=\"cobalt-photo-dropzone__hidden-input\"\n type=\"file\"\n onChange={onFileInputChanged}\n accept={ACCEPTED_PHOTOS_TYPES.map((ext) => `.${ext}`).join(\",\")}\n multiple={false}\n />\n </div>\n )\n}\n\nexport default PhotoDropzone\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/PhotoDropzone/index.tsx"],"sourcesContent":["import React, {\n useState,\n DragEvent as ReactDragEvent,\n useRef,\n TouchEvent as ReactTouchEvent,\n ChangeEvent as ReactChangeEvent,\n MouseEvent as ReactMouseEvent,\n KeyboardEvent as ReactKeyboardEvent,\n ReactNode,\n} from \"react\"\nimport cx from \"classnames\"\nimport {\n PlusIcon,\n BinIcon,\n LoadingIcon,\n ContextualWarningCircleFilledIcon,\n} from \"../Icon\"\nimport { validateFile } from \"../utils/validateFile\"\nimport Popover from \"../Popover\"\nimport Modal from \"../Modal\"\n\nconst ACCEPTED_MAX_SIZE_MB = 10\nconst ACCEPTED_PHOTOS_TYPES = [\"jpg\", \"jpeg\", \"png\", \"gif\"]\nconst ERROR_DISPLAY_TIME = 6000\nconst ACCEPTED_TYPES_LOCALE_STRING = ACCEPTED_PHOTOS_TYPES.join(\", \")\n\nexport type PhotoDropzonePropsType = {\n className?: string\n description?: string\n deleteContent: (onDelete: () => void, close: () => void) => ReactNode\n deleteContentMode?: \"popover\" | \"modal\"\n errorContent: (acceptedTypes: string, maxFileSize: number) => ReactNode\n onDropped: (file: File) => Promise<void> | void\n onPhotoDelete?: () => void\n initialImageUrl?: string\n}\n\nconst preventEventDefaults = (\n e: ReactDragEvent | ReactMouseEvent | ReactKeyboardEvent | ReactTouchEvent\n) => {\n e.preventDefault && e.preventDefault()\n e.stopPropagation && e.stopPropagation()\n}\n\nconst isEnterOrSpaceKey = (event: ReactKeyboardEvent) =>\n event.key === \"Enter\" || event.key === \" \"\n\nconst PhotoDropzone = ({\n className,\n description,\n deleteContent,\n errorContent,\n onDropped,\n onPhotoDelete,\n deleteContentMode = \"popover\",\n initialImageUrl = \"\",\n}: PhotoDropzonePropsType) => {\n const fileInputRef = useRef<HTMLInputElement>(null)\n const deleteButtonRef = useRef<HTMLButtonElement>(null)\n const [isDragging, setIsDragging] = useState(false)\n const [isLoading, setIsLoading] = useState(false)\n const [isErrored, setIsErrored] = useState(false)\n const [imagePreviewUrl, setImagePreviewUrl] = useState(initialImageUrl)\n const [displayDeletion, setDisplayDeletion] = useState(false)\n const [showDeletePopover, setShowDeletePopover] = useState(false)\n\n const openDeletePopover = (\n event?: ReactMouseEvent | ReactKeyboardEvent | ReactTouchEvent\n ) => {\n event && preventEventDefaults(event)\n setShowDeletePopover(true)\n }\n const closeDeletePopover = (event?: ReactMouseEvent | ReactTouchEvent) => {\n event && preventEventDefaults(event)\n setShowDeletePopover(false)\n }\n\n const onDropzoneMouseEnter = (event?: ReactMouseEvent) => {\n event && preventEventDefaults(event)\n if (imagePreviewUrl) setDisplayDeletion(true)\n }\n\n const onDropzoneMouseLeave = (event?: ReactMouseEvent) => {\n event && preventEventDefaults(event)\n if (displayDeletion && !showDeletePopover) setDisplayDeletion(false)\n }\n\n const onDropzoneClick = (event?: ReactMouseEvent | ReactTouchEvent) => {\n event && preventEventDefaults(event)\n if (isLoading) return\n if (isErrored) setIsErrored(false)\n if (imagePreviewUrl) {\n if (showDeletePopover) closeDeletePopover()\n return setDisplayDeletion(!displayDeletion)\n }\n fileInputRef.current?.click()\n }\n\n const onDropzoneKey = (event: ReactKeyboardEvent) => {\n if (showDeletePopover) return\n if (isEnterOrSpaceKey(event)) {\n onDropzoneClick()\n }\n }\n\n const onDeleteKey = (event: ReactKeyboardEvent) => {\n if (isEnterOrSpaceKey(event)) {\n openDeletePopover(event)\n }\n }\n\n const onDelete = () => {\n if (fileInputRef.current) fileInputRef.current.value = \"\"\n closeDeletePopover()\n setImagePreviewUrl(\"\")\n onPhotoDelete && onPhotoDelete()\n }\n\n const onDragEnter = (event: ReactDragEvent) => {\n preventEventDefaults(event)\n if (isErrored) setIsErrored(false)\n !imagePreviewUrl && setIsDragging(true)\n }\n\n const onDragLeave = (event: ReactDragEvent) => {\n preventEventDefaults(event)\n setIsDragging(false)\n }\n\n const processFile = async (fileToProcess: File) => {\n setIsDragging(false)\n setIsErrored(false)\n setIsLoading(true)\n\n const isValidFile = await validateFile(\n fileToProcess,\n (fileToValidate, extension) => {\n const maxFileSize = ACCEPTED_MAX_SIZE_MB * 1000 * 1000\n const acceptedFileTypes = ACCEPTED_PHOTOS_TYPES\n\n if (fileToValidate.size > maxFileSize) {\n return false\n } else if (!extension || !acceptedFileTypes.includes(extension)) {\n return false\n } else {\n return true\n }\n }\n )\n\n if (isValidFile) {\n const imageSrc = URL.createObjectURL(fileToProcess)\n setImagePreviewUrl(imageSrc)\n await onDropped(fileToProcess)\n setIsLoading(false)\n } else {\n setIsLoading(false)\n setIsErrored(true)\n setTimeout(() => {\n setIsErrored(false)\n }, ERROR_DISPLAY_TIME)\n }\n }\n\n const onFileInputChanged = (event: ReactChangeEvent<HTMLInputElement>) => {\n if (event.target.files?.length) {\n processFile(event.target.files[0])\n }\n }\n\n const onDrop = (event: ReactDragEvent<HTMLDivElement>) => {\n preventEventDefaults(event)\n if (event.dataTransfer?.files?.length && !imagePreviewUrl) {\n processFile(event.dataTransfer.files[0])\n }\n }\n\n const onDeleteButtonClick = showDeletePopover\n ? closeDeletePopover\n : openDeletePopover\n\n return (\n <div\n tabIndex={0}\n className={cx(\"cobalt-photo-dropzone\", className, {\n \"cobalt-photo-dropzone--filled\": imagePreviewUrl,\n \"cobalt-photo-dropzone--dragging\": isDragging,\n \"cobalt-photo-dropzone--loading\": isLoading,\n \"cobalt-photo-dropzone--errored\": isErrored,\n })}\n onMouseEnter={onDropzoneMouseEnter}\n onMouseLeave={onDropzoneMouseLeave}\n onDragEnter={onDragEnter}\n onDragLeave={onDragLeave}\n // Not on click because we also use mouseEnter listener\n onMouseUp={onDropzoneClick}\n onTouchEnd={onDropzoneClick}\n onKeyUp={onDropzoneKey}\n onDrop={onDrop}\n // Need to reset those listeners to avoid default browser behaviour\n onDragStart={preventEventDefaults}\n onDragEnd={preventEventDefaults}\n onDragOver={preventEventDefaults}\n >\n {isErrored && (\n <div className=\"cobalt-photo-dropzone__description\">\n <ContextualWarningCircleFilledIcon color=\"red\" />\n {errorContent(ACCEPTED_TYPES_LOCALE_STRING, ACCEPTED_MAX_SIZE_MB)}\n </div>\n )}\n {isLoading && (\n <div className=\"cobalt-photo-dropzone__description\">\n <LoadingIcon />\n </div>\n )}\n {!isLoading &&\n !isErrored &&\n (imagePreviewUrl ? (\n <>\n <img\n className=\"cobalt-photo-dropzone__preview\"\n src={imagePreviewUrl}\n />\n <div>\n <button\n className={cx(\"cobalt-photo-dropzone__delete-button\", {\n \"cobalt-photo-dropzone__delete-button--triggered\":\n displayDeletion,\n })}\n ref={deleteButtonRef}\n // Must follow the click listeners on the dropzone,\n // in order to have the correct events bubbling\n onTouchEnd={onDeleteButtonClick}\n onMouseUp={onDeleteButtonClick}\n onKeyUp={onDeleteKey}\n >\n <BinIcon color=\"indigo\" />\n </button>\n {deleteContentMode === \"modal\" && (\n <Modal\n isOpen={showDeletePopover}\n aria-label=\"delete\"\n bodySpacing={false}\n >\n {deleteContent(onDelete, closeDeletePopover)}\n </Modal>\n )}\n\n {deleteContentMode === \"popover\" && (\n <Popover\n targetRef={deleteButtonRef}\n isOpen={showDeletePopover}\n close={closeDeletePopover}\n placement=\"left-start\"\n distance={12}\n bodySpacing={false}\n arrow\n >\n {deleteContent(onDelete, closeDeletePopover)}\n </Popover>\n )}\n </div>\n </>\n ) : (\n <div className=\"cobalt-photo-dropzone__description cobalt-photo-dropzone__description--strong\">\n {description && <div>{description}</div>}\n <PlusIcon />\n </div>\n ))}\n <input\n ref={fileInputRef}\n className=\"cobalt-photo-dropzone__hidden-input\"\n type=\"file\"\n onChange={onFileInputChanged}\n accept={ACCEPTED_PHOTOS_TYPES.map((ext) => `.${ext}`).join(\",\")}\n multiple={false}\n />\n </div>\n )\n}\n\nexport default PhotoDropzone\n"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -55,6 +55,7 @@ export { default as LayoutStack } from './components/Layout/Components/LayoutSta
|
|
|
55
55
|
export { Fixed, Flexible, FlexibleWithConstraint } from './components/Layout/Surfaces/index.js';
|
|
56
56
|
export { default as useBreakpoint } from './hooks/useBreakpoint.js';
|
|
57
57
|
export { getMonthDaysByWeeks, getWeekDays } from './components/Calendar/utils.js';
|
|
58
|
+
export { default as MultiStepModal } from './components/Modal/MultiStepModal.js';
|
|
58
59
|
export { default as AccountDetailsIcon } from './components/Icon/__generated__/AccountDetailsIcon.js';
|
|
59
60
|
export { default as AddPictureIcon } from './components/Icon/__generated__/AddPictureIcon.js';
|
|
60
61
|
export { default as AirConditioningIcon } from './components/Icon/__generated__/AirConditioningIcon.js';
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ModalPropsType } from ".";
|
|
3
|
+
type StepComponentType<T> = (props: {
|
|
4
|
+
navigation: {
|
|
5
|
+
nextStep: () => void;
|
|
6
|
+
previousStep: () => void;
|
|
7
|
+
closeModal: () => void;
|
|
8
|
+
};
|
|
9
|
+
data: T;
|
|
10
|
+
}) => React.ReactNode;
|
|
11
|
+
export type ModalStepType<T> = {
|
|
12
|
+
title: StepComponentType<T>;
|
|
13
|
+
content: StepComponentType<T>;
|
|
14
|
+
footer?: StepComponentType<T>;
|
|
15
|
+
};
|
|
16
|
+
type MultiStepsModalProps<T = null> = {
|
|
17
|
+
stepData?: T;
|
|
18
|
+
close: () => void;
|
|
19
|
+
onHidden?: (currentStepIndex: number) => void;
|
|
20
|
+
steps: ModalStepType<T>[];
|
|
21
|
+
useMidSizeHeight?: boolean;
|
|
22
|
+
} & Omit<ModalPropsType, "children" | "onHidden" | "close">;
|
|
23
|
+
declare const MultiStepModal: <T>({ stepData, close, steps, onHidden, useMidSizeHeight, ...modalProps }: MultiStepsModalProps<T>) => React.JSX.Element;
|
|
24
|
+
export default MultiStepModal;
|
|
@@ -36,7 +36,7 @@ export type ModalPropsType = {
|
|
|
36
36
|
/**
|
|
37
37
|
* Modal title
|
|
38
38
|
*/
|
|
39
|
-
title?:
|
|
39
|
+
title?: React.ReactNode;
|
|
40
40
|
/**
|
|
41
41
|
* Disable/Enable body paddings (enabled by default)
|
|
42
42
|
*/
|
|
@@ -75,3 +75,4 @@ declare const _default: React.ForwardRefExoticComponent<ModalPropsType & React.R
|
|
|
75
75
|
Footer: (_props: ModalFooterPropsType) => null;
|
|
76
76
|
};
|
|
77
77
|
export default _default;
|
|
78
|
+
export { default as MultiStepModal, type ModalStepType } from "./MultiStepModal";
|
|
@@ -2,11 +2,12 @@ import React, { ReactNode } from "react";
|
|
|
2
2
|
export type PhotoDropzonePropsType = {
|
|
3
3
|
className?: string;
|
|
4
4
|
description?: string;
|
|
5
|
-
|
|
5
|
+
deleteContent: (onDelete: () => void, close: () => void) => ReactNode;
|
|
6
|
+
deleteContentMode?: "popover" | "modal";
|
|
6
7
|
errorContent: (acceptedTypes: string, maxFileSize: number) => ReactNode;
|
|
7
8
|
onDropped: (file: File) => Promise<void> | void;
|
|
8
9
|
onPhotoDelete?: () => void;
|
|
9
10
|
initialImageUrl?: string;
|
|
10
11
|
};
|
|
11
|
-
declare const PhotoDropzone: ({ className, description,
|
|
12
|
+
declare const PhotoDropzone: ({ className, description, deleteContent, errorContent, onDropped, onPhotoDelete, deleteContentMode, initialImageUrl, }: PhotoDropzonePropsType) => React.JSX.Element;
|
|
12
13
|
export default PhotoDropzone;
|
package/types/src/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export { CalendarDayPicker } from "./components/Calendar/CalendarDayPicker";
|
|
|
16
16
|
export { Card, CardSection } from "./components/Card";
|
|
17
17
|
export * from "./components/Icon";
|
|
18
18
|
export { ContainedIcon } from "./components/ContainedIcon";
|
|
19
|
-
export { default as Modal } from "./components/Modal";
|
|
19
|
+
export { default as Modal, MultiStepModal, type ModalStepType, } from "./components/Modal";
|
|
20
20
|
export { Note } from "./components/Note";
|
|
21
21
|
export { default as PhotoDropzone } from "./components/PhotoDropzone";
|
|
22
22
|
export { default as Pagination } from "./components/Pagination";
|