@uploadcare/react-widget
Version:
React File Uploader. React component with uploading from multiple sources
204 lines (198 loc) • 7.75 kB
JavaScript
;
var index = require('./index-f2aa1c3c.cjs');
var React = require('react');
var uploadcare = require('uploadcare-widget');
var defaultPreviewUrlCallback = require('./default-preview-url-callback-45103083.cjs');
var isEqual = require('react-fast-compare');
var useValidators = function useValidators(widget, validators) {
React.useEffect(function () {
if (validators != null) {
var instance = widget.current;
validators.forEach(function (validator) {
instance.validators.push(validator);
});
return function () {
instance.validators.length = 0;
};
}
}, [widget, validators]);
};
function useDeepMemo(factory, deps) {
var isValid = true;
var valueRef = React.useRef();
// initial hook call
if (!valueRef.current) {
valueRef.current = {
deps: deps,
result: factory()
};
// subsequent calls
} else {
isValid = !!(deps && valueRef.current.deps && isEqual(deps, valueRef.current.deps));
}
var cache = isValid ? valueRef.current : {
deps: deps,
result: factory()
};
// must update immediately so any sync renders here don't cause an infinite loop
valueRef.current = cache;
return cache.result;
}
var _excluded = ["id", "name", "value", "onFileSelect", "onChange", "onDialogOpen", "onDialogClose", "onTabChange", "apiRef", "customTabs", "validators", "tabsCss", "locale", "localeTranslations", "localePluralize", "previewUrlCallback", "metadataCallback"];
var useWidget = function useWidget(_ref, uploadcare) {
var id = _ref.id,
name = _ref.name,
value = _ref.value,
onFileSelect = _ref.onFileSelect,
onChange = _ref.onChange,
onDialogOpen = _ref.onDialogOpen,
onDialogClose = _ref.onDialogClose,
onTabChange = _ref.onTabChange,
apiRef = _ref.apiRef,
customTabs = _ref.customTabs,
validators = _ref.validators,
tabsCss = _ref.tabsCss,
locale = _ref.locale,
localeTranslations = _ref.localeTranslations,
localePluralize = _ref.localePluralize,
previewUrlCallback = _ref.previewUrlCallback,
metadataCallback = _ref.metadataCallback,
options = index._objectWithoutProperties(_ref, _excluded);
var input = React.useRef(null);
var widget = React.useRef(null);
var cachedValueRef = React.useRef(null);
var fileSelectedCallback = defaultPreviewUrlCallback.useCommitedCallback(onFileSelect);
var changeCallback = defaultPreviewUrlCallback.useCommitedCallback(onChange);
var dialogOpenCallback = defaultPreviewUrlCallback.useCommitedCallback(onDialogOpen);
var dialogCloseCallback = defaultPreviewUrlCallback.useCommitedCallback(onDialogClose);
var tabChangeCallback = defaultPreviewUrlCallback.useCommitedCallback(onTabChange);
var metadataCommitedCallback = defaultPreviewUrlCallback.useCommitedCallback(metadataCallback);
var previewUrlCommitedCallback = defaultPreviewUrlCallback.useCommitedCallback(previewUrlCallback || defaultPreviewUrlCallback.defaultPreviewUrlCallback);
var widgetOptions = useDeepMemo(function () {
return options;
}, [options]);
defaultPreviewUrlCallback.useCustomTabs(customTabs, uploadcare);
defaultPreviewUrlCallback.useDeepEffect(function () {
if (locale) window.UPLOADCARE_LOCALE = locale;
if (localePluralize) window.UPLOADCARE_LOCALE_PLURALIZE = localePluralize;
if (localeTranslations) {
window.UPLOADCARE_LOCALE_TRANSLATIONS = localeTranslations;
}
uploadcare.plugin(function (internal) {
internal.locale.rebuild({
locale: locale || null,
localeTranslations: localeTranslations || null,
localePluralize: localePluralize || null
});
});
return function () {
if (locale) delete window.UPLOADCARE_LOCALE;
if (localePluralize) delete window.UPLOADCARE_LOCALE_PLURALIZE;
if (localeTranslations) delete window.UPLOADCARE_LOCALE_TRANSLATIONS;
};
}, [locale, localeTranslations, localePluralize]);
React.useEffect(function () {
var inputEl = input.current;
widget.current = uploadcare.Widget(inputEl, index._objectSpread2(index._objectSpread2({}, widgetOptions), {}, {
metadataCallback: widgetOptions.metadata ? undefined : metadataCommitedCallback,
previewUrlCallback: previewUrlCommitedCallback
}));
var widgetElement = inputEl.nextSibling;
if (cachedValueRef.current) {
// restore widget value when called twice in React.StrictMode
widget.current.value(cachedValueRef.current);
}
return function () {
// useEffect could be called twice inside React.StrictMode
// to reinitialize widget on the same input element, we need to cleanup bounded jquery data on it
// `uploadcareWidget` is a data attr that is used to store widget api
// see https://github.com/uploadcare/uploadcare-widget/blob/feat/unsplash-tab/src/widget/live.js#L11
uploadcare.jQuery(inputEl).removeData('uploadcareWidget');
widgetElement && widgetElement.remove();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [uploadcare, widgetOptions, metadataCommitedCallback, previewUrlCommitedCallback]);
useValidators(widget, validators);
React.useEffect(function () {
widget.current.onUploadComplete.add(changeCallback);
widget.current.onChange.add(fileSelectedCallback);
return function () {
widget.current.onUploadComplete.remove(changeCallback);
widget.current.onChange.remove(fileSelectedCallback);
};
}, [changeCallback, fileSelectedCallback, uploadcare, widgetOptions]);
React.useEffect(function () {
var dialog;
var saveDialog = function saveDialog(ref) {
dialog = ref;
dialog.done(dialogCloseCallback).fail(dialogCloseCallback).progress(tabChangeCallback);
dialogOpenCallback(ref);
};
widget.current.onDialogOpen.add(saveDialog);
return function () {
widget.current.onDialogOpen.remove(saveDialog);
dialog && dialog.reject();
};
}, [dialogCloseCallback, dialogOpenCallback, tabChangeCallback, widgetOptions]);
React.useEffect(function () {
var files = [];
var saveFiles = function saveFiles(file) {
if (file) {
files = file.files ? file.files() : [file];
} else {
files = [];
}
};
widget.current.onChange.add(saveFiles);
return function () {
files.forEach(function (file) {
return file.cancel();
});
widget.current.onChange.remove(saveFiles);
};
}, [widgetOptions]);
React.useEffect(function () {
if (cachedValueRef.current !== value) {
widget.current.value(value);
}
cachedValueRef.current = value;
}, [value]);
React.useEffect(function () {
if (uploadcare && tabsCss && typeof tabsCss === 'string') {
if (tabsCss.indexOf('https://') === 0) {
uploadcare.tabsCss.addUrl(tabsCss);
} else {
uploadcare.tabsCss.addStyle(tabsCss);
}
}
}, [uploadcare, tabsCss]);
React.useImperativeHandle(apiRef, function () {
return {
openDialog: function openDialog() {
return widget.current.openDialog();
},
reloadInfo: function reloadInfo() {
return widget.current.reloadInfo();
},
getInput: function getInput() {
return widget.current.inputElement;
},
value: function value(_value) {
return widget.current.value(_value);
}
};
}, []);
return React.useCallback(function () {
return /*#__PURE__*/React.createElement("input", {
type: "hidden",
ref: input,
id: id,
name: name
});
}, [id, name]);
};
var Uploader = function Uploader(props) {
var Input = useWidget(props, uploadcare);
return /*#__PURE__*/React.createElement(Input, null);
};
exports.default = Uploader;