@yandex/ui
Version:
Yandex UI components
70 lines (69 loc) • 4.45 kB
JavaScript
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();