@skbkontur/react-ui 4.25.2 → 4.26.0-next.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.
Files changed (56) hide show
  1. package/README.md +41 -13
  2. package/cjs/components/Autocomplete/Autocomplete.md +76 -3
  3. package/cjs/components/Button/Button.md +38 -11
  4. package/cjs/components/FileUploader/FileUploader.d.ts +2 -0
  5. package/cjs/components/FileUploader/FileUploader.js +32 -9
  6. package/cjs/components/FileUploader/FileUploader.js.map +1 -1
  7. package/cjs/components/FileUploader/FileUploader.md +29 -0
  8. package/cjs/hooks/useDrop.d.ts +1 -1
  9. package/cjs/hooks/useDrop.js.map +1 -1
  10. package/cjs/internal/FileUploaderControl/FileUploaderControlProvider.d.ts +5 -2
  11. package/cjs/internal/FileUploaderControl/FileUploaderControlProvider.js +16 -3
  12. package/cjs/internal/FileUploaderControl/FileUploaderControlProvider.js.map +1 -1
  13. package/cjs/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.d.ts +1 -0
  14. package/cjs/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.js +4 -2
  15. package/cjs/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.js.map +1 -1
  16. package/cjs/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.d.ts +1 -0
  17. package/cjs/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.js +3 -2
  18. package/cjs/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.js.map +1 -1
  19. package/cjs/internal/RenderContainer/RenderContainer.d.ts +2 -0
  20. package/cjs/internal/RenderContainer/RenderContainer.js +6 -3
  21. package/cjs/internal/RenderContainer/RenderContainer.js.map +1 -1
  22. package/cjs/internal/RenderContainer/RenderInnerContainer.js +3 -2
  23. package/cjs/internal/RenderContainer/RenderInnerContainer.js.map +1 -1
  24. package/cjs/internal/ZIndex/ZIndex.d.ts +7 -3
  25. package/cjs/internal/ZIndex/ZIndex.js +41 -3
  26. package/cjs/internal/ZIndex/ZIndex.js.map +1 -1
  27. package/cjs/lib/listenFocusOutside.js +4 -2
  28. package/cjs/lib/listenFocusOutside.js.map +1 -1
  29. package/components/Autocomplete/Autocomplete.md +76 -3
  30. package/components/Button/Button.md +38 -11
  31. package/components/FileUploader/FileUploader/FileUploader.js +30 -8
  32. package/components/FileUploader/FileUploader/FileUploader.js.map +1 -1
  33. package/components/FileUploader/FileUploader.d.ts +2 -0
  34. package/components/FileUploader/FileUploader.md +29 -0
  35. package/hooks/useDrop/useDrop.js.map +1 -1
  36. package/hooks/useDrop.d.ts +1 -1
  37. package/internal/FileUploaderControl/FileUploaderControlProvider/FileUploaderControlProvider.js +12 -3
  38. package/internal/FileUploaderControl/FileUploaderControlProvider/FileUploaderControlProvider.js.map +1 -1
  39. package/internal/FileUploaderControl/FileUploaderControlProvider.d.ts +5 -2
  40. package/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile/FileUploaderFile.js +4 -2
  41. package/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile/FileUploaderFile.js.map +1 -1
  42. package/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.d.ts +1 -0
  43. package/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList/FileUploaderFileList.js +4 -2
  44. package/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList/FileUploaderFileList.js.map +1 -1
  45. package/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.d.ts +1 -0
  46. package/internal/RenderContainer/RenderContainer/RenderContainer.js +3 -1
  47. package/internal/RenderContainer/RenderContainer/RenderContainer.js.map +1 -1
  48. package/internal/RenderContainer/RenderContainer.d.ts +2 -0
  49. package/internal/RenderContainer/RenderInnerContainer/RenderInnerContainer.js +5 -4
  50. package/internal/RenderContainer/RenderInnerContainer/RenderInnerContainer.js.map +1 -1
  51. package/internal/ZIndex/ZIndex/ZIndex.js +55 -7
  52. package/internal/ZIndex/ZIndex/ZIndex.js.map +1 -1
  53. package/internal/ZIndex/ZIndex.d.ts +7 -3
  54. package/lib/listenFocusOutside/listenFocusOutside.js +3 -2
  55. package/lib/listenFocusOutside/listenFocusOutside.js.map +1 -1
  56. package/package.json +3 -3
package/README.md CHANGED
@@ -23,16 +23,17 @@ const MyApp = () => (
23
23
 
24
24
  ### Хотим другой цвет кнопки!
25
25
 
26
- Нужно использовать [ThemeContext](https://tech.skbkontur.ru/react-ui/#/Customization/ThemeContext). Список переменных можно глянуть в [ThemeShowcase](https://tech.skbkontur.ru/react-ui/#/Customization/ThemeShowcase)
26
+ Нужно использовать [ThemeContext](https://tech.skbkontur.ru/react-ui/#/Customization/ThemeContext). Список переменных
27
+ можно глянуть в [ThemeShowcase](https://tech.skbkontur.ru/react-ui/#/Customization/ThemeShowcase)
27
28
 
28
29
  ### StrictMode
29
30
 
30
- Начиная с версий `@skbkontur/react-ui@3.10.0` и `@skbkontur/react-ui-validations@1.7.0`, библиотека поддерживает работу в React.StrictMode.
31
+ Начиная с версий `@skbkontur/react-ui@3.10.0` и `@skbkontur/react-ui-validations@1.7.0`, библиотека поддерживает работу
32
+ в React.StrictMode.
31
33
 
32
- Некоторым компонентам библиотеки необходимо иметь доступ до корневой DOM-ноды своих
33
- children. Ранее для этого использовался метод findDomNode, который в StrictMode запрещён.
34
- Теперь получение DOM-ноды реализовано в библиотеке через ref, из-за чего появились некоторые
35
- требования к компонентам, передаваемым в Hint, Tooltip, Popup или Tab:
34
+ Некоторым компонентам библиотеки необходимо иметь доступ до корневой DOM-ноды своих children. Ранее для этого
35
+ использовался метод findDomNode, который в StrictMode запрещён. Теперь получение DOM-ноды реализовано в библиотеке через
36
+ ref, из-за чего появились некоторые требования к компонентам, передаваемым в Hint, Tooltip, Popup или Tab:
36
37
 
37
38
  - при передаче функциональных компонентов, они должны использовать `React.ForwardRef`:
38
39
 
@@ -46,19 +47,20 @@ const CustomFunctionComponent = React.forwardRef(
46
47
  export const WithFunctionChildren = () => (
47
48
  <React.StrictMode>
48
49
  <Hint pos="top" text="Something will never be changed" manual opened>
49
- <CustomFunctionComponent />
50
+ <CustomFunctionComponent/>
50
51
  </Hint>
51
52
  </React.StrictMode>
52
53
  );
53
54
  ```
54
55
 
55
- - при использовании хука `useImperativeHandle`, возвращаемый объект должен реализовывать метод `getRootNode`, возвращающий DOM-ноду:
56
+ - при использовании хука `useImperativeHandle`, возвращаемый объект должен реализовывать метод `getRootNode`,
57
+ возвращающий DOM-ноду:
56
58
 
57
59
  ```js static
58
60
  import { Hint } from '@skbkontur/react-ui';
59
61
 
60
62
  const ImperativeHandleComponent = React.forwardRef(function FN(_, ref) {
61
- const rootNode = React.useRef<HTMLDivElement>(null);
63
+ const rootNode = React.useRef < HTMLDivElement > (null);
62
64
  React.useImperativeHandle(ref, () => ({
63
65
  foo: 'bar',
64
66
  getRootNode: () => rootNode.current,
@@ -69,7 +71,7 @@ const ImperativeHandleComponent = React.forwardRef(function FN(_, ref) {
69
71
  export const WithImperativeHandleChildren = () => (
70
72
  <React.StrictMode>
71
73
  <Hint pos="top" text="Something will never be changed" manual opened>
72
- <ImperativeHandleComponent />
74
+ <ImperativeHandleComponent/>
73
75
  </Hint>
74
76
  </React.StrictMode>
75
77
  );
@@ -95,7 +97,7 @@ class CustomClassComponent extends React.Component {
95
97
  export const WithClassChildren = () => (
96
98
  <React.StrictMode>
97
99
  <Hint pos="top" text="Something will never be changed" manual opened>
98
- <CustomClassComponent />
100
+ <CustomClassComponent/>
99
101
  </Hint>
100
102
  </React.StrictMode>
101
103
  );
@@ -107,6 +109,29 @@ export const WithClassChildren = () => (
107
109
 
108
110
  ## FAQ
109
111
 
112
+ ### Выпадашки и несколько react-рутов
113
+
114
+ Реакт позволяет создавать рут внутри рута. Но контекст между ними не прокидывается. Это вызывает проблемы в работе
115
+ различных выпадашек, типа `Tooltip`, `Select`, `Modal` и других.
116
+
117
+ В версии `4.26.0` появился мехнизм, который решает большинство этих проблем. Если вложенный реакт-рут является виджетом,
118
+ то будет достаточно обновить библиотеку только в нём.
119
+
120
+ Однако, при удалении html-элемента, который был реакт-рутом, его необходимо предварительно явно размонтировать:
121
+
122
+ ```tsx static
123
+ React.useLayoutEffect(
124
+ () => () => {
125
+ if (React.version === 17) {
126
+ rootRef.current && ReactDOM.unmountComponentAtNode(rootRef.current);
127
+ } else if (React.version === 18) {
128
+ setTimeout(() => reactRoot.current?.unmount());
129
+ }
130
+ },
131
+ [],
132
+ );
133
+ ```
134
+
110
135
  ### Отключение анимаций во время тестирования
111
136
 
112
137
  Анимации в компонентах отключаются любой из следующих глобальных переменных:
@@ -121,11 +146,14 @@ process.env.STORYBOOK_REACT_UI_TEST
121
146
 
122
147
  ### Прокидывание className и style компонентам
123
148
 
124
- Начиная с версии 2.14.0, стало возможным передавать в компоненты свои css-классы для дополнительной стилизации. Однако, не стоит пользоваться этой возможностью для вмешательства во внутренние стили компонентов. Верстка компонентов может быть изменена в любой момент без предупреждения, что приведет к поломке ваших переопределенных стилей.
149
+ Начиная с версии 2.14.0, стало возможным передавать в компоненты свои css-классы для дополнительной стилизации. Однако,
150
+ не стоит пользоваться этой возможностью для вмешательства во внутренние стили компонентов. Верстка компонентов может
151
+ быть изменена в любой момент без предупреждения, что приведет к поломке ваших переопределенных стилей.
125
152
 
126
153
  ### Мобильная верстка
127
154
 
128
- С версии 4.0 многие компоненты умеют адаптироваться под мобильные устройства. Подробнее об управлении этим поведением в [MOBILES.md](https://github.com/skbkontur/retail-ui/blob/master/packages/react-ui/MOBILES.md).
155
+ С версии 4.0 многие компоненты умеют адаптироваться под мобильные устройства. Подробнее об управлении этим поведением
156
+ в [MOBILES.md](https://github.com/skbkontur/retail-ui/blob/master/packages/react-ui/MOBILES.md).
129
157
 
130
158
  ### Помощь в развитии
131
159
 
@@ -1,4 +1,6 @@
1
1
  ```jsx harmony
2
+ import { Autocomplete } from '@skbkontur/react-ui';
3
+
2
4
  const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
3
5
 
4
6
  const [value, setValue] = React.useState('Kappa');
@@ -6,9 +8,9 @@ const [value, setValue] = React.useState('Kappa');
6
8
  <Autocomplete source={items} value={value} onValueChange={setValue} />;
7
9
  ```
8
10
 
9
- Очистить значение в `Autocomplete` можно только с помощью пустой строки
11
+ Очистить значение в `Autocomplete` можно только с помощью пустой строки.
10
12
  ```jsx harmony
11
- import { Button, Group } from '@skbkontur/react-ui';
13
+ import { Autocomplete, Button, Group } from '@skbkontur/react-ui';
12
14
 
13
15
  const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
14
16
 
@@ -22,7 +24,7 @@ const [value, setValue] = React.useState('Kappa');
22
24
 
23
25
  У Autocomplete есть 3 стандартных размера.
24
26
  ```jsx harmony
25
- import { Gapped } from '@skbkontur/react-ui';
27
+ import { Autocomplete, Gapped } from '@skbkontur/react-ui';
26
28
 
27
29
  const items = ['Маленький', 'Средний', 'Большой'];
28
30
 
@@ -36,3 +38,74 @@ const [valueLarge, setValueLarge] = React.useState('Большой');
36
38
  <Autocomplete source={items} value={valueLarge} onValueChange={setValueLarge} size={'large'} />
37
39
  </Gapped>
38
40
  ```
41
+
42
+ Можно выделять введеное значение при фокусе.
43
+ ```jsx harmony
44
+ import { Autocomplete } from '@skbkontur/react-ui';
45
+
46
+ const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
47
+
48
+ const [value, setValue] = React.useState('');
49
+
50
+ <Autocomplete source={items} value={value} onValueChange={setValue} selectAllOnFocus />
51
+ ```
52
+
53
+ Расположение иконки слева и справа.
54
+ ```jsx harmony
55
+ import { Autocomplete, Gapped } from '@skbkontur/react-ui';
56
+ import { SearchLoupeIcon16Regular } from '@skbkontur/icons/SearchLoupeIcon16Regular';
57
+
58
+ const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
59
+
60
+ const [valueLeft, setValueLeft] = React.useState('');
61
+ const [valueRight, setValueRight] = React.useState('');
62
+
63
+ <Gapped>
64
+ <Autocomplete source={items} value={valueLeft} onValueChange={setValueLeft} leftIcon={<SearchLoupeIcon16Regular />} />
65
+ <Autocomplete source={items} value={valueRight} onValueChange={setValueRight} rightIcon={<SearchLoupeIcon16Regular />} />
66
+ </Gapped>
67
+ ```
68
+
69
+ Изменение ширины меню.
70
+ ```jsx harmony
71
+ import { Autocomplete } from '@skbkontur/react-ui';
72
+
73
+ const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
74
+
75
+ const [value, setValue] = React.useState('');
76
+
77
+ <Autocomplete source={items} value={value} onValueChange={setValue} menuWidth={'80%'} />
78
+ ```
79
+
80
+ Расположение выпадающего окна Autocomplete.
81
+ ```jsx harmony
82
+ import { Autocomplete } from '@skbkontur/react-ui';
83
+
84
+ const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
85
+
86
+ const [value, setValue] = React.useState('');
87
+
88
+ <Autocomplete source={items} value={value} onValueChange={setValue} menuPos={'top'} />
89
+ ```
90
+
91
+ Отрисовка тени у выпадающего меню.
92
+ ```jsx harmony
93
+ import { Autocomplete } from '@skbkontur/react-ui';
94
+
95
+ const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
96
+
97
+ const [value, setValue] = React.useState('');
98
+
99
+ <Autocomplete source={items} value={value} onValueChange={setValue} hasShadow />
100
+ ```
101
+
102
+ Использование режима прозрачной рамки.
103
+ ```jsx harmony
104
+ import { Autocomplete } from '@skbkontur/react-ui';
105
+
106
+ const items = ['Grey Face', 'Grey Space', 'Kappa', 'Keepo', 'Resident Sleeper'];
107
+
108
+ const [value, setValue] = React.useState('Kappa');
109
+
110
+ <Autocomplete source={items} value={value} onValueChange={setValue} borderless />
111
+ ```
@@ -60,15 +60,15 @@ import { XIcon16Regular } from '@skbkontur/icons/XIcon16Regular';
60
60
 
61
61
  ```jsx harmony
62
62
  <div
63
- style={{
64
- display: "flex",
65
- alignItems: "end",
66
- gap: '10px',
67
- }}
68
- >
69
- <Button size="small">Маленькая</Button>
70
- <Button size="medium">Средняя</Button>
71
- <Button size="large">Большая</Button>
63
+ style={{
64
+ display: "flex",
65
+ alignItems: "end",
66
+ gap: '10px',
67
+ }}
68
+ >
69
+ <Button size="small">Маленькая</Button>
70
+ <Button size="medium">Средняя</Button>
71
+ <Button size="large">Большая</Button>
72
72
  </div>
73
73
  ```
74
74
 
@@ -133,7 +133,7 @@ const handleClick = () => {
133
133
 
134
134
  ```
135
135
 
136
- Пример кнопки с пропом `theme`
136
+ Пример кнопки с пропом `theme`.
137
137
 
138
138
  ```jsx harmony
139
139
  import { Button, Gapped } from '@skbkontur/react-ui';
@@ -146,7 +146,7 @@ import { Button, Gapped } from '@skbkontur/react-ui';
146
146
  ```
147
147
 
148
148
 
149
- Пример кастомизации кнопки-ссылки
149
+ Пример кастомизации кнопки-ссылки.
150
150
 
151
151
  ```jsx harmony
152
152
  import { Toast } from "@skbkontur/react-ui";
@@ -212,3 +212,30 @@ const renderExampleRow = (title, styles, index) => {
212
212
  {renderExampleRow('Изменение цвета ссылки', differentColorStyles)}
213
213
  </table>
214
214
  ```
215
+
216
+
217
+ Кнопка может быть узкой.
218
+
219
+ ```jsx harmony
220
+ import { Button } from '@skbkontur/react-ui';
221
+
222
+ <Button narrow>
223
+ Создать отчет
224
+ </Button>
225
+ ```
226
+
227
+
228
+ У кнопки есть состояния валидации.
229
+
230
+ ```jsx harmony
231
+ import { Button, Gapped } from '@skbkontur/react-ui';
232
+
233
+ <Gapped gap={5}>
234
+ <Button warning>
235
+ Warning
236
+ </Button>
237
+ <Button error>
238
+ Error
239
+ </Button>
240
+ </Gapped>
241
+ ```
@@ -11,6 +11,8 @@ import { SizeProp } from '../../lib/types/props';
11
11
  export declare type FileUploaderSize = SizeProp;
12
12
  declare type FileUploaderOverriddenProps = 'size';
13
13
  interface _FileUploaderProps extends CommonProps, Omit<React.InputHTMLAttributes<HTMLInputElement>, FileUploaderOverriddenProps> {
14
+ /** Начальное состояние загруженных файлов */
15
+ initialFiles?: File[];
14
16
  /** Состояние ошибки всего контрола */
15
17
  error?: boolean;
16
18
  /** Состояние предупреждения всего контрола */
@@ -26,7 +26,7 @@ var _forwardRefAndName = require("../../lib/forwardRefAndName");
26
26
  var _FocusControlWrapper = require("../../internal/FocusControlWrapper");
27
27
 
28
28
  var _UploadIcon = require("./UploadIcon");
29
- var _FileUploader2 = require("./FileUploader.styles");var _excluded = ["disabled", "error", "warning", "multiple", "width", "hideFiles", "onBlur", "onFocus", "onChange", "request", "validateBeforeUpload", "onRequestSuccess", "onRequestError", "size", "renderFile"];
29
+ var _FileUploader2 = require("./FileUploader.styles");var _excluded = ["initialFiles", "disabled", "error", "warning", "multiple", "width", "hideFiles", "onBlur", "onFocus", "onChange", "request", "validateBeforeUpload", "onRequestSuccess", "onRequestError", "size", "renderFile"];
30
30
 
31
31
  var stopPropagation = function stopPropagation(e) {return e.stopPropagation();};
32
32
 
@@ -80,6 +80,8 @@ var stopPropagation = function stopPropagation(e) {return e.stopPropagation();};
80
80
 
81
81
 
82
82
 
83
+
84
+
83
85
 
84
86
 
85
87
 
@@ -97,7 +99,8 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
97
99
  var _isTheme2022 = (0, _ThemeHelpers.isTheme2022)(theme);
98
100
 
99
101
  var
100
- disabled =
102
+ initialFiles =
103
+
101
104
 
102
105
 
103
106
 
@@ -113,7 +116,7 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
113
116
 
114
117
 
115
118
 
116
- props.disabled,error = props.error,warning = props.warning,_props$multiple = props.multiple,multiple = _props$multiple === void 0 ? false : _props$multiple,_props$width = props.width,width = _props$width === void 0 ? theme.fileUploaderWidth : _props$width,_props$hideFiles = props.hideFiles,hideFiles = _props$hideFiles === void 0 ? false : _props$hideFiles,onBlur = props.onBlur,onFocus = props.onFocus,onChange = props.onChange,request = props.request,validateBeforeUpload = props.validateBeforeUpload,onRequestSuccess = props.onRequestSuccess,onRequestError = props.onRequestError,_props$size = props.size,size = _props$size === void 0 ? 'small' : _props$size,_props$renderFile = props.renderFile,renderFile = _props$renderFile === void 0 ? defaultRenderFile : _props$renderFile,inputProps = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
119
+ props.initialFiles,disabled = props.disabled,error = props.error,warning = props.warning,_props$multiple = props.multiple,multiple = _props$multiple === void 0 ? false : _props$multiple,_props$width = props.width,width = _props$width === void 0 ? theme.fileUploaderWidth : _props$width,_props$hideFiles = props.hideFiles,hideFiles = _props$hideFiles === void 0 ? false : _props$hideFiles,onBlur = props.onBlur,onFocus = props.onFocus,onChange = props.onChange,request = props.request,validateBeforeUpload = props.validateBeforeUpload,onRequestSuccess = props.onRequestSuccess,onRequestError = props.onRequestError,_props$size = props.size,size = _props$size === void 0 ? 'small' : _props$size,_props$renderFile = props.renderFile,renderFile = _props$renderFile === void 0 ? defaultRenderFile : _props$renderFile,inputProps = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
117
120
 
118
121
  var _useContext =
119
122
  (0, _react.useContext)(_FileUploaderControlContext.FileUploaderControlContext),files = _useContext.files,setFiles = _useContext.setFiles,removeFile = _useContext.removeFile,reset = _useContext.reset,setFileValidationResult = _useContext.setFileValidationResult,isMinLengthReached = _useContext.isMinLengthReached;
@@ -165,7 +168,7 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
165
168
  /** common part **/
166
169
  var handleChange = (0, _react.useCallback)(
167
170
  function (newFiles) {
168
- if (!newFiles) {
171
+ if (!newFiles || !newFiles.length) {
169
172
  return;
170
173
  }
171
174
 
@@ -255,6 +258,16 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
255
258
  }
256
259
  };
257
260
 
261
+ var handleRemoveFile = (0, _react.useCallback)(function (fileId) {
262
+ var dataTransfer = new DataTransfer();
263
+ files.
264
+ filter(function (f) {return f.id !== fileId;}).
265
+ forEach(function (file) {
266
+ dataTransfer.items.add(file.originalFile);
267
+ });
268
+ inputRef.current && (inputRef.current.files = dataTransfer.files);
269
+ }, []);
270
+
258
271
  var _useState3 = (0, _react.useState)(false),hovered = _useState3[0],setHovered = _useState3[1];
259
272
 
260
273
  var uploadButtonClassNames = (0, _Emotion.cx)(
@@ -291,6 +304,16 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
291
304
  setIsLinkVisible(hasOneFileForSingle ? !isMinLengthReached : true);
292
305
  }, [isMinLengthReached, hasOneFileForSingle]);
293
306
 
307
+ (0, _react.useEffect)(function () {
308
+ if (!files || !files.length || !inputRef.current) {
309
+ return;
310
+ }
311
+
312
+ var dataTransfer = new DataTransfer();
313
+ files.forEach(function (file) {return dataTransfer.items.add(file.originalFile);});
314
+ inputRef.current.files = dataTransfer.files;
315
+ }, []);
316
+
294
317
  var rootNodeRef = (0, _react.useRef)(null);
295
318
 
296
319
  var iconSizes = {
@@ -308,7 +331,9 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
308
331
  style: (0, _useMemoObject.useMemoObject)({ width: width }),
309
332
  ref: rootNodeRef },
310
333
 
311
- !hideFiles && !isSingleMode && !!files.length && /*#__PURE__*/_react.default.createElement(_FileUploaderFileList.FileUploaderFileList, { renderFile: renderFile, size: size }), /*#__PURE__*/
334
+ !hideFiles && !isSingleMode && !!files.length && /*#__PURE__*/
335
+ _react.default.createElement(_FileUploaderFileList.FileUploaderFileList, { renderFile: renderFile, size: size, onRemove: handleRemoveFile }), /*#__PURE__*/
336
+
312
337
  _react.default.createElement("div", { className: uploadButtonWrapperClassNames }, /*#__PURE__*/
313
338
  _react.default.createElement("label", {
314
339
  onMouseEnter: function onMouseEnter() {return setHovered(true);},
@@ -334,7 +359,7 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
334
359
 
335
360
  hasOneFileForSingle ? /*#__PURE__*/
336
361
  _react.default.createElement("div", { ref: fileDivRef, className: _FileUploader2.jsStyles.singleFile() },
337
- renderFile(files[0], /*#__PURE__*/_react.default.createElement(_FileUploaderFile.FileUploaderFile, { file: files[0], size: size }))) : /*#__PURE__*/
362
+ renderFile(files[0], /*#__PURE__*/_react.default.createElement(_FileUploaderFile.FileUploaderFile, { file: files[0], size: size, onRemove: handleRemoveFile }))) : /*#__PURE__*/
338
363
 
339
364
 
340
365
  _react.default.createElement(_react.default.Fragment, null,
@@ -357,9 +382,7 @@ var _FileUploader = (0, _forwardRefAndName.forwardRefAndName)('FileUploader', fu
357
382
  onClick: stopPropagation,
358
383
  onChange: handleInputChange,
359
384
  onFocus: handleFocus,
360
- onBlur: handleBlur
361
- // для того, чтобы срабатывало событие change при выборе одного и того же файла подряд
362
- , value: '' }))))))));
385
+ onBlur: handleBlur }))))))));
363
386
 
364
387
 
365
388
 
@@ -1 +1 @@
1
- {"version":3,"sources":["FileUploader.tsx"],"names":["stopPropagation","e","FileUploaderDataTids","root","content","link","input","defaultRenderFile","file","fileNode","_FileUploader","props","ref","theme","ThemeContext","_isTheme2022","disabled","error","warning","multiple","width","fileUploaderWidth","hideFiles","onBlur","onFocus","onChange","request","validateBeforeUpload","onRequestSuccess","onRequestError","size","renderFile","inputProps","FileUploaderControlContext","files","setFiles","removeFile","reset","setFileValidationResult","isMinLengthReached","locale","inputRef","fileDivRef","isAsync","isSingleMode","isLinkVisible","setIsLinkVisible","upload","tryValidateAndUpload","forEach","validationMessage","id","FileUploaderFileValidationResult","sizeClassName","small","jsStyles","sizeSmall","medium","sizeMedium","large","sizeLarge","sizeIconClass","iconSmall","iconMedium","iconLarge","contentInnerClass","contentInnerSmall","contentInnerMedium","contentInnerLarge","handleChange","newFiles","filesArray","Array","from","attachedFiles","map","getAttachedFile","length","handleDrop","event","dataTransfer","clearData","onDrop","isDraggable","labelRef","isWindowDraggable","windowRef","globalObject","current","document","focus","keyListener","isTabPressed","blur","getRootNode","rootNodeRef","focusedByTab","setFocusedByTab","handleInputChange","target","handleFocus","requestAnimationFrame","handleBlur","hovered","setHovered","uploadButtonClassNames","uploadButton","uploadButtonFocus","dragOver","canDrop","uploadButtonWrapperClassNames","windowDragOver","windowDragOver2022","uploadButtonIconClassNames","icon","iconDisabled","hasOneFile","hasOneFileForSingle","contentClassNames","contentWithFiles","linkClassNames","linkHovered","linkDisabled","iconSizes","parseInt","btnIconSizeSmall","btnIconSizeMedium","btnIconSizeLarge","choosedFile","chooseFile","String","fromCharCode","globalClasses","afterLinkText","afterLinkText_HasFiles","singleFile","orDragHere","visuallyHidden","FileUploader","React","memo","displayName"],"mappings":"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","sourcesContent":["import React, { useCallback, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { globalObject, isBrowser } from '@skbkontur/global-object';\n\nimport { FileUploaderAttachedFile, getAttachedFile } from '../../internal/FileUploaderControl/fileUtils';\nimport { cx } from '../../lib/theming/Emotion';\nimport { InstanceWithRootNode } from '../../lib/rootNode';\nimport { useMemoObject } from '../../hooks/useMemoObject';\nimport { FileUploaderControlContext } from '../../internal/FileUploaderControl/FileUploaderControlContext';\nimport { useControlLocale } from '../../internal/FileUploaderControl/hooks/useControlLocale';\nimport { useUpload } from '../../internal/FileUploaderControl/hooks/useUpload';\nimport { useDrop } from '../../hooks/useDrop';\nimport { ThemeContext } from '../../lib/theming/ThemeContext';\nimport { UploadIcon } from '../../internal/icons/16px';\nimport { FileUploaderControlProviderProps } from '../../internal/FileUploaderControl/FileUploaderControlProvider';\nimport { withFileUploaderControlProvider } from '../../internal/FileUploaderControl/withFileUploaderControlProvider';\nimport { keyListener } from '../../lib/events/keyListener';\nimport { FileUploaderFile } from '../../internal/FileUploaderControl/FileUploaderFile/FileUploaderFile';\nimport { FileUploaderFileList } from '../../internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList';\nimport { CommonProps, CommonWrapper } from '../../internal/CommonWrapper';\nimport { Nullable } from '../../typings/utility-types';\nimport { FileUploaderFileValidationResult } from '../../internal/FileUploaderControl/FileUploaderFileValidationResult';\nimport { useFileUploaderSize } from '../../internal/FileUploaderControl/hooks/useFileUploaderSize';\nimport { isTheme2022 } from '../../lib/theming/ThemeHelpers';\nimport { SizeProp } from '../../lib/types/props';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName';\nimport { FocusControlWrapper } from '../../internal/FocusControlWrapper';\n\nimport { UploadIcon as UploadIcon2022 } from './UploadIcon';\nimport { globalClasses, jsStyles } from './FileUploader.styles';\n\nconst stopPropagation: React.ReactEventHandler = (e) => e.stopPropagation();\n\n/**\n * @deprecated use SizeProp\n */\nexport type FileUploaderSize = SizeProp;\n\ntype FileUploaderOverriddenProps = 'size';\n\ninterface _FileUploaderProps\n extends CommonProps,\n Omit<React.InputHTMLAttributes<HTMLInputElement>, FileUploaderOverriddenProps> {\n /** Состояние ошибки всего контрола */\n error?: boolean;\n /** Состояние предупреждения всего контрола */\n warning?: boolean;\n /** Свойство ширины. */\n width?: React.CSSProperties['width'];\n /**\n * Задаёт размер контрола.\n *\n * **Допустимые значения**: `\"small\"`, `\"medium\"`, `\"large\"`.\n */\n size?: SizeProp;\n /** Свойство, скрывающее отображение файлов. */\n hideFiles?: boolean;\n\n /** Функция, через которую отправляем файлы. Используется для отслеживания статуса загрузки файла. */\n request?: (file: FileUploaderAttachedFile) => Promise<void>;\n /** Срабатывает при удачной попытке отправки через request */\n onRequestSuccess?: (fileId: string) => void;\n /** Срабатывает при неудачной попытке отправки через request */\n onRequestError?: (fileId: string) => void;\n\n /**\n * Функция валидации каждого файла.\n * Срабатывает после выбора файлов и перед попыткой отправить в request.\n * Чтобы вывести валидацию ошибки, промис должен вернуть строку.\n * */\n validateBeforeUpload?: (file: FileUploaderAttachedFile) => Promise<Nullable<string>>;\n\n /**\n * Функция, позволяющая кастомизировать файлы.\n * Через нее можно вешать кастомные валидации на каждый файл.\n * */\n renderFile?: (file: FileUploaderAttachedFile, fileNode: React.ReactElement) => React.ReactNode;\n}\n\nexport interface FileUploaderRef extends InstanceWithRootNode {\n focus: () => void;\n blur: () => void;\n /** Сбрасывает выбранные файлы */\n reset: () => void;\n}\n\nexport const FileUploaderDataTids = {\n root: 'FileUploader__root',\n content: 'FileUploader__content',\n link: 'FileUploader__link',\n input: 'FileUploader__input',\n} as const;\n\nconst defaultRenderFile = (file: FileUploaderAttachedFile, fileNode: React.ReactElement) => fileNode;\n\nconst _FileUploader = forwardRefAndName<FileUploaderRef, _FileUploaderProps>('FileUploader', (props, ref) => {\n const theme = useContext(ThemeContext);\n const _isTheme2022 = isTheme2022(theme);\n\n const {\n disabled,\n error,\n warning,\n multiple = false,\n width = theme.fileUploaderWidth,\n hideFiles = false,\n onBlur,\n onFocus,\n onChange,\n request,\n validateBeforeUpload,\n onRequestSuccess,\n onRequestError,\n size = 'small',\n renderFile = defaultRenderFile,\n ...inputProps\n } = props;\n\n const { files, setFiles, removeFile, reset, setFileValidationResult, isMinLengthReached } =\n useContext(FileUploaderControlContext);\n\n const locale = useControlLocale();\n\n const inputRef = useRef<HTMLInputElement>(null);\n const fileDivRef = useRef<HTMLDivElement>(null);\n\n const isAsync = !!request;\n const isSingleMode = !multiple;\n\n const [isLinkVisible, setIsLinkVisible] = useState(true);\n const upload = useUpload(request, onRequestSuccess, onRequestError);\n\n const tryValidateAndUpload = useCallback(\n (files: FileUploaderAttachedFile[]) => {\n files.forEach(async (file) => {\n const validationMessage = validateBeforeUpload && (await validateBeforeUpload(file));\n\n if (!validationMessage) {\n isAsync && upload(file);\n } else {\n setFileValidationResult(file.id, FileUploaderFileValidationResult.error(validationMessage));\n }\n });\n },\n [validateBeforeUpload, isAsync, upload, setFileValidationResult],\n );\n\n const sizeClassName = useFileUploaderSize(size, {\n small: jsStyles.sizeSmall(theme),\n medium: jsStyles.sizeMedium(theme),\n large: jsStyles.sizeLarge(theme),\n });\n\n const sizeIconClass = useFileUploaderSize(size, {\n small: jsStyles.iconSmall(theme),\n medium: jsStyles.iconMedium(theme),\n large: jsStyles.iconLarge(theme),\n });\n\n const contentInnerClass = useFileUploaderSize(size, {\n small: jsStyles.contentInnerSmall(theme),\n medium: jsStyles.contentInnerMedium(theme),\n large: jsStyles.contentInnerLarge(theme),\n });\n\n /** common part **/\n const handleChange = useCallback(\n (newFiles: FileList | null) => {\n if (!newFiles) {\n return;\n }\n\n let filesArray = Array.from(newFiles);\n\n if (isSingleMode) {\n filesArray = [filesArray[0]];\n }\n\n const attachedFiles = filesArray.map(getAttachedFile);\n\n if (isSingleMode && attachedFiles.length && files.length) {\n removeFile(files[0].id);\n }\n\n if (attachedFiles.length) {\n setFiles(attachedFiles);\n tryValidateAndUpload(attachedFiles);\n }\n },\n [tryValidateAndUpload, setFiles, isSingleMode, files, removeFile],\n );\n\n const handleDrop = useCallback(\n (event) => {\n if (disabled) {\n return;\n }\n\n const { dataTransfer } = event;\n const { files } = dataTransfer;\n\n if (files?.length > 0) {\n handleChange(files);\n dataTransfer.clearData();\n }\n },\n [handleChange, disabled],\n );\n\n const { isDraggable, ref: labelRef } = useDrop<HTMLLabelElement>({ onDrop: handleDrop });\n const { isDraggable: isWindowDraggable, ref: windowRef } = useDrop<Document>();\n\n if (isBrowser(globalObject)) {\n windowRef.current = globalObject.document;\n }\n\n const focus = useCallback(() => {\n keyListener.isTabPressed = true;\n inputRef.current?.focus();\n }, []);\n\n const blur = useCallback(() => {\n inputRef.current?.blur();\n }, []);\n\n useImperativeHandle(ref, () => ({ focus, blur, reset, getRootNode: () => rootNodeRef.current }), [\n ref,\n blur,\n focus,\n reset,\n ]);\n\n const [focusedByTab, setFocusedByTab] = useState(false);\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.(event);\n handleChange(event.target.files);\n };\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n if (!disabled) {\n // focus event fires before keyDown eventlistener\n // so we should check tabPressed in async way\n globalObject.requestAnimationFrame?.(() => {\n if (keyListener.isTabPressed) {\n setFocusedByTab(true);\n }\n });\n onFocus?.(e);\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedByTab(false);\n if (!disabled) {\n onBlur?.(e);\n }\n };\n\n const [hovered, setHovered] = useState(false);\n\n const uploadButtonClassNames = cx(\n jsStyles.uploadButton(theme),\n sizeClassName,\n focusedByTab && jsStyles.uploadButtonFocus(theme),\n disabled && jsStyles.disabled(theme),\n !disabled && hovered && jsStyles.hovered(theme),\n !!warning && jsStyles.warning(theme),\n !!error && jsStyles.error(theme),\n isDraggable && !disabled && jsStyles.dragOver(theme),\n );\n\n const canDrop = isWindowDraggable && !disabled;\n const uploadButtonWrapperClassNames = cx(\n !_isTheme2022 && canDrop && jsStyles.windowDragOver(theme),\n _isTheme2022 && canDrop && jsStyles.windowDragOver2022(theme),\n );\n\n const uploadButtonIconClassNames = cx(jsStyles.icon(theme), sizeIconClass, disabled && jsStyles.iconDisabled(theme));\n\n const hasOneFile = files.length === 1;\n const hasOneFileForSingle = isSingleMode && hasOneFile && !hideFiles;\n\n const contentClassNames = cx(jsStyles.content(), hasOneFileForSingle && jsStyles.contentWithFiles());\n\n const linkClassNames = cx(\n jsStyles.link(theme),\n !disabled && hovered && jsStyles.linkHovered(theme),\n disabled && jsStyles.linkDisabled(theme),\n );\n\n useEffect(() => {\n setIsLinkVisible(hasOneFileForSingle ? !isMinLengthReached : true);\n }, [isMinLengthReached, hasOneFileForSingle]);\n\n const rootNodeRef = useRef(null);\n\n const iconSizes: Record<SizeProp, number> = {\n small: parseInt(theme.btnIconSizeSmall),\n medium: parseInt(theme.btnIconSizeMedium),\n large: parseInt(theme.btnIconSizeLarge),\n };\n const icon = _isTheme2022 ? <UploadIcon2022 size={iconSizes[size]} /> : <UploadIcon />;\n\n return (\n <CommonWrapper {...props}>\n <div\n data-tid={FileUploaderDataTids.root}\n className={jsStyles.root(theme)}\n style={useMemoObject({ width })}\n ref={rootNodeRef}\n >\n {!hideFiles && !isSingleMode && !!files.length && <FileUploaderFileList renderFile={renderFile} size={size} />}\n <div className={uploadButtonWrapperClassNames}>\n <label\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n ref={labelRef}\n className={uploadButtonClassNames}\n >\n <div\n data-tid={FileUploaderDataTids.content}\n className={cx(contentClassNames, { [contentInnerClass]: !files.length || !isSingleMode })}\n >\n {isLinkVisible && (\n <span data-tid={FileUploaderDataTids.link} className={linkClassNames}>\n {hasOneFileForSingle ? locale.choosedFile : locale.chooseFile}\n </span>\n )}\n {isLinkVisible && String.fromCharCode(0xa0) /* &nbsp; */}\n <div\n className={cx(\n globalClasses.afterLinkText,\n hasOneFileForSingle ? jsStyles.afterLinkText_HasFiles(theme) : jsStyles.afterLinkText(theme),\n )}\n >\n {hasOneFileForSingle ? (\n <div ref={fileDivRef} className={jsStyles.singleFile()}>\n {renderFile(files[0], <FileUploaderFile file={files[0]} size={size} />)}\n </div>\n ) : (\n <>\n {locale.orDragHere}&nbsp;\n <div className={uploadButtonIconClassNames}>{icon}</div>\n </>\n )}\n </div>\n </div>\n <FocusControlWrapper onBlurWhenDisabled={() => setFocusedByTab(false)}>\n <input\n {...inputProps}\n data-tid={FileUploaderDataTids.input}\n ref={inputRef}\n tabIndex={disabled ? -1 : 0}\n type=\"file\"\n disabled={disabled}\n multiple={multiple}\n className={jsStyles.visuallyHidden()}\n onClick={stopPropagation}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n // для того, чтобы срабатывало событие change при выборе одного и того же файла подряд\n value={''}\n />\n </FocusControlWrapper>\n </label>\n </div>\n </div>\n </CommonWrapper>\n );\n});\n\nexport interface FileUploaderProps extends _FileUploaderProps, FileUploaderControlProviderProps {}\n\nexport const FileUploader = withFileUploaderControlProvider<FileUploaderProps, FileUploaderRef>(\n React.memo(_FileUploader),\n);\nFileUploader.displayName = 'FileUploader';\n"]}
1
+ {"version":3,"sources":["FileUploader.tsx"],"names":["stopPropagation","e","FileUploaderDataTids","root","content","link","input","defaultRenderFile","file","fileNode","_FileUploader","props","ref","theme","ThemeContext","_isTheme2022","initialFiles","disabled","error","warning","multiple","width","fileUploaderWidth","hideFiles","onBlur","onFocus","onChange","request","validateBeforeUpload","onRequestSuccess","onRequestError","size","renderFile","inputProps","FileUploaderControlContext","files","setFiles","removeFile","reset","setFileValidationResult","isMinLengthReached","locale","inputRef","fileDivRef","isAsync","isSingleMode","isLinkVisible","setIsLinkVisible","upload","tryValidateAndUpload","forEach","validationMessage","id","FileUploaderFileValidationResult","sizeClassName","small","jsStyles","sizeSmall","medium","sizeMedium","large","sizeLarge","sizeIconClass","iconSmall","iconMedium","iconLarge","contentInnerClass","contentInnerSmall","contentInnerMedium","contentInnerLarge","handleChange","newFiles","length","filesArray","Array","from","attachedFiles","map","getAttachedFile","handleDrop","event","dataTransfer","clearData","onDrop","isDraggable","labelRef","isWindowDraggable","windowRef","globalObject","current","document","focus","keyListener","isTabPressed","blur","getRootNode","rootNodeRef","focusedByTab","setFocusedByTab","handleInputChange","target","handleFocus","requestAnimationFrame","handleBlur","handleRemoveFile","fileId","DataTransfer","filter","f","items","add","originalFile","hovered","setHovered","uploadButtonClassNames","uploadButton","uploadButtonFocus","dragOver","canDrop","uploadButtonWrapperClassNames","windowDragOver","windowDragOver2022","uploadButtonIconClassNames","icon","iconDisabled","hasOneFile","hasOneFileForSingle","contentClassNames","contentWithFiles","linkClassNames","linkHovered","linkDisabled","iconSizes","parseInt","btnIconSizeSmall","btnIconSizeMedium","btnIconSizeLarge","choosedFile","chooseFile","String","fromCharCode","globalClasses","afterLinkText","afterLinkText_HasFiles","singleFile","orDragHere","visuallyHidden","FileUploader","React","memo","displayName"],"mappings":"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","sourcesContent":["import React, { useCallback, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { globalObject, isBrowser } from '@skbkontur/global-object';\n\nimport { FileUploaderAttachedFile, getAttachedFile } from '../../internal/FileUploaderControl/fileUtils';\nimport { cx } from '../../lib/theming/Emotion';\nimport { InstanceWithRootNode } from '../../lib/rootNode';\nimport { useMemoObject } from '../../hooks/useMemoObject';\nimport { FileUploaderControlContext } from '../../internal/FileUploaderControl/FileUploaderControlContext';\nimport { useControlLocale } from '../../internal/FileUploaderControl/hooks/useControlLocale';\nimport { useUpload } from '../../internal/FileUploaderControl/hooks/useUpload';\nimport { useDrop } from '../../hooks/useDrop';\nimport { ThemeContext } from '../../lib/theming/ThemeContext';\nimport { UploadIcon } from '../../internal/icons/16px';\nimport { FileUploaderControlProviderProps } from '../../internal/FileUploaderControl/FileUploaderControlProvider';\nimport { withFileUploaderControlProvider } from '../../internal/FileUploaderControl/withFileUploaderControlProvider';\nimport { keyListener } from '../../lib/events/keyListener';\nimport { FileUploaderFile } from '../../internal/FileUploaderControl/FileUploaderFile/FileUploaderFile';\nimport { FileUploaderFileList } from '../../internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList';\nimport { CommonProps, CommonWrapper } from '../../internal/CommonWrapper';\nimport { Nullable } from '../../typings/utility-types';\nimport { FileUploaderFileValidationResult } from '../../internal/FileUploaderControl/FileUploaderFileValidationResult';\nimport { useFileUploaderSize } from '../../internal/FileUploaderControl/hooks/useFileUploaderSize';\nimport { isTheme2022 } from '../../lib/theming/ThemeHelpers';\nimport { SizeProp } from '../../lib/types/props';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName';\nimport { FocusControlWrapper } from '../../internal/FocusControlWrapper';\n\nimport { UploadIcon as UploadIcon2022 } from './UploadIcon';\nimport { globalClasses, jsStyles } from './FileUploader.styles';\n\nconst stopPropagation: React.ReactEventHandler = (e) => e.stopPropagation();\n\n/**\n * @deprecated use SizeProp\n */\nexport type FileUploaderSize = SizeProp;\n\ntype FileUploaderOverriddenProps = 'size';\n\ninterface _FileUploaderProps\n extends CommonProps,\n Omit<React.InputHTMLAttributes<HTMLInputElement>, FileUploaderOverriddenProps> {\n /** Начальное состояние загруженных файлов */\n initialFiles?: File[];\n /** Состояние ошибки всего контрола */\n error?: boolean;\n /** Состояние предупреждения всего контрола */\n warning?: boolean;\n /** Свойство ширины. */\n width?: React.CSSProperties['width'];\n /**\n * Задаёт размер контрола.\n *\n * **Допустимые значения**: `\"small\"`, `\"medium\"`, `\"large\"`.\n */\n size?: SizeProp;\n /** Свойство, скрывающее отображение файлов. */\n hideFiles?: boolean;\n\n /** Функция, через которую отправляем файлы. Используется для отслеживания статуса загрузки файла. */\n request?: (file: FileUploaderAttachedFile) => Promise<void>;\n /** Срабатывает при удачной попытке отправки через request */\n onRequestSuccess?: (fileId: string) => void;\n /** Срабатывает при неудачной попытке отправки через request */\n onRequestError?: (fileId: string) => void;\n\n /**\n * Функция валидации каждого файла.\n * Срабатывает после выбора файлов и перед попыткой отправить в request.\n * Чтобы вывести валидацию ошибки, промис должен вернуть строку.\n * */\n validateBeforeUpload?: (file: FileUploaderAttachedFile) => Promise<Nullable<string>>;\n\n /**\n * Функция, позволяющая кастомизировать файлы.\n * Через нее можно вешать кастомные валидации на каждый файл.\n * */\n renderFile?: (file: FileUploaderAttachedFile, fileNode: React.ReactElement) => React.ReactNode;\n}\n\nexport interface FileUploaderRef extends InstanceWithRootNode {\n focus: () => void;\n blur: () => void;\n /** Сбрасывает выбранные файлы */\n reset: () => void;\n}\n\nexport const FileUploaderDataTids = {\n root: 'FileUploader__root',\n content: 'FileUploader__content',\n link: 'FileUploader__link',\n input: 'FileUploader__input',\n} as const;\n\nconst defaultRenderFile = (file: FileUploaderAttachedFile, fileNode: React.ReactElement) => fileNode;\n\nconst _FileUploader = forwardRefAndName<FileUploaderRef, _FileUploaderProps>('FileUploader', (props, ref) => {\n const theme = useContext(ThemeContext);\n const _isTheme2022 = isTheme2022(theme);\n\n const {\n initialFiles,\n disabled,\n error,\n warning,\n multiple = false,\n width = theme.fileUploaderWidth,\n hideFiles = false,\n onBlur,\n onFocus,\n onChange,\n request,\n validateBeforeUpload,\n onRequestSuccess,\n onRequestError,\n size = 'small',\n renderFile = defaultRenderFile,\n ...inputProps\n } = props;\n\n const { files, setFiles, removeFile, reset, setFileValidationResult, isMinLengthReached } =\n useContext(FileUploaderControlContext);\n\n const locale = useControlLocale();\n\n const inputRef = useRef<HTMLInputElement>(null);\n const fileDivRef = useRef<HTMLDivElement>(null);\n\n const isAsync = !!request;\n const isSingleMode = !multiple;\n\n const [isLinkVisible, setIsLinkVisible] = useState(true);\n const upload = useUpload(request, onRequestSuccess, onRequestError);\n\n const tryValidateAndUpload = useCallback(\n (files: FileUploaderAttachedFile[]) => {\n files.forEach(async (file) => {\n const validationMessage = validateBeforeUpload && (await validateBeforeUpload(file));\n\n if (!validationMessage) {\n isAsync && upload(file);\n } else {\n setFileValidationResult(file.id, FileUploaderFileValidationResult.error(validationMessage));\n }\n });\n },\n [validateBeforeUpload, isAsync, upload, setFileValidationResult],\n );\n\n const sizeClassName = useFileUploaderSize(size, {\n small: jsStyles.sizeSmall(theme),\n medium: jsStyles.sizeMedium(theme),\n large: jsStyles.sizeLarge(theme),\n });\n\n const sizeIconClass = useFileUploaderSize(size, {\n small: jsStyles.iconSmall(theme),\n medium: jsStyles.iconMedium(theme),\n large: jsStyles.iconLarge(theme),\n });\n\n const contentInnerClass = useFileUploaderSize(size, {\n small: jsStyles.contentInnerSmall(theme),\n medium: jsStyles.contentInnerMedium(theme),\n large: jsStyles.contentInnerLarge(theme),\n });\n\n /** common part **/\n const handleChange = useCallback(\n (newFiles: FileList | null) => {\n if (!newFiles || !newFiles.length) {\n return;\n }\n\n let filesArray = Array.from(newFiles);\n\n if (isSingleMode) {\n filesArray = [filesArray[0]];\n }\n\n const attachedFiles = filesArray.map(getAttachedFile);\n\n if (isSingleMode && attachedFiles.length && files.length) {\n removeFile(files[0].id);\n }\n\n if (attachedFiles.length) {\n setFiles(attachedFiles);\n tryValidateAndUpload(attachedFiles);\n }\n },\n [tryValidateAndUpload, setFiles, isSingleMode, files, removeFile],\n );\n\n const handleDrop = useCallback(\n (event) => {\n if (disabled) {\n return;\n }\n\n const { dataTransfer } = event;\n const { files } = dataTransfer;\n\n if (files?.length > 0) {\n handleChange(files);\n dataTransfer.clearData();\n }\n },\n [handleChange, disabled],\n );\n\n const { isDraggable, ref: labelRef } = useDrop<HTMLLabelElement>({ onDrop: handleDrop });\n const { isDraggable: isWindowDraggable, ref: windowRef } = useDrop<Document>();\n\n if (isBrowser(globalObject)) {\n windowRef.current = globalObject.document;\n }\n\n const focus = useCallback(() => {\n keyListener.isTabPressed = true;\n inputRef.current?.focus();\n }, []);\n\n const blur = useCallback(() => {\n inputRef.current?.blur();\n }, []);\n\n useImperativeHandle(ref, () => ({ focus, blur, reset, getRootNode: () => rootNodeRef.current }), [\n ref,\n blur,\n focus,\n reset,\n ]);\n\n const [focusedByTab, setFocusedByTab] = useState(false);\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.(event);\n handleChange(event.target.files);\n };\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n if (!disabled) {\n // focus event fires before keyDown eventlistener\n // so we should check tabPressed in async way\n globalObject.requestAnimationFrame?.(() => {\n if (keyListener.isTabPressed) {\n setFocusedByTab(true);\n }\n });\n onFocus?.(e);\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedByTab(false);\n if (!disabled) {\n onBlur?.(e);\n }\n };\n\n const handleRemoveFile = useCallback((fileId: string) => {\n const dataTransfer = new DataTransfer();\n files\n .filter((f) => f.id !== fileId)\n .forEach((file) => {\n dataTransfer.items.add(file.originalFile);\n });\n inputRef.current && (inputRef.current.files = dataTransfer.files);\n }, []);\n\n const [hovered, setHovered] = useState(false);\n\n const uploadButtonClassNames = cx(\n jsStyles.uploadButton(theme),\n sizeClassName,\n focusedByTab && jsStyles.uploadButtonFocus(theme),\n disabled && jsStyles.disabled(theme),\n !disabled && hovered && jsStyles.hovered(theme),\n !!warning && jsStyles.warning(theme),\n !!error && jsStyles.error(theme),\n isDraggable && !disabled && jsStyles.dragOver(theme),\n );\n\n const canDrop = isWindowDraggable && !disabled;\n const uploadButtonWrapperClassNames = cx(\n !_isTheme2022 && canDrop && jsStyles.windowDragOver(theme),\n _isTheme2022 && canDrop && jsStyles.windowDragOver2022(theme),\n );\n\n const uploadButtonIconClassNames = cx(jsStyles.icon(theme), sizeIconClass, disabled && jsStyles.iconDisabled(theme));\n\n const hasOneFile = files.length === 1;\n const hasOneFileForSingle = isSingleMode && hasOneFile && !hideFiles;\n\n const contentClassNames = cx(jsStyles.content(), hasOneFileForSingle && jsStyles.contentWithFiles());\n\n const linkClassNames = cx(\n jsStyles.link(theme),\n !disabled && hovered && jsStyles.linkHovered(theme),\n disabled && jsStyles.linkDisabled(theme),\n );\n\n useEffect(() => {\n setIsLinkVisible(hasOneFileForSingle ? !isMinLengthReached : true);\n }, [isMinLengthReached, hasOneFileForSingle]);\n\n useEffect(() => {\n if (!files || !files.length || !inputRef.current) {\n return;\n }\n\n const dataTransfer = new DataTransfer();\n files.forEach((file) => dataTransfer.items.add(file.originalFile));\n inputRef.current.files = dataTransfer.files;\n }, []);\n\n const rootNodeRef = useRef(null);\n\n const iconSizes: Record<SizeProp, number> = {\n small: parseInt(theme.btnIconSizeSmall),\n medium: parseInt(theme.btnIconSizeMedium),\n large: parseInt(theme.btnIconSizeLarge),\n };\n const icon = _isTheme2022 ? <UploadIcon2022 size={iconSizes[size]} /> : <UploadIcon />;\n\n return (\n <CommonWrapper {...props}>\n <div\n data-tid={FileUploaderDataTids.root}\n className={jsStyles.root(theme)}\n style={useMemoObject({ width })}\n ref={rootNodeRef}\n >\n {!hideFiles && !isSingleMode && !!files.length && (\n <FileUploaderFileList renderFile={renderFile} size={size} onRemove={handleRemoveFile} />\n )}\n <div className={uploadButtonWrapperClassNames}>\n <label\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n ref={labelRef}\n className={uploadButtonClassNames}\n >\n <div\n data-tid={FileUploaderDataTids.content}\n className={cx(contentClassNames, { [contentInnerClass]: !files.length || !isSingleMode })}\n >\n {isLinkVisible && (\n <span data-tid={FileUploaderDataTids.link} className={linkClassNames}>\n {hasOneFileForSingle ? locale.choosedFile : locale.chooseFile}\n </span>\n )}\n {isLinkVisible && String.fromCharCode(0xa0) /* &nbsp; */}\n <div\n className={cx(\n globalClasses.afterLinkText,\n hasOneFileForSingle ? jsStyles.afterLinkText_HasFiles(theme) : jsStyles.afterLinkText(theme),\n )}\n >\n {hasOneFileForSingle ? (\n <div ref={fileDivRef} className={jsStyles.singleFile()}>\n {renderFile(files[0], <FileUploaderFile file={files[0]} size={size} onRemove={handleRemoveFile} />)}\n </div>\n ) : (\n <>\n {locale.orDragHere}&nbsp;\n <div className={uploadButtonIconClassNames}>{icon}</div>\n </>\n )}\n </div>\n </div>\n <FocusControlWrapper onBlurWhenDisabled={() => setFocusedByTab(false)}>\n <input\n {...inputProps}\n data-tid={FileUploaderDataTids.input}\n ref={inputRef}\n tabIndex={disabled ? -1 : 0}\n type=\"file\"\n disabled={disabled}\n multiple={multiple}\n className={jsStyles.visuallyHidden()}\n onClick={stopPropagation}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n />\n </FocusControlWrapper>\n </label>\n </div>\n </div>\n </CommonWrapper>\n );\n});\n\nexport interface FileUploaderProps extends _FileUploaderProps, FileUploaderControlProviderProps {}\n\nexport const FileUploader = withFileUploaderControlProvider<FileUploaderProps, FileUploaderRef>(\n React.memo(_FileUploader),\n);\nFileUploader.displayName = 'FileUploader';\n"]}
@@ -27,6 +27,35 @@ const request = () => Promise.reject();
27
27
  <FileUploader request={request} multiple />
28
28
  ```
29
29
 
30
+ Файлы по умолчанию
31
+ ```jsx harmony
32
+ import { FileUploader } from '@skbkontur/react-ui';
33
+
34
+ function createFile(filename, content) {
35
+ return new File(['content'], filename, { type: 'text/plain' });
36
+ };
37
+
38
+ const initialFiles = [createFile('test1.txt'), createFile('test2.txt')];
39
+ <FileUploader multiple initialFiles={initialFiles} />
40
+ ```
41
+
42
+ Файлы по умолчанию с кастомизацией рендеринга
43
+ ```jsx harmony
44
+ import { cloneElement } from 'react';
45
+ import { FileUploader } from '@skbkontur/react-ui';
46
+
47
+ function createFile(filename, content) {
48
+ return new File(['content'], filename, { type: 'text/plain' });
49
+ };
50
+
51
+ const initialFiles = [createFile('test1.txt'), createFile('test2.txt')];
52
+ <FileUploader
53
+ multiple
54
+ initialFiles={initialFiles}
55
+ renderFile={(file, fileNode) => cloneElement(fileNode, { showSize: false })}
56
+ />
57
+ ```
58
+
30
59
  Использование `accept`
31
60
  ```jsx harmony
32
61
  import { FileUploader } from '@skbkontur/react-ui';
@@ -1,6 +1,6 @@
1
1
  import { MutableRefObject } from 'react';
2
2
  interface IUseDropProps {
3
- onDrop?: (event: Event) => void;
3
+ onDrop?: (event: DragEvent) => void;
4
4
  }
5
5
  declare type IElementWithListener = Pick<HTMLElement, 'addEventListener' | 'removeEventListener'>;
6
6
  interface IUseDropResult<TElement extends IElementWithListener> {
@@ -1 +1 @@
1
- {"version":3,"sources":["useDrop.ts"],"names":["useDrop","props","onDrop","droppableRef","overRef","timerId","isDraggable","setIsDraggable","clearTimer","current","globalObject","clearTimeout","handleDragOver","event","preventDefault","setTimeout","stopPropagation","handleDrop","ref","addEventListener","removeEventListener"],"mappings":"gEAAA;AACA;;;;;;;;;;;;;AAaO,IAAMA,OAAO,GAAG,SAAVA,OAAU,CAAwCC,KAAxC,EAAgG,KAAxDA,KAAwD,cAAxDA,KAAwD,GAAjC,EAAiC;AACrH,eAAmBA,KAAnB,CAAQC,MAAR,UAAQA,MAAR;;AAEA,MAAMC,YAAY,GAAG,mBAAiB,IAAjB,CAArB;AACA,MAAMC,OAAO,GAAG,mBAAgB,KAAhB,CAAhB;AACA,MAAMC,OAAO,GAAG,oBAAhB;AACA,kBAAsC,qBAAkB,KAAlB,CAAtC,CAAOC,WAAP,gBAAoBC,cAApB;;AAEA,MAAMC,UAAU,GAAG,wBAAY,YAAM;AACnCH,IAAAA,OAAO,CAACI,OAAR,IAAmBC,2BAAaC,YAAb,CAA0BN,OAAO,CAACI,OAAlC,CAAnB;AACD,GAFkB,EAEhB,EAFgB,CAAnB;;AAIA,MAAMG,cAAc,GAAG;AACrB,YAACC,KAAD,EAAW;AACTA,IAAAA,KAAK,CAACC,cAAN;AACAP,IAAAA,cAAc,CAAC,IAAD,CAAd;;AAEAC,IAAAA,UAAU;AACVH,IAAAA,OAAO,CAACI,OAAR,GAAkBC,2BAAaK,UAAb,CAAwB,YAAM;AAC9CX,MAAAA,OAAO,CAACK,OAAR,GAAkB,KAAlB;AACAF,MAAAA,cAAc,CAAC,KAAD,CAAd;AACD,KAHiB,EAGf,GAHe,CAAlB;AAID,GAVoB;AAWrB,GAACC,UAAD,CAXqB,CAAvB;;;AAcA,MAAMM,cAAc,GAAG,wBAAY,UAACD,KAAD,EAAW;AAC5CA,IAAAA,KAAK,CAACC,cAAN;AACAD,IAAAA,KAAK,CAACG,eAAN;AACD,GAHsB,EAGpB,EAHoB,CAAvB;;AAKA,MAAMC,UAAU,GAAG;AACjB,YAACJ,KAAD,EAAkB;AAChBC,IAAAA,cAAc,CAACD,KAAD,CAAd;AACAN,IAAAA,cAAc,CAAC,KAAD,CAAd;AACAH,IAAAA,OAAO,CAACK,OAAR,GAAkB,KAAlB;;AAEAP,IAAAA,MAAM,QAAN,YAAAA,MAAM,CAAGW,KAAH,CAAN;AACD,GAPgB;AAQjB,GAACC,cAAD,EAAiBZ,MAAjB,CARiB,CAAnB;;;AAWA,wBAAU,YAAM;AACd,QAAMgB,GAAG,GAAGf,YAAY,CAACM,OAAzB;;AAEA,QAAI,CAACS,GAAL,EAAU;AACR;AACD;;AAEDA,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,WAArB,EAAkCL,cAAlC;AACAI,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,WAArB,EAAkCL,cAAlC;AACAI,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,UAArB,EAAiCP,cAAjC;AACAM,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,MAArB,EAA6BF,UAA7B;;AAEA,WAAO,YAAM;AACXC,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,WAAxB,EAAqCN,cAArC;AACAI,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,WAAxB,EAAqCN,cAArC;AACAI,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,UAAxB,EAAoCR,cAApC;AACAM,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,MAAxB,EAAgCH,UAAhC;AACD,KALD;AAMD,GAlBD,EAkBG,CAACA,UAAD,EAAaL,cAAb,EAA6BE,cAA7B,CAlBH;;AAoBA,SAAO,EAAER,WAAW,EAAXA,WAAF,EAAeY,GAAG,EAAEf,YAApB,EAAP;AACD,CA/DM,C","sourcesContent":["import { MutableRefObject, useCallback, useEffect, useRef, useState } from 'react';\nimport { globalObject, SafeTimer } from '@skbkontur/global-object';\n\ninterface IUseDropProps {\n onDrop?: (event: Event) => void;\n}\n\ntype IElementWithListener = Pick<HTMLElement, 'addEventListener' | 'removeEventListener'>;\n\ninterface IUseDropResult<TElement extends IElementWithListener> {\n isDraggable: boolean;\n ref: MutableRefObject<TElement | null>;\n}\n\nexport const useDrop = <TElement extends IElementWithListener>(props: IUseDropProps = {}): IUseDropResult<TElement> => {\n const { onDrop } = props;\n\n const droppableRef = useRef<TElement>(null);\n const overRef = useRef<boolean>(false);\n const timerId = useRef<SafeTimer>();\n const [isDraggable, setIsDraggable] = useState<boolean>(false);\n\n const clearTimer = useCallback(() => {\n timerId.current && globalObject.clearTimeout(timerId.current);\n }, []);\n\n const handleDragOver = useCallback(\n (event) => {\n event.preventDefault();\n setIsDraggable(true);\n\n clearTimer();\n timerId.current = globalObject.setTimeout(() => {\n overRef.current = false;\n setIsDraggable(false);\n }, 200);\n },\n [clearTimer],\n );\n\n const preventDefault = useCallback((event) => {\n event.preventDefault();\n event.stopPropagation();\n }, []);\n\n const handleDrop = useCallback(\n (event: Event) => {\n preventDefault(event);\n setIsDraggable(false);\n overRef.current = false;\n\n onDrop?.(event);\n },\n [preventDefault, onDrop],\n );\n\n useEffect(() => {\n const ref = droppableRef.current;\n\n if (!ref) {\n return;\n }\n\n ref.addEventListener('dragenter', preventDefault);\n ref.addEventListener('dragleave', preventDefault);\n ref.addEventListener('dragover', handleDragOver);\n ref.addEventListener('drop', handleDrop);\n\n return () => {\n ref.removeEventListener('dragenter', preventDefault);\n ref.removeEventListener('dragleave', preventDefault);\n ref.removeEventListener('dragover', handleDragOver);\n ref.removeEventListener('drop', handleDrop);\n };\n }, [handleDrop, handleDragOver, preventDefault]);\n\n return { isDraggable, ref: droppableRef };\n};\n"]}
1
+ {"version":3,"sources":["useDrop.ts"],"names":["useDrop","props","onDrop","droppableRef","overRef","timerId","isDraggable","setIsDraggable","clearTimer","current","globalObject","clearTimeout","handleDragOver","event","preventDefault","setTimeout","stopPropagation","handleDrop","ref","addEventListener","removeEventListener"],"mappings":"gEAAA;AACA;;;;;;;;;;;;;AAaO,IAAMA,OAAO,GAAG,SAAVA,OAAU,CAAwCC,KAAxC,EAAgG,KAAxDA,KAAwD,cAAxDA,KAAwD,GAAjC,EAAiC;AACrH,eAAmBA,KAAnB,CAAQC,MAAR,UAAQA,MAAR;;AAEA,MAAMC,YAAY,GAAG,mBAAiB,IAAjB,CAArB;AACA,MAAMC,OAAO,GAAG,mBAAgB,KAAhB,CAAhB;AACA,MAAMC,OAAO,GAAG,oBAAhB;AACA,kBAAsC,qBAAkB,KAAlB,CAAtC,CAAOC,WAAP,gBAAoBC,cAApB;;AAEA,MAAMC,UAAU,GAAG,wBAAY,YAAM;AACnCH,IAAAA,OAAO,CAACI,OAAR,IAAmBC,2BAAaC,YAAb,CAA0BN,OAAO,CAACI,OAAlC,CAAnB;AACD,GAFkB,EAEhB,EAFgB,CAAnB;;AAIA,MAAMG,cAAc,GAAG;AACrB,YAACC,KAAD,EAAsB;AACpBA,IAAAA,KAAK,CAACC,cAAN;AACAP,IAAAA,cAAc,CAAC,IAAD,CAAd;;AAEAC,IAAAA,UAAU;AACVH,IAAAA,OAAO,CAACI,OAAR,GAAkBC,2BAAaK,UAAb,CAAwB,YAAM;AAC9CX,MAAAA,OAAO,CAACK,OAAR,GAAkB,KAAlB;AACAF,MAAAA,cAAc,CAAC,KAAD,CAAd;AACD,KAHiB,EAGf,GAHe,CAAlB;AAID,GAVoB;AAWrB,GAACC,UAAD,CAXqB,CAAvB;;;AAcA,MAAMM,cAAc,GAAG,wBAAY,UAACD,KAAD,EAAsB;AACvDA,IAAAA,KAAK,CAACC,cAAN;AACAD,IAAAA,KAAK,CAACG,eAAN;AACD,GAHsB,EAGpB,EAHoB,CAAvB;;AAKA,MAAMC,UAAU,GAAG;AACjB,YAACJ,KAAD,EAAsB;AACpBC,IAAAA,cAAc,CAACD,KAAD,CAAd;AACAN,IAAAA,cAAc,CAAC,KAAD,CAAd;AACAH,IAAAA,OAAO,CAACK,OAAR,GAAkB,KAAlB;;AAEAP,IAAAA,MAAM,QAAN,YAAAA,MAAM,CAAGW,KAAH,CAAN;AACD,GAPgB;AAQjB,GAACC,cAAD,EAAiBZ,MAAjB,CARiB,CAAnB;;;AAWA,wBAAU,YAAM;AACd,QAAMgB,GAAG,GAAGf,YAAY,CAACM,OAAzB;;AAEA,QAAI,CAACS,GAAL,EAAU;AACR;AACD;;AAEDA,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,WAArB,EAAkCL,cAAlC;AACAI,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,WAArB,EAAkCL,cAAlC;AACAI,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,UAArB,EAAiCP,cAAjC;AACAM,IAAAA,GAAG,CAACC,gBAAJ,CAAqB,MAArB,EAA6BF,UAA7B;;AAEA,WAAO,YAAM;AACXC,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,WAAxB,EAAqCN,cAArC;AACAI,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,WAAxB,EAAqCN,cAArC;AACAI,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,UAAxB,EAAoCR,cAApC;AACAM,MAAAA,GAAG,CAACE,mBAAJ,CAAwB,MAAxB,EAAgCH,UAAhC;AACD,KALD;AAMD,GAlBD,EAkBG,CAACA,UAAD,EAAaL,cAAb,EAA6BE,cAA7B,CAlBH;;AAoBA,SAAO,EAAER,WAAW,EAAXA,WAAF,EAAeY,GAAG,EAAEf,YAApB,EAAP;AACD,CA/DM,C","sourcesContent":["import { MutableRefObject, useCallback, useEffect, useRef, useState } from 'react';\nimport { globalObject, SafeTimer } from '@skbkontur/global-object';\n\ninterface IUseDropProps {\n onDrop?: (event: DragEvent) => void;\n}\n\ntype IElementWithListener = Pick<HTMLElement, 'addEventListener' | 'removeEventListener'>;\n\ninterface IUseDropResult<TElement extends IElementWithListener> {\n isDraggable: boolean;\n ref: MutableRefObject<TElement | null>;\n}\n\nexport const useDrop = <TElement extends IElementWithListener>(props: IUseDropProps = {}): IUseDropResult<TElement> => {\n const { onDrop } = props;\n\n const droppableRef = useRef<TElement>(null);\n const overRef = useRef<boolean>(false);\n const timerId = useRef<SafeTimer>();\n const [isDraggable, setIsDraggable] = useState<boolean>(false);\n\n const clearTimer = useCallback(() => {\n timerId.current && globalObject.clearTimeout(timerId.current);\n }, []);\n\n const handleDragOver = useCallback(\n (event: DragEvent) => {\n event.preventDefault();\n setIsDraggable(true);\n\n clearTimer();\n timerId.current = globalObject.setTimeout(() => {\n overRef.current = false;\n setIsDraggable(false);\n }, 200);\n },\n [clearTimer],\n );\n\n const preventDefault = useCallback((event: DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n }, []);\n\n const handleDrop = useCallback(\n (event: DragEvent) => {\n preventDefault(event);\n setIsDraggable(false);\n overRef.current = false;\n\n onDrop?.(event);\n },\n [preventDefault, onDrop],\n );\n\n useEffect(() => {\n const ref = droppableRef.current;\n\n if (!ref) {\n return;\n }\n\n ref.addEventListener('dragenter', preventDefault);\n ref.addEventListener('dragleave', preventDefault);\n ref.addEventListener('dragover', handleDragOver);\n ref.addEventListener('drop', handleDrop);\n\n return () => {\n ref.removeEventListener('dragenter', preventDefault);\n ref.removeEventListener('dragleave', preventDefault);\n ref.removeEventListener('dragover', handleDragOver);\n ref.removeEventListener('drop', handleDrop);\n };\n }, [handleDrop, handleDragOver, preventDefault]);\n\n return { isDraggable, ref: droppableRef };\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { PropsWithChildren } from 'react';
1
+ import React, { PropsWithChildren } from 'react';
2
2
  import { FileUploaderAttachedFile } from './fileUtils';
3
3
  export interface FileUploaderControlProviderProps {
4
4
  /** Срабатывает при выборе файлов */
@@ -9,6 +9,9 @@ export interface FileUploaderControlProviderProps {
9
9
  onValueChange?: (files: FileUploaderAttachedFile[]) => void;
10
10
  }
11
11
  export declare const FileUploaderControlProvider: {
12
- (props: PropsWithChildren<FileUploaderControlProviderProps>): JSX.Element;
12
+ (props: React.PropsWithChildren<FileUploaderControlProviderProps & {
13
+ initialFiles?: File[] | undefined;
14
+ multiple?: boolean | undefined;
15
+ }>): JSX.Element;
13
16
  displayName: string;
14
17
  };