UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

199 lines (194 loc) 9.52 kB
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray'; import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import React__default from 'react'; import { chatInputMaxTextAreaHeight } from './chatInputTokens.js'; import { isFileAccepted } from '../FileUpload/isFileAccepted.js'; import { useControllableState } from '../../utils/useControllable.js'; import { useIsMobile } from '../../utils/useIsMobile.js'; import { useMergeRefs } from '../../utils/useMergeRefs.js'; function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } var useChatInput = function useChatInput(_ref, ref) { var controlledValue = _ref.value, defaultValue = _ref.defaultValue, _onChange = _ref.onChange, onSubmit = _ref.onSubmit, controlledFileList = _ref.fileList, onFileChange = _ref.onFileChange, onFileRemove = _ref.onFileRemove, accept = _ref.accept, suggestions = _ref.suggestions, onSuggestionAccept = _ref.onSuggestionAccept; var fileInputRef = React__default.useRef(null); var textareaRef = React__default.useRef(null); var mergedRef = useMergeRefs(ref, textareaRef); var _useControllableState = useControllableState({ value: controlledValue, defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : '', onChange: function onChange(newValue) { _onChange === null || _onChange === void 0 || _onChange({ value: newValue }); } }), _useControllableState2 = _slicedToArray(_useControllableState, 2), textValue = _useControllableState2[0], setTextValue = _useControllableState2[1]; var _useControllableState3 = useControllableState({ value: controlledFileList, defaultValue: controlledFileList !== null && controlledFileList !== void 0 ? controlledFileList : [] }), _useControllableState4 = _slicedToArray(_useControllableState3, 2), files = _useControllableState4[0], setFiles = _useControllableState4[1]; var _React$useState = React__default.useState(0), _React$useState2 = _slicedToArray(_React$useState, 2), activeSuggestionIndex = _React$useState2[0], setActiveSuggestionIndex = _React$useState2[1]; var isMobile = useIsMobile(); var hasText = textValue.trim().length > 0; var hasFiles = files.length > 0; var isSubmitDisabled = !hasText && !hasFiles; var showGhostSuggestion = !hasText && Boolean(suggestions === null || suggestions === void 0 ? void 0 : suggestions.length) && !isMobile; var adjustTextareaHeight = React__default.useCallback(function () { var textarea = textareaRef.current; if (textarea && textarea instanceof HTMLTextAreaElement) { textarea.style.height = 'auto'; textarea.style.height = "".concat(Math.min(textarea.scrollHeight, chatInputMaxTextAreaHeight), "px"); } }, []); React__default.useEffect(function () { adjustTextareaHeight(); }, [textValue, adjustTextareaHeight]); var handleTextChange = React__default.useCallback(function (_ref2) { var newValue = _ref2.value; setTextValue(function () { return newValue !== null && newValue !== void 0 ? newValue : ''; }); }, [setTextValue]); var handleSubmit = React__default.useCallback(function () { if (isSubmitDisabled) return; onSubmit === null || onSubmit === void 0 || onSubmit({ value: textValue, fileList: files }); }, [isSubmitDisabled, onSubmit, textValue, files]); var handleKeyDown = React__default.useCallback(function (_ref3) { var event = _ref3.event; if (!event) return; if (event.key === 'Enter' && !event.shiftKey) { event.preventDefault(); handleSubmit(); return; } if (event.key === 'Tab' && showGhostSuggestion && suggestions !== null && suggestions !== void 0 && suggestions.length) { event.preventDefault(); var currentSuggestion = suggestions[activeSuggestionIndex]; setTextValue(function () { return currentSuggestion; }); onSuggestionAccept === null || onSuggestionAccept === void 0 || onSuggestionAccept({ suggestion: currentSuggestion }); } }, [handleSubmit, showGhostSuggestion, suggestions, activeSuggestionIndex, setTextValue, onSuggestionAccept]); var handleUploadClick = React__default.useCallback(function () { var _fileInputRef$current; (_fileInputRef$current = fileInputRef.current) === null || _fileInputRef$current === void 0 || _fileInputRef$current.click(); }, []); var handleFileInputChange = React__default.useCallback(function (event) { var _event$target$files; var inputFiles = Array.from((_event$target$files = event.target.files) !== null && _event$target$files !== void 0 ? _event$target$files : []); var validFiles = inputFiles.filter(function (file) { if (accept && !isFileAccepted(file, accept)) return false; return true; }); var _iterator = _createForOfIteratorHelper(validFiles), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var file = _step.value; if (!file.id) { file.id = "".concat(Date.now()).concat(Math.floor(Math.random() * 1000000)); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (validFiles.length > 0) { var newFileList = [].concat(_toConsumableArray(files), _toConsumableArray(validFiles)); setFiles(function () { return newFileList; }); onFileChange === null || onFileChange === void 0 || onFileChange({ fileList: newFileList }); } event.target.value = ''; }, [accept, files, setFiles, onFileChange]); var handleFileRemove = React__default.useCallback(function (file) { var newFileList = files.filter(function (f) { return f.id !== file.id; }); setFiles(function () { return newFileList; }); onFileRemove === null || onFileRemove === void 0 || onFileRemove({ file: file }); }, [files, setFiles, onFileRemove]); var handlePaste = React__default.useCallback(function (event) { var _event$clipboardData$, _event$clipboardData; var clipboardFiles = Array.from((_event$clipboardData$ = (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.files) !== null && _event$clipboardData$ !== void 0 ? _event$clipboardData$ : []); if (clipboardFiles.length === 0) return; event.preventDefault(); for (var _i = 0, _clipboardFiles = clipboardFiles; _i < _clipboardFiles.length; _i++) { var file = _clipboardFiles[_i]; if (!file.id) { file.id = "".concat(Date.now()).concat(Math.floor(Math.random() * 1000000)); } } if (clipboardFiles.length > 0) { var newFileList = [].concat(_toConsumableArray(files), clipboardFiles); setFiles(function () { return newFileList; }); onFileChange === null || onFileChange === void 0 || onFileChange({ fileList: newFileList }); } }, [files, setFiles, onFileChange]); var handleInnerMouseDownCapture = React__default.useCallback(function (event) { var target = event.target; if (!target) return; // Allow normal behavior when clicking directly inside textarea. if (target.closest('textarea')) return; // Prevent focus from moving to internal controls (submit/upload/file actions). event.preventDefault(); }, []); return { fileInputRef: fileInputRef, mergedRef: mergedRef, textValue: textValue, files: files, activeSuggestionIndex: activeSuggestionIndex, setActiveSuggestionIndex: setActiveSuggestionIndex, hasText: hasText, hasFiles: hasFiles, isSubmitDisabled: isSubmitDisabled, showGhostSuggestion: showGhostSuggestion, handleTextChange: handleTextChange, handleSubmit: handleSubmit, handleKeyDown: handleKeyDown, handleUploadClick: handleUploadClick, handleFileInputChange: handleFileInputChange, handleFileRemove: handleFileRemove, handlePaste: handlePaste, handleInnerMouseDownCapture: handleInnerMouseDownCapture }; }; export { useChatInput }; //# sourceMappingURL=useChatInput.js.map