UNPKG

@yandex/ui

Version:

Yandex UI components

70 lines (69 loc) 4.45 kB
import { __assign, __read, __rest } from "tslib"; import React, { useState, useCallback, useRef, useEffect, } from 'react'; import { useComponentRegistry } from '@bem-react/di'; import { mergeRefs } from '../lib/mergeRefs'; import { Keys, isKeyCode } from '../lib/keyboard'; import { useUniqId } from '../useUniqId'; import { cnAttach, extensionsMap } from './Attach.const'; import './Attach.css'; export * from './Attach.const'; /** * Компонент для создания кнопки выбора файла, предназначенного для отправки на сервер. * @param {IAttachProps} props */ export var Attach = function (_a) { var children = _a.children, className = _a.className, controlRef = _a.controlRef, disabled = _a.disabled, hasHolder = _a.hasHolder, holderText = _a.holderText, holderTextWidth = _a.holderTextWidth, // eslint-disable-next-line react-hooks/rules-of-hooks _b = _a.id, // eslint-disable-next-line react-hooks/rules-of-hooks id = _b === void 0 ? useUniqId() : _b, innerRef = _a.innerRef, name = _a.name, onChange = _a.onChange, onClearClick = _a.onClearClick, size = _a.size, theme = _a.theme, view = _a.view, _c = _a.tabIndex, tabIndex = _c === void 0 ? 0 : _c, accept = _a.accept, props = __rest(_a, ["children", "className", "controlRef", "disabled", "hasHolder", "holderText", "holderTextWidth", "id", "innerRef", "name", "onChange", "onClearClick", "size", "theme", "view", "tabIndex", "accept"]); var _d = __read(useState({}), 2), _e = _d[0], fileName = _e.fileName, fileExtension = _e.fileExtension, setFileMeta = _d[1]; var _f = useComponentRegistry(cnAttach()), Button = _f.Button, Holder = _f.Holder, Control = _f.Control; var controlInternalRef = useRef(null); useEffect(function () { mergeRefs(controlInternalRef, controlRef); }, [controlInternalRef, controlRef]); var onInternalChange = useCallback(function (event) { var fileName = event.target.value.split('\\').pop(); var rawFileExtension = fileName.split('.').pop().toLowerCase(); var fileExtension = extensionsMap[rawFileExtension] || 'unknown'; if (onChange !== undefined) { onChange(event); } setFileMeta({ fileName: fileName, fileExtension: fileExtension }); }, [onChange]); var onInternalClearClick = useCallback(function (event) { if (controlInternalRef.current !== null) { if (onChange !== undefined) { // Создаем синтетическое событие для эмуляции очистки контрола. var syntheticEvent = Object.create(event); syntheticEvent.target = controlInternalRef.current; syntheticEvent.currentTarget = controlInternalRef.current; controlInternalRef.current.value = ''; onChange(syntheticEvent); } else { controlInternalRef.current.value = ''; } } if (onClearClick !== undefined) { onClearClick(event); } setFileMeta({ fileName: undefined, fileExtension: undefined }); }, [onChange, onClearClick]); var onInternalKeyUp = useCallback(function (event) { if (controlInternalRef.current !== null && isKeyCode(event.keyCode, [Keys.SPACE, Keys.ENTER])) { controlInternalRef.current.click(); } }, [controlInternalRef]); return (React.createElement("span", __assign({}, props, { ref: innerRef, className: cnAttach({ disabled: disabled }, [className]) }), React.createElement(Button, { disabled: disabled, theme: theme, view: view, size: size, as: "span", // Указываем role и aria-label для доступности. role: "button", "aria-label": children, tabIndex: disabled ? -1 : tabIndex, onKeyUp: onInternalKeyUp, className: cnAttach('Button'), // @ts-ignore autoComplete: null, // @ts-ignore type: null, addonAfter: React.createElement(Control, { disabled: disabled, id: id, name: name, onChange: onInternalChange, innerRef: controlInternalRef, accept: accept }) }, children), hasHolder && (React.createElement(Holder, { id: id, fileName: fileName, fileExtension: fileExtension, textWidth: holderTextWidth, onClearClick: onInternalClearClick }, holderText)))); }; Attach.displayName = cnAttach();