@trackunit/react-form-components 0.0.343-alpha-869e1cbc10.0 → 0.0.343
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/index.cjs.js
CHANGED
|
@@ -49,6 +49,8 @@ var ReactAsyncSelect__default = /*#__PURE__*/_interopDefaultLegacy(ReactAsyncSel
|
|
|
49
49
|
|
|
50
50
|
var defaultTranslations = {
|
|
51
51
|
"clearIndicator.icon.tooltip.clearAll": "Clear all",
|
|
52
|
+
"dropzone.input.title": "Drag-and-drop file input",
|
|
53
|
+
"dropzone.label.default": "<clickable>Browse</clickable> or drag files here...",
|
|
52
54
|
"phoneField.error.INVALID_COUNTRY": "The country code is not valid",
|
|
53
55
|
"phoneField.error.INVALID_LENGTH": "The phone number is not valid",
|
|
54
56
|
"phoneField.error.INVALID_NUMBER": "The phone number is not valid",
|
|
@@ -95,6 +97,10 @@ const translations = {
|
|
|
95
97
|
* Local useTranslation for this specific library
|
|
96
98
|
*/
|
|
97
99
|
const useTranslation = () => i18nLibraryTranslation.useNamespaceTranslation(namespace);
|
|
100
|
+
/**
|
|
101
|
+
* Trans for this specific library.
|
|
102
|
+
*/
|
|
103
|
+
const Trans = (props) => (jsxRuntime.jsx(i18nLibraryTranslation.NamespaceTrans, Object.assign({}, props, { namespace: namespace })));
|
|
98
104
|
/**
|
|
99
105
|
* Registers the translations for this library
|
|
100
106
|
*/
|
|
@@ -630,17 +636,32 @@ const cvaDropZoneLabel = cssClassVarianceUtilities.cvaMerge([
|
|
|
630
636
|
"flex",
|
|
631
637
|
"justify-center",
|
|
632
638
|
]);
|
|
639
|
+
const cvaDropZoneIconBackground = cssClassVarianceUtilities.cvaMerge(["relative", "flex", "items-center", "justify-center", "rounded-full", "p-3"], {
|
|
640
|
+
variants: {
|
|
641
|
+
invalid: { true: ["bg-red-100"], false: ["bg-slate-200"] },
|
|
642
|
+
},
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
*
|
|
647
|
+
* Default UX-intuitive label for the DropZone - can be overwritten by the label prop
|
|
648
|
+
*/
|
|
649
|
+
const DropZoneDefaultLabel = () => (jsxRuntime.jsx(Trans, { components: {
|
|
650
|
+
clickable: jsxRuntime.jsx("span", { className: "text-primary-600 hover:text-primary-700 cursor-pointer underline" }),
|
|
651
|
+
}, i18nKey: "dropzone.label.default", values: {} }));
|
|
633
652
|
|
|
634
653
|
/**
|
|
635
|
-
* The Drop Zone can be used to drag and drop files
|
|
654
|
+
* The Drop Zone can be used to drag and drop files or to browse and select files from the file system.
|
|
636
655
|
*
|
|
637
656
|
* @param {DropZoneProps} props - The props for the DropZone component
|
|
638
657
|
* @returns {JSX.Element} DropZone component
|
|
639
658
|
*/
|
|
640
659
|
const DropZone = (_a) => {
|
|
641
|
-
var { className, dataTestId, filesSelected, label, size = "large", isInvalid = false, disabled = false } = _a, rest = __rest(_a, ["className", "dataTestId", "filesSelected", "label", "size", "isInvalid", "disabled"]);
|
|
642
|
-
const [dragActive, setDragActive] =
|
|
643
|
-
const [fileDropped, setFileDropped] =
|
|
660
|
+
var { className, dataTestId, filesSelected, label = jsxRuntime.jsx(DropZoneDefaultLabel, {}), size = "large", isInvalid = false, disabled = false, accept } = _a, rest = __rest(_a, ["className", "dataTestId", "filesSelected", "label", "size", "isInvalid", "disabled", "accept"]);
|
|
661
|
+
const [dragActive, setDragActive] = React.useState(false);
|
|
662
|
+
const [fileDropped, setFileDropped] = React.useState(false);
|
|
663
|
+
const [t] = useTranslation();
|
|
664
|
+
const inputLabelRef = React.useRef(null);
|
|
644
665
|
// function that handles drag enter, drag leave and drag over
|
|
645
666
|
const handleDrag = (e) => {
|
|
646
667
|
e.preventDefault();
|
|
@@ -660,7 +681,7 @@ const DropZone = (_a) => {
|
|
|
660
681
|
filesSelected(e.target.files);
|
|
661
682
|
}
|
|
662
683
|
};
|
|
663
|
-
//
|
|
684
|
+
//function to handle drop
|
|
664
685
|
const handleDrop = (e) => {
|
|
665
686
|
e.preventDefault();
|
|
666
687
|
e.stopPropagation();
|
|
@@ -670,12 +691,22 @@ const DropZone = (_a) => {
|
|
|
670
691
|
setFileDropped(true);
|
|
671
692
|
}
|
|
672
693
|
};
|
|
694
|
+
//function to handle focusable button click (for accessibility)
|
|
695
|
+
const handleButtonClick = (e) => {
|
|
696
|
+
var _a;
|
|
697
|
+
e.preventDefault();
|
|
698
|
+
e.stopPropagation();
|
|
699
|
+
if (disabled) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
(_a = inputLabelRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
703
|
+
};
|
|
673
704
|
return (jsxRuntime.jsxs("div", Object.assign({ className: cvaDropZone({ size, dropComplete: fileDropped, dragActive, disabled, invalid: isInvalid, className }), "data-testid": dataTestId, onClick: e => {
|
|
674
705
|
if (disabled) {
|
|
675
706
|
e.preventDefault();
|
|
676
707
|
e.stopPropagation();
|
|
677
708
|
}
|
|
678
|
-
}, onDragEnter: handleDrag, onDragLeave: handleDrag, onDragOver: handleDrag, onDrop: handleDrop }, rest, { children: [jsxRuntime.jsx("input", { className: "hidden", id: "input-file-upload", onChange: handleChange, title: "
|
|
709
|
+
}, onDragEnter: handleDrag, onDragLeave: handleDrag, onDragOver: handleDrag, onDrop: handleDrop }, rest, { children: [jsxRuntime.jsx("input", { accept: accept, className: "hidden", id: "input-file-upload", onChange: handleChange, title: t("dropzone.input.title"), type: "file" }), jsxRuntime.jsxs("label", { className: cvaDropZoneLabel(), "data-testid": dataTestId && `${dataTestId}-label`, htmlFor: "input-file-upload", ref: inputLabelRef, children: [jsxRuntime.jsx("div", { className: cvaDropZoneIconBackground({ invalid: isInvalid }), children: jsxRuntime.jsx(reactComponents.Icon, { className: !isInvalid ? "text-gray-400" : "", color: isInvalid ? "danger" : "neutral", name: "ArrowUpCircle", type: "solid" }) }), jsxRuntime.jsx("button", { disabled: disabled, onClick: handleButtonClick, children: label })] })] })));
|
|
679
710
|
};
|
|
680
711
|
|
|
681
712
|
// Doing the same check as we do on the backend
|
package/index.esm.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
|
|
2
|
+
import { registerTranslations, useNamespaceTranslation, NamespaceTrans } from '@trackunit/i18n-library-translation';
|
|
3
3
|
import { IconButton, Icon, Tooltip, Heading, Text, MenuItem, Tag, Spinner } from '@trackunit/react-components';
|
|
4
4
|
import { useCopyToClipboard } from 'react-use';
|
|
5
5
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
6
6
|
import * as React from 'react';
|
|
7
|
-
import React__default, { useMemo, forwardRef,
|
|
7
|
+
import React__default, { useMemo, forwardRef, useState, useRef, useCallback, cloneElement, useEffect, useImperativeHandle } from 'react';
|
|
8
8
|
import { v4 } from 'uuid';
|
|
9
9
|
import { format } from 'date-fns';
|
|
10
10
|
import parsePhoneNumberFromString, { isSupportedCountry, getCountries, getCountryCallingCode, AsYouType, parseIncompletePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';
|
|
@@ -19,6 +19,8 @@ import { z } from 'zod';
|
|
|
19
19
|
|
|
20
20
|
var defaultTranslations = {
|
|
21
21
|
"clearIndicator.icon.tooltip.clearAll": "Clear all",
|
|
22
|
+
"dropzone.input.title": "Drag-and-drop file input",
|
|
23
|
+
"dropzone.label.default": "<clickable>Browse</clickable> or drag files here...",
|
|
22
24
|
"phoneField.error.INVALID_COUNTRY": "The country code is not valid",
|
|
23
25
|
"phoneField.error.INVALID_LENGTH": "The phone number is not valid",
|
|
24
26
|
"phoneField.error.INVALID_NUMBER": "The phone number is not valid",
|
|
@@ -65,6 +67,10 @@ const translations = {
|
|
|
65
67
|
* Local useTranslation for this specific library
|
|
66
68
|
*/
|
|
67
69
|
const useTranslation = () => useNamespaceTranslation(namespace);
|
|
70
|
+
/**
|
|
71
|
+
* Trans for this specific library.
|
|
72
|
+
*/
|
|
73
|
+
const Trans = (props) => (jsx(NamespaceTrans, Object.assign({}, props, { namespace: namespace })));
|
|
68
74
|
/**
|
|
69
75
|
* Registers the translations for this library
|
|
70
76
|
*/
|
|
@@ -600,17 +606,32 @@ const cvaDropZoneLabel = cvaMerge([
|
|
|
600
606
|
"flex",
|
|
601
607
|
"justify-center",
|
|
602
608
|
]);
|
|
609
|
+
const cvaDropZoneIconBackground = cvaMerge(["relative", "flex", "items-center", "justify-center", "rounded-full", "p-3"], {
|
|
610
|
+
variants: {
|
|
611
|
+
invalid: { true: ["bg-red-100"], false: ["bg-slate-200"] },
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
*
|
|
617
|
+
* Default UX-intuitive label for the DropZone - can be overwritten by the label prop
|
|
618
|
+
*/
|
|
619
|
+
const DropZoneDefaultLabel = () => (jsx(Trans, { components: {
|
|
620
|
+
clickable: jsx("span", { className: "text-primary-600 hover:text-primary-700 cursor-pointer underline" }),
|
|
621
|
+
}, i18nKey: "dropzone.label.default", values: {} }));
|
|
603
622
|
|
|
604
623
|
/**
|
|
605
|
-
* The Drop Zone can be used to drag and drop files
|
|
624
|
+
* The Drop Zone can be used to drag and drop files or to browse and select files from the file system.
|
|
606
625
|
*
|
|
607
626
|
* @param {DropZoneProps} props - The props for the DropZone component
|
|
608
627
|
* @returns {JSX.Element} DropZone component
|
|
609
628
|
*/
|
|
610
629
|
const DropZone = (_a) => {
|
|
611
|
-
var { className, dataTestId, filesSelected, label, size = "large", isInvalid = false, disabled = false } = _a, rest = __rest(_a, ["className", "dataTestId", "filesSelected", "label", "size", "isInvalid", "disabled"]);
|
|
612
|
-
const [dragActive, setDragActive] =
|
|
613
|
-
const [fileDropped, setFileDropped] =
|
|
630
|
+
var { className, dataTestId, filesSelected, label = jsx(DropZoneDefaultLabel, {}), size = "large", isInvalid = false, disabled = false, accept } = _a, rest = __rest(_a, ["className", "dataTestId", "filesSelected", "label", "size", "isInvalid", "disabled", "accept"]);
|
|
631
|
+
const [dragActive, setDragActive] = useState(false);
|
|
632
|
+
const [fileDropped, setFileDropped] = useState(false);
|
|
633
|
+
const [t] = useTranslation();
|
|
634
|
+
const inputLabelRef = useRef(null);
|
|
614
635
|
// function that handles drag enter, drag leave and drag over
|
|
615
636
|
const handleDrag = (e) => {
|
|
616
637
|
e.preventDefault();
|
|
@@ -630,7 +651,7 @@ const DropZone = (_a) => {
|
|
|
630
651
|
filesSelected(e.target.files);
|
|
631
652
|
}
|
|
632
653
|
};
|
|
633
|
-
//
|
|
654
|
+
//function to handle drop
|
|
634
655
|
const handleDrop = (e) => {
|
|
635
656
|
e.preventDefault();
|
|
636
657
|
e.stopPropagation();
|
|
@@ -640,12 +661,22 @@ const DropZone = (_a) => {
|
|
|
640
661
|
setFileDropped(true);
|
|
641
662
|
}
|
|
642
663
|
};
|
|
664
|
+
//function to handle focusable button click (for accessibility)
|
|
665
|
+
const handleButtonClick = (e) => {
|
|
666
|
+
var _a;
|
|
667
|
+
e.preventDefault();
|
|
668
|
+
e.stopPropagation();
|
|
669
|
+
if (disabled) {
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
(_a = inputLabelRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
673
|
+
};
|
|
643
674
|
return (jsxs("div", Object.assign({ className: cvaDropZone({ size, dropComplete: fileDropped, dragActive, disabled, invalid: isInvalid, className }), "data-testid": dataTestId, onClick: e => {
|
|
644
675
|
if (disabled) {
|
|
645
676
|
e.preventDefault();
|
|
646
677
|
e.stopPropagation();
|
|
647
678
|
}
|
|
648
|
-
}, onDragEnter: handleDrag, onDragLeave: handleDrag, onDragOver: handleDrag, onDrop: handleDrop }, rest, { children: [jsx("input", { className: "hidden", id: "input-file-upload", onChange: handleChange, title: "
|
|
679
|
+
}, onDragEnter: handleDrag, onDragLeave: handleDrag, onDragOver: handleDrag, onDrop: handleDrop }, rest, { children: [jsx("input", { accept: accept, className: "hidden", id: "input-file-upload", onChange: handleChange, title: t("dropzone.input.title"), type: "file" }), jsxs("label", { className: cvaDropZoneLabel(), "data-testid": dataTestId && `${dataTestId}-label`, htmlFor: "input-file-upload", ref: inputLabelRef, children: [jsx("div", { className: cvaDropZoneIconBackground({ invalid: isInvalid }), children: jsx(Icon, { className: !isInvalid ? "text-gray-400" : "", color: isInvalid ? "danger" : "neutral", name: "ArrowUpCircle", type: "solid" }) }), jsx("button", { disabled: disabled, onClick: handleButtonClick, children: label })] })] })));
|
|
649
680
|
};
|
|
650
681
|
|
|
651
682
|
// Doing the same check as we do on the backend
|
package/package.json
CHANGED
|
@@ -4,9 +4,9 @@ import { BaseInputProps } from "../BaseInput";
|
|
|
4
4
|
type BaseInputExposedProps = Omit<BaseInputProps, "type" | "suffix" | "prefix" | "addonAfter" | "addonBefore" | "actions" | "placeholder" | "fieldSize" | "size" | "nonInteractive">;
|
|
5
5
|
export interface DropZoneProps extends BaseInputExposedProps, CommonProps {
|
|
6
6
|
/**
|
|
7
|
-
* A string to set
|
|
7
|
+
* A JSX element or a string to set a focusable label in Drop Zone. If not provided, the default label will be used.
|
|
8
8
|
*/
|
|
9
|
-
label
|
|
9
|
+
label?: JSX.Element | string;
|
|
10
10
|
/**
|
|
11
11
|
* A flag to disable the drop zone.
|
|
12
12
|
*/
|
|
@@ -25,10 +25,10 @@ export interface DropZoneProps extends BaseInputExposedProps, CommonProps {
|
|
|
25
25
|
filesSelected: (file: FileList) => void;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* The Drop Zone can be used to drag and drop files
|
|
28
|
+
* The Drop Zone can be used to drag and drop files or to browse and select files from the file system.
|
|
29
29
|
*
|
|
30
30
|
* @param {DropZoneProps} props - The props for the DropZone component
|
|
31
31
|
* @returns {JSX.Element} DropZone component
|
|
32
32
|
*/
|
|
33
|
-
export declare const DropZone: ({ className, dataTestId, filesSelected, label, size, isInvalid, disabled, ...rest }: DropZoneProps) => JSX.Element;
|
|
33
|
+
export declare const DropZone: ({ className, dataTestId, filesSelected, label, size, isInvalid, disabled, accept, ...rest }: DropZoneProps) => JSX.Element;
|
|
34
34
|
export {};
|
|
@@ -6,3 +6,6 @@ export declare const cvaDropZone: (props?: ({
|
|
|
6
6
|
invalid?: boolean | null | undefined;
|
|
7
7
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
8
8
|
export declare const cvaDropZoneLabel: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
9
|
+
export declare const cvaDropZoneIconBackground: (props?: ({
|
|
10
|
+
invalid?: boolean | null | undefined;
|
|
11
|
+
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
package/src/translation.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export declare const translations: TranslationResource<TranslationKeys>;
|
|
|
15
15
|
/**
|
|
16
16
|
* Local useTranslation for this specific library
|
|
17
17
|
*/
|
|
18
|
-
export declare const useTranslation: () => [TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">, import("i18next").i18n, boolean] & {
|
|
19
|
-
t: TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">;
|
|
18
|
+
export declare const useTranslation: () => [TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">, import("i18next").i18n, boolean] & {
|
|
19
|
+
t: TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">;
|
|
20
20
|
i18n: import("i18next").i18n;
|
|
21
21
|
ready: boolean;
|
|
22
22
|
};
|