@torq-north/react-tools 1.2.0 → 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/dist/index.cjs CHANGED
@@ -817,6 +817,63 @@ var DropIndicator = material.styled(material.Box, {
817
817
  });
818
818
  });
819
819
 
820
+ function isAsset(file) {
821
+ return "id" in file;
822
+ }
823
+
824
+ var FileBox = material.styled(material.Box)(function (_a) {
825
+ var disableInteraction = _a.disableInteraction, theme = _a.theme;
826
+ var alterFunc = theme.palette.mode === "dark" ? material.lighten : material.darken;
827
+ return {
828
+ transition: "0.2s",
829
+ cursor: disableInteraction ? undefined : "pointer",
830
+ "&:hover": disableInteraction
831
+ ? undefined
832
+ : {
833
+ backgroundColor: alterFunc(theme.palette.background.paper, 0.05),
834
+ "&:active": {
835
+ transition: "0s",
836
+ backgroundColor: alterFunc(theme.palette.background.paper, 0.1),
837
+ },
838
+ },
839
+ "&:nth-of-type(odd)": {
840
+ backgroundColor: alterFunc(theme.palette.background.paper, 0.05),
841
+ "&:hover": disableInteraction
842
+ ? undefined
843
+ : {
844
+ backgroundColor: alterFunc(theme.palette.background.paper, 0.1),
845
+ "&:active": {
846
+ backgroundColor: alterFunc(theme.palette.background.paper, 0.15),
847
+ },
848
+ },
849
+ },
850
+ };
851
+ });
852
+
853
+ var UnstyledLink = material.styled("a")({
854
+ color: "unset",
855
+ textDecoration: "none",
856
+ });
857
+ function IndividualFile(_a) {
858
+ var file = _a.file, disableLink = _a.disableLink, allowDelete = _a.allowDelete, onDelete = _a.onDelete;
859
+ var isImage = isAsset(file)
860
+ ? file.mimeType.startsWith("image")
861
+ : ["png", "jpg", "jpeg", "gif"].some(function (ext) { return file.name.endsWith(ext); });
862
+ var content = (jsxRuntime.jsxs(material.Stack, { p: 0.5, direction: "row", justifyContent: "space-between", children: [jsxRuntime.jsxs(material.Stack, { direction: "row", gap: 2, alignItems: "center", children: [isImage ? jsxRuntime.jsx(ImageIcon, {}) : jsxRuntime.jsx(FileIcon, {}), jsxRuntime.jsx(material.Typography, { children: isAsset(file) ? file.fileName : file.name }), file instanceof File && (jsxRuntime.jsx(material.Tooltip, { title: "New File", placement: "right", children: jsxRuntime.jsx(SparkleIcon, { color: "info" }) }))] }), allowDelete && (jsxRuntime.jsx(material.IconButton, { color: "error", onClick: function (e) {
863
+ e.stopPropagation();
864
+ onDelete && onDelete(file);
865
+ }, children: jsxRuntime.jsx(DeleteIcon, {}) }))] }));
866
+ return (jsxRuntime.jsxs(FileBox, { disableInteraction: disableLink, children: [!disableLink && (jsxRuntime.jsx(UnstyledLink, { href: isAsset(file) ? file.fullPath : "#", target: "_blank", children: content })), disableLink && content] }));
867
+ }
868
+
869
+ function FileDisplay(_a) {
870
+ var files = _a.files, individualFileProps = __rest(_a, ["files"]);
871
+ if (!Array.isArray(files)) {
872
+ return (jsxRuntime.jsx(material.Box, { children: jsxRuntime.jsx(IndividualFile, __assign({ file: files }, individualFileProps)) }));
873
+ }
874
+ return (jsxRuntime.jsx(material.Stack, { children: files.map(function (f) { return (jsxRuntime.jsx(IndividualFile, __assign({ file: f }, individualFileProps), isAsset(f) ? f.id : f.name)); }) }));
875
+ }
876
+
820
877
  var propTypes = {exports: {}};
821
878
 
822
879
  var reactIs = {exports: {}};
@@ -4797,24 +4854,21 @@ function arrayify(value) {
4797
4854
  }
4798
4855
  return Array.isArray(value) ? value : [value];
4799
4856
  }
4800
- function useFileEditorField(name, options) {
4801
- var _a = reactFinalForm.useField(name, __assign({ validate: function (v) {
4802
- return options.required && v == null ? "This field is required" : undefined;
4803
- } }, options.fieldProps)), input = _a.input, meta = _a.meta;
4804
- var values = React.useMemo(function () { return arrayify(input.value); }, [input.value]);
4805
- var _b = React.useState(false), showError = _b[0], setShowError = _b[1];
4806
- var _c = React.useState(""), errorMessage = _c[0], setErrorMessage = _c[1];
4807
- var _d = React.useState(false), dragOverDropzone = _d[0], setDragOverDropzone = _d[1];
4857
+ function useFileEditor(value, onChange, options) {
4858
+ var values = React.useMemo(function () { return arrayify(value); }, [value]);
4859
+ var _a = React.useState(false), showError = _a[0], setShowError = _a[1];
4860
+ var _b = React.useState(""), errorMessage = _b[0], setErrorMessage = _b[1];
4861
+ var _c = React.useState(false), dragOverDropzone = _c[0], setDragOverDropzone = _c[1];
4808
4862
  var multiple = options.multiple, disabled = options.disabled, otherOptions = __rest(options, ["multiple", "disabled"]);
4809
- var _e = useDropzone(__assign({ multiple: multiple, noClick: multiple || values.length == 0, noKeyboard: multiple, disabled: disabled, onDragEnter: function () { return setDragOverDropzone(true); }, onDragOver: function (e) {
4863
+ var _d = useDropzone(__assign({ multiple: multiple, noClick: multiple || values.length == 0, noKeyboard: multiple, disabled: disabled, onDragEnter: function () { return setDragOverDropzone(true); }, onDragOver: function (e) {
4810
4864
  e.preventDefault();
4811
4865
  e.stopPropagation();
4812
4866
  }, onDragLeave: function () { return setDragOverDropzone(false); }, onDrop: function () { return setDragOverDropzone(false); }, onDropAccepted: function (acceptedFiles) {
4813
4867
  if (multiple) {
4814
- input.onChange((values !== null && values !== void 0 ? values : []).concat(acceptedFiles));
4868
+ onChange((values !== null && values !== void 0 ? values : []).concat(acceptedFiles));
4815
4869
  }
4816
4870
  else {
4817
- input.onChange(acceptedFiles[0]);
4871
+ onChange(acceptedFiles[0]);
4818
4872
  }
4819
4873
  }, onDropRejected: function (fileRejections) {
4820
4874
  setShowError(true);
@@ -4822,17 +4876,13 @@ function useFileEditorField(name, options) {
4822
4876
  setErrorMessage("Multiple files cannot be added to this field");
4823
4877
  }
4824
4878
  else {
4825
- //Other than trying to add multiple files to a single input, the only other errors
4826
- // it could be would be size or type violations. Since those are case by case and kind
4827
- // of hard to cram into a single error message, it's easier to just cover all our bases
4828
- // with one message
4829
4879
  setErrorMessage("Some files were rejected because they do not fit the size restriction or are not the right file type");
4830
4880
  }
4831
- } }, otherOptions)), getRootProps = _e.getRootProps, getInputProps = _e.getInputProps, open = _e.open;
4881
+ } }, otherOptions)), getRootProps = _d.getRootProps, getInputProps = _d.getInputProps, open = _d.open;
4832
4882
  var removeFile = React.useCallback(function (file) {
4833
4883
  var _a, _b;
4834
4884
  if (!multiple) {
4835
- input.onChange(null);
4885
+ onChange(null);
4836
4886
  return;
4837
4887
  }
4838
4888
  var index = (_a = values === null || values === void 0 ? void 0 : values.findIndex(function (f) { return f === file; })) !== null && _a !== void 0 ? _a : -1;
@@ -4841,8 +4891,8 @@ function useFileEditorField(name, options) {
4841
4891
  }
4842
4892
  var copy = (_b = values === null || values === void 0 ? void 0 : values.slice()) !== null && _b !== void 0 ? _b : [];
4843
4893
  copy.splice(index, 1);
4844
- input.onChange(copy);
4845
- }, [multiple, input.onChange, values]);
4894
+ onChange(copy);
4895
+ }, [multiple, onChange, values]);
4846
4896
  return {
4847
4897
  dragOverDropzone: dragOverDropzone,
4848
4898
  getRootProps: getRootProps,
@@ -4853,77 +4903,37 @@ function useFileEditorField(name, options) {
4853
4903
  showError: showError,
4854
4904
  setShowError: setShowError,
4855
4905
  errorMessage: errorMessage,
4856
- meta: meta,
4857
4906
  };
4858
4907
  }
4859
4908
 
4860
- function isAsset(file) {
4861
- return "id" in file;
4862
- }
4863
-
4864
- var FileBox = material.styled(material.Box)(function (_a) {
4865
- var disableInteraction = _a.disableInteraction, theme = _a.theme;
4866
- var alterFunc = theme.palette.mode === "dark" ? material.lighten : material.darken;
4867
- return {
4868
- transition: "0.2s",
4869
- cursor: disableInteraction ? undefined : "pointer",
4870
- "&:hover": disableInteraction
4871
- ? undefined
4872
- : {
4873
- backgroundColor: alterFunc(theme.palette.background.paper, 0.05),
4874
- "&:active": {
4875
- transition: "0s",
4876
- backgroundColor: alterFunc(theme.palette.background.paper, 0.1),
4877
- },
4878
- },
4879
- "&:nth-of-type(odd)": {
4880
- backgroundColor: alterFunc(theme.palette.background.paper, 0.05),
4881
- "&:hover": disableInteraction
4882
- ? undefined
4883
- : {
4884
- backgroundColor: alterFunc(theme.palette.background.paper, 0.1),
4885
- "&:active": {
4886
- backgroundColor: alterFunc(theme.palette.background.paper, 0.15),
4887
- },
4888
- },
4889
- },
4890
- };
4891
- });
4892
-
4893
- var UnstyledLink = material.styled("a")({
4894
- color: "unset",
4895
- textDecoration: "none",
4896
- });
4897
- function IndividualFile(_a) {
4898
- var file = _a.file, disableLink = _a.disableLink, allowDelete = _a.allowDelete, onDelete = _a.onDelete;
4899
- var isImage = isAsset(file)
4900
- ? file.mimeType.startsWith("image")
4901
- : ["png", "jpg", "jpeg", "gif"].some(function (ext) { return file.name.endsWith(ext); });
4902
- var content = (jsxRuntime.jsxs(material.Stack, { p: 0.5, direction: "row", justifyContent: "space-between", children: [jsxRuntime.jsxs(material.Stack, { direction: "row", gap: 2, alignItems: "center", children: [isImage ? jsxRuntime.jsx(ImageIcon, {}) : jsxRuntime.jsx(FileIcon, {}), jsxRuntime.jsx(material.Typography, { children: isAsset(file) ? file.fileName : file.name }), file instanceof File && (jsxRuntime.jsx(material.Tooltip, { title: "New File", placement: "right", children: jsxRuntime.jsx(SparkleIcon, { color: "info" }) }))] }), allowDelete && (jsxRuntime.jsx(material.IconButton, { color: "error", onClick: function (e) {
4903
- e.stopPropagation();
4904
- onDelete && onDelete(file);
4905
- }, children: jsxRuntime.jsx(DeleteIcon, {}) }))] }));
4906
- return (jsxRuntime.jsxs(FileBox, { disableInteraction: disableLink, children: [!disableLink && (jsxRuntime.jsx(UnstyledLink, { href: isAsset(file) ? file.fullPath : "#", target: "_blank", children: content })), disableLink && content] }));
4909
+ function FileEditor(_a) {
4910
+ var value = _a.value, onChange = _a.onChange, multiple = _a.multiple, disabled = _a.disabled, placeholder = _a.placeholder, accept = _a.accept, maxFiles = _a.maxFiles, maxSize = _a.maxSize, minSize = _a.minSize;
4911
+ var _b = useFileEditor(value, onChange, {
4912
+ multiple: multiple,
4913
+ accept: accept,
4914
+ disabled: disabled,
4915
+ maxFiles: maxFiles,
4916
+ maxSize: maxSize,
4917
+ minSize: minSize,
4918
+ }), getInputProps = _b.getInputProps, getRootProps = _b.getRootProps, dragOverDropzone = _b.dragOverDropzone, values = _b.values, removeFile = _b.removeFile, open = _b.open, showError = _b.showError, setShowError = _b.setShowError, errorMessage = _b.errorMessage;
4919
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(material.Box, { sx: { position: "relative" }, children: [jsxRuntime.jsx("input", __assign({}, getInputProps())), jsxRuntime.jsx(DropIndicator, __assign({ multiple: multiple, dragOver: dragOverDropzone, disabled: disabled }, getRootProps(), { children: jsxRuntime.jsxs(material.Stack, { gap: 1, children: [values.length > 0 && (jsxRuntime.jsx(material.Box, { sx: { opacity: disabled ? 0.4 : 1 }, children: jsxRuntime.jsx(FileDisplay, { files: values !== null && values !== void 0 ? values : [], disableLink: true, allowDelete: !disabled, onDelete: removeFile }) })), (multiple || (values === null || values === void 0 ? void 0 : values.length) == 0) && (jsxRuntime.jsx(material.Button, { onClick: open, startIcon: jsxRuntime.jsx(AddIcon, {}), fullWidth: true, disabled: disabled, children: placeholder !== null && placeholder !== void 0 ? placeholder : "Add File".concat(multiple ? "s" : "") }))] }) })), dragOverDropzone && (jsxRuntime.jsx(material.Stack, { position: "absolute", top: 0, bottom: 0, left: 0, right: 0, justifyContent: "center", alignItems: "center", sx: { pointerEvents: "none" }, children: jsxRuntime.jsx(NoteAddIcon, { sx: { fontSize: 50 } }) }))] }), jsxRuntime.jsx(ErrorNotification, { open: showError, onClose: function () { return setShowError(false); }, message: errorMessage })] }));
4907
4920
  }
4908
4921
 
4909
- function FileDisplay(_a) {
4910
- var files = _a.files, individualFileProps = __rest(_a, ["files"]);
4911
- if (!Array.isArray(files)) {
4912
- return (jsxRuntime.jsx(material.Box, { children: jsxRuntime.jsx(IndividualFile, __assign({ file: files }, individualFileProps)) }));
4922
+ var isFileRequired = function (value) {
4923
+ if (value == null) {
4924
+ return "This field is required";
4913
4925
  }
4914
- return (jsxRuntime.jsx(material.Stack, { children: files.map(function (f) { return (jsxRuntime.jsx(IndividualFile, __assign({ file: f }, individualFileProps), isAsset(f) ? f.id : f.name)); }) }));
4915
- }
4926
+ if (Array.isArray(value) && value.length === 0) {
4927
+ return "This field is required";
4928
+ }
4929
+ return undefined;
4930
+ };
4916
4931
 
4917
4932
  function FileEditorField(_a) {
4918
- var name = _a.name, label = _a.label, icon = _a.icon, showSpace = _a.showSpace, multiple = _a.multiple, disabled = _a.disabled, helperText = _a.helperText, placeholder = _a.placeholder, required = _a.required, slotProps = _a.slotProps, accept = _a.accept, forceError = _a.forceError;
4919
- var _b = useFileEditorField(name, {
4920
- multiple: multiple,
4921
- accept: accept,
4922
- disabled: disabled,
4923
- required: required,
4924
- fieldProps: slotProps === null || slotProps === void 0 ? void 0 : slotProps.field,
4925
- }), getInputProps = _b.getInputProps, getRootProps = _b.getRootProps, dragOverDropzone = _b.dragOverDropzone, values = _b.values, removeFile = _b.removeFile, open = _b.open, showError = _b.showError, setShowError = _b.setShowError, errorMessage = _b.errorMessage, meta = _b.meta;
4926
- return (jsxRuntime.jsxs(FieldWrapper, { icon: icon, showSpace: showSpace, children: [jsxRuntime.jsxs(material.FormControl, { fullWidth: true, sx: { position: "relative" }, children: [label && (jsxRuntime.jsx(material.FormLabel, { disabled: disabled, error: meta.touched && meta.error, children: label })), jsxRuntime.jsx("input", __assign({}, getInputProps())), jsxRuntime.jsx(DropIndicator, __assign({ multiple: multiple, dragOver: dragOverDropzone, disabled: disabled }, getRootProps(), { children: jsxRuntime.jsxs(material.Stack, { gap: 1, children: [values.length > 0 && (jsxRuntime.jsx(material.Box, { sx: { opacity: disabled ? 0.4 : 1 }, children: jsxRuntime.jsx(FileDisplay, { files: values !== null && values !== void 0 ? values : [], disableLink: true, allowDelete: !disabled, onDelete: removeFile }) })), (multiple || (values === null || values === void 0 ? void 0 : values.length) == 0) && (jsxRuntime.jsx(material.Button, { onClick: open, startIcon: jsxRuntime.jsx(AddIcon, {}), fullWidth: true, disabled: disabled, children: placeholder !== null && placeholder !== void 0 ? placeholder : "Add File".concat(multiple ? "s" : "") }))] }) })), dragOverDropzone && (jsxRuntime.jsx(material.Stack, { position: "absolute", top: 0, bottom: 0, left: 0, right: 0, justifyContent: "center", alignItems: "center", sx: { pointerEvents: "none" }, children: jsxRuntime.jsx(NoteAddIcon, { sx: { fontSize: 50 } }) })), jsxRuntime.jsx(material.FormHelperText, { error: (meta.touched && meta.error) || forceError, children: (meta.touched && meta.error) || helperText })] }), jsxRuntime.jsx(ErrorNotification, { open: showError, onClose: function () { return setShowError(false); }, message: errorMessage })] }));
4933
+ var name = _a.name, label = _a.label, icon = _a.icon, showSpace = _a.showSpace, multiple = _a.multiple, disabled = _a.disabled, helperText = _a.helperText, placeholder = _a.placeholder, required = _a.required, slotProps = _a.slotProps, accept = _a.accept, maxFiles = _a.maxFiles, maxSize = _a.maxSize, minSize = _a.minSize, forceError = _a.forceError, _b = _a.validators, validators = _b === void 0 ? [] : _b;
4934
+ var _c = reactFinalForm.useField(name, __assign({ validate: required
4935
+ ? composeValidators.apply(void 0, __spreadArray(__spreadArray([], validators, false), [isFileRequired], false)) : composeValidators.apply(void 0, validators) }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.field)), input = _c.input, meta = _c.meta;
4936
+ return (jsxRuntime.jsx(FieldWrapper, { icon: icon, showSpace: showSpace, children: jsxRuntime.jsxs(material.FormControl, { fullWidth: true, children: [label && (jsxRuntime.jsx(material.FormLabel, { disabled: disabled, error: meta.touched && meta.error, children: label })), jsxRuntime.jsx(FileEditor, { value: input.value, onChange: input.onChange, multiple: multiple, disabled: disabled, accept: accept, maxFiles: maxFiles, maxSize: maxSize, minSize: minSize, placeholder: placeholder }), jsxRuntime.jsx(material.FormHelperText, { error: (meta.touched && meta.error) || forceError, children: (meta.touched && meta.error) || helperText })] }) }));
4927
4937
  }
4928
4938
 
4929
4939
  function asInteger(value) {
@@ -5219,6 +5229,7 @@ exports.ExtendedTable = ExtendedTable;
5219
5229
  exports.FieldWrapper = FieldWrapper;
5220
5230
  exports.FileDisplay = FileDisplay;
5221
5231
  exports.FileDropper = FileDropper;
5232
+ exports.FileEditor = FileEditor;
5222
5233
  exports.FileEditorField = FileEditorField;
5223
5234
  exports.LabeledValue = LabeledValue;
5224
5235
  exports.LoaderButton = LoaderButton;
@@ -5243,5 +5254,6 @@ exports.useAsyncData = useAsyncData;
5243
5254
  exports.useAsyncDataCallback = useAsyncDataCallback;
5244
5255
  exports.useDebounce = useDebounce;
5245
5256
  exports.useDebounceEffect = useDebounceEffect;
5257
+ exports.useFileEditor = useFileEditor;
5246
5258
  exports.usePartialSetterState = usePartialSetterState;
5247
5259
  //# sourceMappingURL=index.cjs.map