@ozen-ui/kit 0.40.0 → 0.41.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.
@@ -1,22 +1,24 @@
1
1
  /* stylelint-disable */
2
2
  .FieldControl {
3
3
  --textfield-color: var(--color-content-primary);
4
- --textfield-background-color: var(--color-background-primary);
5
4
  --textfield-border-width: var(--border-width-s);
6
5
  --textfield-border-color: var(--color-border-main);
6
+ --textfield-placeholder-color: var(--color-content-tertiary);
7
+ --textfield-background-color: var(--color-background-primary);
7
8
  cursor: text;
8
- display: inline-flex;
9
9
  vertical-align: top;
10
+ display: inline-flex;
10
11
  flex-direction: column;
11
12
  }
12
13
  .FieldControl > * {
13
14
  cursor: text;
14
15
  }
15
16
  .FieldControl_size_2xs {
16
- --textfield-gutter-x: 12px;
17
- --textfield-input-height: 32px;
18
17
  --textfield-input-padding: 8px 0;
19
18
  --textfield-input-gap: var(--spacing-2xs);
19
+ --textfield-gutter-x: var(--control-padding-xs);
20
+ --textfield-border-radius: var(--border-radius-xs);
21
+ --textfield-input-height: var(--control-height-2xs);
20
22
 
21
23
  font: var(--typography-text-2xs-font);
22
24
 
@@ -25,10 +27,11 @@
25
27
  text-transform: var(--typography-text-2xs-text_transform, none);
26
28
  }
27
29
  .FieldControl_size_xs {
28
- --textfield-gutter-x: 12px;
29
- --textfield-input-height: 40px;
30
30
  --textfield-input-padding: 12px 0;
31
31
  --textfield-input-gap: var(--spacing-2xs);
32
+ --textfield-gutter-x: var(--control-padding-xs);
33
+ --textfield-border-radius: var(--border-radius-xs);
34
+ --textfield-input-height: var(--control-height-xs);
32
35
 
33
36
  font: var(--typography-text-xs-font);
34
37
 
@@ -37,10 +40,11 @@
37
40
  text-transform: var(--typography-text-xs-text_transform, none);
38
41
  }
39
42
  .FieldControl_size_s {
40
- --textfield-gutter-x: 16px;
41
- --textfield-input-height: 48px;
42
43
  --textfield-input-padding: 14px 0;
43
44
  --textfield-input-gap: var(--spacing-xs);
45
+ --textfield-gutter-x: var(--control-padding-s);
46
+ --textfield-border-radius: var(--border-radius-xs);
47
+ --textfield-input-height: var(--control-height-s);
44
48
 
45
49
  font: var(--typography-text-s-font);
46
50
 
@@ -49,10 +53,11 @@
49
53
  text-transform: var(--typography-text-s-text_transform, none);
50
54
  }
51
55
  .FieldControl_size_m {
52
- --textfield-gutter-x: 20px;
53
- --textfield-input-height: 56px;
54
56
  --textfield-input-padding: 16px 0;
55
57
  --textfield-input-gap: var(--spacing-xs);
58
+ --textfield-gutter-x: var(--control-padding-m);
59
+ --textfield-border-radius: var(--border-radius-xs);
60
+ --textfield-input-height: var(--control-height-m);
56
61
 
57
62
  font: var(--typography-text-m-font);
58
63
 
@@ -61,10 +66,11 @@
61
66
  text-transform: var(--typography-text-m-text_transform, none);
62
67
  }
63
68
  .FieldControl_size_l {
64
- --textfield-gutter-x: 24px;
65
- --textfield-input-height: 64px;
66
69
  --textfield-input-padding: 18px 0;
67
70
  --textfield-input-gap: var(--spacing-s);
71
+ --textfield-gutter-x: var(--control-padding-l);
72
+ --textfield-border-radius: var(--border-radius-xs);
73
+ --textfield-input-height: var(--control-height-l);
68
74
 
69
75
  font: var(--typography-text-l-font);
70
76
 
@@ -76,16 +82,16 @@
76
82
  --textfield-input-padding: 8px 0 8px;
77
83
  }
78
84
  .FieldControl_hasLabel.FieldControl_size_xs {
79
- --textfield-input-padding: 19px 0 4px;
85
+ --textfield-input-padding: 20px 0 4px;
80
86
  }
81
87
  .FieldControl_hasLabel.FieldControl_size_s {
82
- --textfield-input-padding: 21px 0 6px;
88
+ --textfield-input-padding: 22px 0 6px;
83
89
  }
84
90
  .FieldControl_hasLabel.FieldControl_size_m {
85
- --textfield-input-padding: 24px 0 6px;
91
+ --textfield-input-padding: 24px 0 8px;
86
92
  }
87
93
  .FieldControl_hasLabel.FieldControl_size_l {
88
- --textfield-input-padding: 26px 0 6px;
94
+ --textfield-input-padding: 28px 0 8px;
89
95
  }
90
96
  .FieldControl_hasLabel .FieldInput::placeholder {
91
97
  opacity: 0;
@@ -102,8 +108,8 @@
102
108
  .FieldControl_focused,
103
109
  .FieldControl_focused:hover {
104
110
  --textfield-border-width: var(--border-width-m);
105
- --textfield-background-color: var(--color-background-main);
106
111
  --textfield-border-color: var(--color-border-action);
112
+ --textfield-background-color: var(--color-background-main);
107
113
  }
108
114
  .FieldControl_error,
109
115
  .FieldControl_error.FieldControl:hover,
@@ -112,9 +118,9 @@
112
118
  --textfield-border-color: var(--color-border-error);
113
119
  }
114
120
  .FieldControl_disabled {
121
+ --textfield-color: var(--color-content-secondary);
115
122
  --textfield-border-color: var(--color-border-disabled);
116
123
  --textfield-background-color: var(--color-background-disabled);
117
- --textfield-color: var(--color-content-secondary);
118
- pointer-events: none;
119
124
  cursor: default;
125
+ pointer-events: none;
120
126
  }
@@ -48,22 +48,22 @@
48
48
  .FieldLabel_size_s {
49
49
  --field-label-font: var(--typography-text-s-font);
50
50
  --field-label-scaled: var(--typography-text-3xs-font);
51
- --field-label-translate_y: -9px;
51
+ --field-label-translate_y: -8px;
52
52
  --field-label-top: 14px;
53
53
  }
54
54
 
55
55
  .FieldLabel_size_m {
56
56
  --field-label-font: var(--typography-text-m-font);
57
- --field-label-scaled: var(--typography-text-s-font);
58
- --field-label-translate_y: -10px;
59
- --field-label-top: 15px;
57
+ --field-label-scaled: var(--typography-text-xs-font);
58
+ --field-label-translate_y: -8px;
59
+ --field-label-top: 16px;
60
60
  }
61
61
 
62
62
  .FieldLabel_size_l {
63
63
  --field-label-font: var(--typography-text-l-font);
64
64
  --field-label-scaled: var(--typography-text-s-font);
65
- --field-label-translate_y: -9px;
66
- --field-label-top: 17px;
65
+ --field-label-translate_y: -10px;
66
+ --field-label-top: 18px;
67
67
  }
68
68
 
69
69
  .FieldLabel_disabled {
@@ -4,7 +4,7 @@
4
4
  margin: 0;
5
5
  padding: 0;
6
6
  pointer-events: none;
7
- border-radius: var(--border-radius-xs);
7
+ border-radius: var(--textfield-border-radius);
8
8
  border: var(--textfield-border-width) solid var(--textfield-border-color);
9
9
  transition: border var(--transition-default);
10
10
  }
@@ -1,130 +1,70 @@
1
- /* stylelint-disable */
2
- .FilePicker {
3
- --textfield-color: var(--color-content-tertiary);
4
- --textfield-background-color: var(--color-background-primary);
5
- --textfield-border-width: var(--border-width-s);
6
- --textfield-border-color: var(--color-border-main);
7
- font: var(--textfield-input-font);
8
- display: inline-flex;
9
- vertical-align: top;
10
- flex-direction: column;
11
- }
12
1
  .FilePicker-Body {
13
- position: relative;
14
2
  display: flex;
15
- -moz-column-gap: var(--textfield-input-gap);
16
- column-gap: var(--textfield-input-gap);
3
+ cursor: pointer;
4
+ position: relative;
17
5
  align-items: center;
18
6
  box-sizing: border-box;
7
+ color: var(--textfield-color);
19
8
  padding: 0 var(--textfield-gutter-x);
9
+ -moz-column-gap: var(--textfield-input-gap);
10
+ column-gap: var(--textfield-input-gap);
11
+ border-radius: var(--textfield-border-radius);
20
12
  background-color: var(--textfield-background-color);
21
13
  transition: background-color var(--transition-slow);
22
- color: var(--textfield-color);
23
- border-radius: var(--border-radius-xs);
24
- cursor: pointer;
25
14
  }
26
- .FilePicker-FieldContainer {
15
+ .FilePicker-FieldContainer {
16
+ overflow: hidden;
27
17
  inline-size: 100%;
28
18
  min-inline-size: 0;
29
19
  position: relative;
30
- overflow: hidden;
31
20
  }
32
- .FilePicker-FileName,
21
+ .FilePicker-FileName,
33
22
  .FilePicker-Placeholder {
34
- text-overflow: ellipsis;
35
- white-space: nowrap;
36
- overflow: hidden;
23
+ padding: 0;
37
24
  border: none;
38
- outline: none;
39
- position: relative;
40
25
  display: flex;
41
- align-items: center;
26
+ outline: none;
27
+ overflow: hidden;
42
28
  inline-size: 100%;
43
- padding: 0;
44
29
  background: none;
30
+ position: relative;
31
+ align-items: center;
32
+ white-space: nowrap;
45
33
  box-sizing: border-box;
46
- color: var(--textfield-color);
34
+ text-overflow: ellipsis;
47
35
  block-size: var(--textfield-input-height);
48
36
  }
49
- .FilePicker-Input {
37
+ .FilePicker-Placeholder {
38
+ color: var(--textfield-placeholder-color);
39
+ }
40
+ .FilePicker-Input {
41
+ opacity: 0;
42
+ inline-size: 100%;
50
43
  inset-block-end: 0;
51
- inset-inline-start: 0;
52
44
  position: absolute;
53
- opacity: 0;
54
45
  pointer-events: none;
55
- inline-size: 100%;
46
+ inset-inline-start: 0;
56
47
  }
57
- .FilePicker-Input:focus + .FilePicker-Placeholder {
48
+ .FilePicker-Input:focus + .FilePicker-Placeholder {
58
49
  opacity: 1;
59
50
  }
60
- .FilePicker_size_2xs {
61
- --textfield-gutter-x: 12px;
62
- --textfield-input-height: 32px;
63
- --textfield-input-font: var(--typography-text-2xs-font);
64
- --textfield-input-padding: 8px 0 8px;
65
- --textfield-input-gap: var(--spacing-2xs);
66
- }
67
- .FilePicker_size_xs {
68
- --textfield-gutter-x: 12px;
69
- --textfield-input-height: 40px;
70
- --textfield-input-font: var(--typography-text-xs-font);
71
- --textfield-input-padding: 19px 0 4px;
72
- --textfield-input-gap: var(--spacing-2xs);
73
- }
74
- .FilePicker_size_s {
75
- --textfield-gutter-x: 16px;
76
- --textfield-input-height: 48px;
77
- --textfield-input-font: var(--typography-text-s-font);
78
- --textfield-input-padding: 21px 0 6px;
79
- --textfield-input-gap: var(--spacing-xs);
80
- }
81
- .FilePicker_size_m {
82
- --textfield-gutter-x: 20px;
83
- --textfield-input-height: 56px;
84
- --textfield-input-font: var(--typography-text-m-font);
85
- --textfield-input-padding: 24px 0 6px;
86
- --textfield-input-gap: var(--spacing-xs);
87
- }
88
- .FilePicker_size_l {
89
- --textfield-gutter-x: 24px;
90
- --textfield-input-height: 64px;
91
- --textfield-input-font: var(--typography-text-l-font);
92
- --textfield-input-padding: 26px 0 6px;
93
- --textfield-input-gap: var(--spacing-s);
94
- }
95
- .FilePicker_fullWidth {
96
- inline-size: 100%;
51
+ .FilePicker-ClearButton {
52
+ visibility: hidden;
53
+ transition: visibility var(--transition-default);
97
54
  }
98
- .FilePicker_hasValue {
99
- --textfield-color: var(--color-content-primary);
55
+ .FilePicker-ClearButton_visibility {
56
+ visibility: visible;
57
+ }
58
+ .FilePicker-RenderRight {
59
+ display: flex;
60
+ gap: var(--spacing-2xs);
100
61
  }
101
- .FilePicker_hasLabel .FilePicker-Placeholder {
62
+
63
+ .FieldControl_hasLabel .FilePicker-Placeholder {
102
64
  opacity: 0;
103
65
  }
104
- .FilePicker_hasLabel .FilePicker-FileName,
105
- .FilePicker_hasLabel .FilePicker-Placeholder {
66
+
67
+ .FieldControl_hasLabel .FilePicker-FileName,
68
+ .FieldControl_hasLabel .FilePicker-Placeholder {
106
69
  padding: var(--textfield-input-padding);
107
- font: var(--textfield-input-font);
108
70
  }
109
- .FilePicker:hover {
110
- --textfield-border-color: var(--color-border-main-hover);
111
- }
112
- .FilePicker_focused,
113
- .FilePicker_focused:hover {
114
- --textfield-border-width: var(--border-width-m);
115
- --textfield-background-color: var(--color-background-main);
116
- --textfield-border-color: var(--color-border-action);
117
- }
118
- .FilePicker_error,
119
- .FilePicker_error.FilePicker:hover,
120
- .FilePicker_error.FilePicker_focused,
121
- .FilePicker_error.FilePicker_focused:hover {
122
- --textfield-border-color: var(--color-border-error);
123
- }
124
- .FilePicker_disabled {
125
- --textfield-border-color: var(--color-border-disabled);
126
- --textfield-background-color: var(--color-background-disabled);
127
- --textfield-color: var(--color-content-secondary);
128
- pointer-events: none;
129
- cursor: default;
130
- }
@@ -1,4 +1,72 @@
1
1
  import './FilePicker.css';
2
2
  import React from 'react';
3
3
  export declare const cnFilePicker: import("@bem-react/classname").ClassNameFormatter;
4
- export declare const FilePicker: React.ForwardRefExoticComponent<import("./types").FilePickerBaseProps & Omit<React.HTMLAttributes<HTMLDivElement>, keyof import("./types").FilePickerBaseProps> & React.RefAttributes<HTMLDivElement>>;
4
+ export declare const FilePicker: React.ForwardRefExoticComponent<{
5
+ id?: string | undefined;
6
+ name?: string | undefined;
7
+ size?: "s" | "m" | "l" | "2xs" | "xs" | undefined;
8
+ label?: string | undefined;
9
+ accept?: string | undefined;
10
+ placeholder?: string | undefined;
11
+ onChange?: React.ChangeEventHandler<HTMLInputElement> | undefined;
12
+ multiple?: boolean | undefined;
13
+ fileList?: File[] | undefined;
14
+ fullWidth?: boolean | undefined;
15
+ autoFocus?: boolean | undefined;
16
+ inputProps?: (Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & {
17
+ ref?: ((instance: HTMLInputElement | null) => void) | React.RefObject<HTMLInputElement> | null | undefined;
18
+ } & {
19
+ 'data-testid'?: string | undefined;
20
+ }) | undefined;
21
+ disableTruncate?: boolean | undefined;
22
+ required?: boolean | undefined;
23
+ renderLeft?: string | number | React.FC<React.SVGProps<SVGSVGElement> & {
24
+ color?: string | undefined;
25
+ ref?: React.Ref<SVGSVGElement> | undefined;
26
+ } & {
27
+ size?: import("@ozen-ui/icons").IconSize | undefined;
28
+ }> | React.ReactElement<React.SVGProps<SVGSVGElement> & {
29
+ color?: string | undefined;
30
+ ref?: React.Ref<SVGSVGElement> | undefined;
31
+ } & {
32
+ size?: import("@ozen-ui/icons").IconSize | undefined;
33
+ }, string | React.JSXElementConstructor<any>> | (() => React.ReactElement<React.SVGProps<SVGSVGElement> & {
34
+ color?: string | undefined;
35
+ ref?: React.Ref<SVGSVGElement> | undefined;
36
+ } & {
37
+ size?: import("@ozen-ui/icons").IconSize | undefined;
38
+ }, string | React.JSXElementConstructor<any>>) | undefined;
39
+ renderRight?: string | number | React.FC<React.SVGProps<SVGSVGElement> & {
40
+ color?: string | undefined;
41
+ ref?: React.Ref<SVGSVGElement> | undefined;
42
+ } & {
43
+ size?: import("@ozen-ui/icons").IconSize | undefined;
44
+ }> | React.ReactElement<React.SVGProps<SVGSVGElement> & {
45
+ color?: string | undefined;
46
+ ref?: React.Ref<SVGSVGElement> | undefined;
47
+ } & {
48
+ size?: import("@ozen-ui/icons").IconSize | undefined;
49
+ }, string | React.JSXElementConstructor<any>> | (() => React.ReactElement<React.SVGProps<SVGSVGElement> & {
50
+ color?: string | undefined;
51
+ ref?: React.Ref<SVGSVGElement> | undefined;
52
+ } & {
53
+ size?: import("@ozen-ui/icons").IconSize | undefined;
54
+ }, string | React.JSXElementConstructor<any>>) | undefined;
55
+ hint?: string | null | undefined;
56
+ error?: boolean | undefined;
57
+ disabled?: boolean | undefined;
58
+ labelProps?: import("../FieldLabel").FieldLabelProps | undefined;
59
+ renderValue?: import("./types").FilePickerRenderValue | undefined;
60
+ clearText?: string | undefined;
61
+ onClear?: ((e: React.KeyboardEvent<HTMLInputElement> | React.MouseEvent<HTMLButtonElement, globalThis.MouseEvent>, payload: {
62
+ name?: string | undefined;
63
+ }) => void) | undefined;
64
+ className?: string | undefined;
65
+ 'data-testid'?: string | undefined;
66
+ } & {
67
+ labelRef?: ((instance: HTMLSpanElement | null) => void) | React.RefObject<HTMLSpanElement> | null | undefined;
68
+ inputRef?: React.Ref<HTMLInputElement> | undefined;
69
+ } & Omit<React.HTMLAttributes<HTMLDivElement>, "name" | "label" | "className" | "id" | "onChange" | "autoFocus" | "disabled" | "accept" | "multiple" | "placeholder" | "required" | "size" | "error" | "fullWidth" | "labelProps" | "data-testid" | "hint" | "renderLeft" | "renderRight" | "inputProps" | "clearText" | "onClear" | "fileList" | "disableTruncate" | "renderValue" | keyof {
70
+ labelRef?: ((instance: HTMLSpanElement | null) => void) | React.RefObject<HTMLSpanElement> | null | undefined;
71
+ inputRef?: React.Ref<HTMLInputElement> | undefined;
72
+ }> & React.RefAttributes<HTMLDivElement>>;
@@ -5,26 +5,33 @@ var tslib_1 = require("tslib");
5
5
  require("./FilePicker.css");
6
6
  var react_1 = tslib_1.__importStar(require("react"));
7
7
  var icons_1 = require("@ozen-ui/icons");
8
+ var logger_1 = require("@ozen-ui/logger");
8
9
  var useMultiRef_1 = require("../../hooks/useMultiRef");
9
10
  var useThemeProps_1 = require("../../hooks/useThemeProps");
10
11
  var classname_1 = require("../../utils/classname");
11
12
  var isKey_1 = require("../../utils/isKey");
13
+ var FieldControl_1 = require("../FieldControl");
12
14
  var FieldHint_1 = require("../FieldHint");
13
15
  var FieldIcon_1 = require("../FieldIcon");
14
16
  var FieldLabel_1 = require("../FieldLabel");
15
17
  var Fieldset_1 = require("../Fieldset");
16
- var IconButton_1 = require("../IconButton");
18
+ var IconButtonNext_1 = require("../IconButtonNext");
17
19
  var constants_1 = require("./constants");
18
20
  exports.cnFilePicker = (0, classname_1.cn)('FilePicker');
19
21
  exports.FilePicker = (0, react_1.forwardRef)(function (inProps, ref) {
20
22
  var _a = (0, useThemeProps_1.useThemeProps)({
21
23
  props: inProps,
22
24
  name: 'FilePicker',
23
- }), _b = _a.size, size = _b === void 0 ? constants_1.FILE_PICKER_DEFAULT_SIZE : _b, _c = _a.disabled, disabled = _c === void 0 ? constants_1.FILE_PICKER_DEFAULT_DISABLED : _c, _d = _a.required, required = _d === void 0 ? constants_1.FILE_PICKER_DEFAULT_REQUIRED : _d, _e = _a.fullWidth, fullWidth = _e === void 0 ? constants_1.FILE_PICKER_DEFAULT_FULL_WIDTH : _e, _f = _a.disableTruncate, disableTruncate = _f === void 0 ? constants_1.FILE_PICKER_DEFAULT_DISABLE_TRUNCATE : _f, _g = _a.multiple, multiple = _g === void 0 ? constants_1.FILE_PICKER_DEFAULT_MULTIPLE : _g, placeholder = _a.placeholder, clearText = _a.clearText, _h = _a.renderRight, renderRight = _h === void 0 ? icons_1.AttachmentIcon : _h, renderValueProp = _a.renderValue, onChangeProp = _a.onChange, onClearProp = _a.onClear, inputRefProp = _a.inputRef, fileList = _a.fileList, accept = _a.accept, id = _a.id, name = _a.name, label = _a.label, autoFocus = _a.autoFocus, error = _a.error, hint = _a.hint, renderLeft = _a.renderLeft, labelProps = _a.labelProps, inputProps = _a.inputProps, labelRef = _a.labelRef, className = _a.className, other = tslib_1.__rest(_a, ["size", "disabled", "required", "fullWidth", "disableTruncate", "multiple", "placeholder", "clearText", "renderRight", "renderValue", "onChange", "onClear", "inputRef", "fileList", "accept", "id", "name", "label", "autoFocus", "error", "hint", "renderLeft", "labelProps", "inputProps", "labelRef", "className"]);
24
- var fieldRef = (0, react_1.useRef)(null);
25
- var inputRef = (0, react_1.useRef)(null);
26
- var clearRef = (0, react_1.useRef)(null);
25
+ }), _b = _a.size, size = _b === void 0 ? constants_1.FILE_PICKER_DEFAULT_SIZE : _b, _c = _a.disabled, disabled = _c === void 0 ? constants_1.FILE_PICKER_DEFAULT_DISABLED : _c, _d = _a.required, required = _d === void 0 ? constants_1.FILE_PICKER_DEFAULT_REQUIRED : _d, _e = _a.fullWidth, fullWidth = _e === void 0 ? constants_1.FILE_PICKER_DEFAULT_FULL_WIDTH : _e, _f = _a.disableTruncate, disableTruncate = _f === void 0 ? constants_1.FILE_PICKER_DEFAULT_DISABLE_TRUNCATE : _f, _g = _a.multiple, multiple = _g === void 0 ? constants_1.FILE_PICKER_DEFAULT_MULTIPLE : _g, placeholder = _a.placeholder, clearText = _a.clearText, _h = _a.renderRight, renderRight = _h === void 0 ? icons_1.AttachmentIcon : _h, renderValueProp = _a.renderValue, onChangeProp = _a.onChange, onClearProp = _a.onClear, inputRef = _a.inputRef, fileList = _a.fileList, accept = _a.accept, id = _a.id, name = _a.name, label = _a.label, autoFocus = _a.autoFocus, error = _a.error, hint = _a.hint, renderLeft = _a.renderLeft, labelProps = _a.labelProps, inputProps = _a.inputProps, labelRef = _a.labelRef, className = _a.className, other = tslib_1.__rest(_a, ["size", "disabled", "required", "fullWidth", "disableTruncate", "multiple", "placeholder", "clearText", "renderRight", "renderValue", "onChange", "onClear", "inputRef", "fileList", "accept", "id", "name", "label", "autoFocus", "error", "hint", "renderLeft", "labelProps", "inputProps", "labelRef", "className"]);
26
+ if (process.env.NODE_ENV !== 'production' && labelRef) {
27
+ (0, logger_1.deprecate)('Свойство «labelRef» устарело. Для замены используйте «labelProps.ref».');
28
+ }
29
+ if (process.env.NODE_ENV !== 'production' && inputRef) {
30
+ (0, logger_1.deprecate)('Свойство «inputRef» устарело. Для замены используйте «inputProps.ref».');
31
+ }
32
+ var inputInnerRef = (0, react_1.useRef)(null);
27
33
  var _j = tslib_1.__read((0, react_1.useState)(false), 2), focused = _j[0], setFocused = _j[1];
34
+ var hasFiles = !!(fileList === null || fileList === void 0 ? void 0 : fileList.length);
28
35
  var handleFocus = function (e) {
29
36
  var _a;
30
37
  (_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onFocus) === null || _a === void 0 ? void 0 : _a.call(inputProps, e);
@@ -37,8 +44,8 @@ exports.FilePicker = (0, react_1.forwardRef)(function (inProps, ref) {
37
44
  };
38
45
  var onChange = function (e) {
39
46
  onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(e);
40
- if (inputRef.current) {
41
- inputRef.current.value = '';
47
+ if (inputInnerRef.current) {
48
+ inputInnerRef.current.value = '';
42
49
  }
43
50
  };
44
51
  var onClear = function (e) {
@@ -55,25 +62,19 @@ exports.FilePicker = (0, react_1.forwardRef)(function (inProps, ref) {
55
62
  ? renderValueProp(file)
56
63
  : (0, constants_1.FILE_PICKER_DEFAULT_VALUE_RENDERER)(file, disableTruncate);
57
64
  };
58
- return (react_1.default.createElement("div", tslib_1.__assign({}, other, { className: (0, exports.cnFilePicker)('', {
59
- hasLabel: !!label,
60
- hasValue: !!(fileList === null || fileList === void 0 ? void 0 : fileList.length),
61
- size: size,
62
- error: error,
63
- focused: focused,
64
- disabled: disabled,
65
- required: required,
66
- fullWidth: fullWidth,
67
- }, [className]), ref: (0, useMultiRef_1.useMultiRef)([fieldRef, ref]) }),
65
+ return (react_1.default.createElement(FieldControl_1.FieldControl, tslib_1.__assign({ size: size, error: error, focused: focused, disabled: disabled, required: required, fullWidth: fullWidth, filled: hasFiles }, other, { className: (0, exports.cnFilePicker)('', [className]), ref: ref }),
68
66
  react_1.default.createElement("label", { className: (0, exports.cnFilePicker)('Body') },
69
- react_1.default.createElement(FieldIcon_1.FieldIcon, { className: (0, exports.cnFilePicker)('RenderLeft'), icon: renderLeft, size: size }),
67
+ react_1.default.createElement(FieldIcon_1.FieldIcon, { icon: renderLeft }),
70
68
  react_1.default.createElement("div", { className: (0, exports.cnFilePicker)('FieldContainer') },
71
- label && (react_1.default.createElement(FieldLabel_1.FieldLabel, tslib_1.__assign({ filled: !!(fileList === null || fileList === void 0 ? void 0 : fileList.length), focused: focused, required: required, disabled: disabled, size: size }, labelProps, { className: (0, exports.cnFilePicker)('Label', [labelProps === null || labelProps === void 0 ? void 0 : labelProps.className]), ref: labelRef }), label)),
72
- react_1.default.createElement("input", tslib_1.__assign({ id: id, name: name, autoFocus: autoFocus, onFocus: handleFocus, onBlur: handleBlur, className: (0, exports.cnFilePicker)('Input'), required: required, disabled: disabled, accept: accept, multiple: multiple }, inputProps, { onChange: onChange, onKeyDown: onKeyDown, ref: (0, useMultiRef_1.useMultiRef)([inputRef, inputRefProp]), type: "file" })),
73
- (fileList === null || fileList === void 0 ? void 0 : fileList.length) ? (react_1.default.createElement("span", { className: (0, exports.cnFilePicker)('FileName') }, renderValue(fileList, disableTruncate))) : (react_1.default.createElement("span", { "aria-placeholder": placeholder, className: (0, exports.cnFilePicker)('Placeholder') }, placeholder))),
74
- !!(fileList === null || fileList === void 0 ? void 0 : fileList.length) && onClearProp && (react_1.default.createElement(IconButton_1.IconButton, { tabIndex: -1, variant: "function", "aria-label": clearText, ref: clearRef, onClick: onClear, size: size, icon: icons_1.CrossIcon })),
75
- react_1.default.createElement(FieldIcon_1.FieldIcon, { className: (0, exports.cnFilePicker)('RenderRight'), icon: renderRight, size: size }),
76
- react_1.default.createElement(Fieldset_1.Fieldset, { className: (0, exports.cnFilePicker)('Fieldset') })),
77
- react_1.default.createElement(FieldHint_1.FieldHint, { size: size, error: error, disabled: disabled }, hint)));
69
+ react_1.default.createElement(FieldLabel_1.FieldLabel, tslib_1.__assign({}, labelProps, { ref: labelRef || (labelProps === null || labelProps === void 0 ? void 0 : labelProps.ref), className: (0, exports.cnFilePicker)('Label', [labelProps === null || labelProps === void 0 ? void 0 : labelProps.className]) }), label),
70
+ react_1.default.createElement("input", tslib_1.__assign({ id: id, name: name, accept: accept, multiple: multiple, onBlur: handleBlur, required: required, disabled: disabled, autoFocus: autoFocus, onFocus: handleFocus, className: (0, exports.cnFilePicker)('Input') }, inputProps, { type: "file", onChange: onChange, onKeyDown: onKeyDown, ref: (0, useMultiRef_1.useMultiRef)([inputRef || (inputProps === null || inputProps === void 0 ? void 0 : inputProps.ref), inputInnerRef]) })),
71
+ hasFiles ? (react_1.default.createElement("span", { className: (0, exports.cnFilePicker)('FileName') }, renderValue(fileList, disableTruncate))) : (react_1.default.createElement("span", { "aria-placeholder": placeholder, className: (0, exports.cnFilePicker)('Placeholder') }, placeholder))),
72
+ react_1.default.createElement("div", { className: (0, exports.cnFilePicker)('RenderRight') },
73
+ onClearProp && (react_1.default.createElement(IconButtonNext_1.IconButton, { size: size, tabIndex: -1, icon: icons_1.CrossIcon, onClick: onClear, variant: "function", "aria-label": clearText, className: (0, exports.cnFilePicker)('ClearButton', {
74
+ visibility: hasFiles,
75
+ }) })),
76
+ react_1.default.createElement(FieldIcon_1.FieldIcon, { icon: renderRight })),
77
+ react_1.default.createElement(Fieldset_1.Fieldset, null)),
78
+ react_1.default.createElement(FieldHint_1.FieldHint, null, hint)));
78
79
  });
79
80
  exports.FilePicker.displayName = 'FilePicker';
@@ -1,11 +1,23 @@
1
- import type { Ref, HTMLAttributes, InputHTMLAttributes, MouseEvent, KeyboardEvent, ChangeEventHandler, ReactNode } from 'react';
1
+ import type { Ref, HTMLAttributes, MouseEvent, KeyboardEvent, ChangeEventHandler, ReactNode, ComponentPropsWithRef } from 'react';
2
2
  import type { ExtendableProps } from '../../types/ExtendableProps';
3
3
  import type { FormElementSizeVariant } from '../../types/FormElementSizeVariant';
4
4
  import type { FieldIconProps } from '../FieldIcon';
5
5
  import type { FieldLabelProps } from '../FieldLabel';
6
6
  export type FilePickerSizeVariant = FormElementSizeVariant;
7
7
  export type FilePickerRenderValue = (value: File[]) => ReactNode | null;
8
- type InputElement = InputHTMLAttributes<HTMLInputElement>;
8
+ type InputElement = ComponentPropsWithRef<'input'>;
9
+ type FilePickerPropsDeprecated = {
10
+ /**
11
+ * Ссылка на FieldLabel
12
+ * @deprecated Используйте labelProps.ref
13
+ * */
14
+ labelRef?: FieldLabelProps['ref'];
15
+ /**
16
+ * Ссылка на элемент input
17
+ * @deprecated Используйте inputProps.ref
18
+ * */
19
+ inputRef?: Ref<HTMLInputElement>;
20
+ };
9
21
  export type FilePickerBaseProps = {
10
22
  /** Атрибут id для элемента input */
11
23
  id?: string;
@@ -33,8 +45,6 @@ export type FilePickerBaseProps = {
33
45
  inputProps?: InputElement & {
34
46
  'data-testid'?: string;
35
47
  };
36
- /** Ссылка на элемент input */
37
- inputRef?: Ref<HTMLInputElement>;
38
48
  /** Если {true} отключает сокращение длинного названия файла */
39
49
  disableTruncate?: boolean;
40
50
  /** Если {true} делает элемент обязательным к заполнению */
@@ -51,8 +61,6 @@ export type FilePickerBaseProps = {
51
61
  disabled?: boolean;
52
62
  /** Свойства FieldLabel */
53
63
  labelProps?: FieldLabelProps;
54
- /** Ссылка на FieldLabel */
55
- labelRef?: FieldLabelProps['ref'];
56
64
  /** Функция */
57
65
  renderValue?: FilePickerRenderValue;
58
66
  /** Текст для кнопки очистки поля */
@@ -63,7 +71,8 @@ export type FilePickerBaseProps = {
63
71
  }) => void;
64
72
  /** Дополнительные css-классы */
65
73
  className?: string;
74
+ /** data-атрибут для тестирования */
66
75
  'data-testid'?: string;
67
- };
76
+ } & FilePickerPropsDeprecated;
68
77
  export type FilePickerProps = ExtendableProps<HTMLAttributes<HTMLDivElement>, FilePickerBaseProps>;
69
78
  export {};
@@ -9,7 +9,7 @@
9
9
  background-color: var(--textfield-background-color);
10
10
  transition: background-color var(--transition-slow);
11
11
  color: var(--textfield-color);
12
- border-radius: var(--border-radius-xs);
12
+ border-radius: var(--textfield-border-radius);
13
13
  }
14
14
  .Input-FieldContainer {
15
15
  inline-size: 100%;
@@ -29,7 +29,7 @@
29
29
  }
30
30
  .Input-Field::placeholder {
31
31
  opacity: 1;
32
- color: var(--color-content-tertiary);
32
+ color: var(--textfield-placeholder-color);
33
33
  }
34
34
  .Input-Field:-webkit-autofill,
35
35
  .Input-Field:-webkit-autofill:hover,
@@ -41,7 +41,7 @@
41
41
  color: var(--textfield-color);
42
42
  -moz-column-gap: var(--textfield-input-gap);
43
43
  column-gap: var(--textfield-input-gap);
44
- border-radius: var(--border-radius-xs);
44
+ border-radius: var(--textfield-border-radius);
45
45
  padding: var(--input-number-padding);
46
46
  background-color: var(--textfield-background-color);
47
47
  transition: background-color var(--transition-slow);
@@ -70,7 +70,7 @@
70
70
 
71
71
  .InputNumber-Field::placeholder {
72
72
  opacity: 1;
73
- color: var(--color-content-tertiary);
73
+ color: var(--textfield-placeholder-color);
74
74
  }
75
75
 
76
76
  .InputNumber-Field:-webkit-autofill,
@@ -23,7 +23,7 @@
23
23
  transition: background-color var(--transition-slow);
24
24
  padding: 0 var(--textfield-gutter-x);
25
25
  color: var(--textfield-color);
26
- border-radius: var(--border-radius-xs);
26
+ border-radius: var(--textfield-border-radius);
27
27
  cursor: pointer;
28
28
  outline: none;
29
29
  }
@@ -54,7 +54,7 @@
54
54
  }
55
55
 
56
56
  .Select-Field_asPlaceholder {
57
- color: var(--color-content-tertiary);
57
+ color: var(--textfield-placeholder-color);
58
58
  }
59
59
 
60
60
  .Select_multiline .Select-FieldContainer {
@@ -23,7 +23,7 @@
23
23
  background-color: var(--textfield-background-color);
24
24
  transition: background-color var(--transition-slow);
25
25
  color: var(--textfield-color);
26
- border-radius: var(--border-radius-xs);
26
+ border-radius: var(--textfield-border-radius);
27
27
  min-block-size: inherit;
28
28
  block-size: inherit;
29
29
  padding: var(--textfield-input-padding);
@@ -78,7 +78,7 @@
78
78
 
79
79
  .Textarea-Field::placeholder {
80
80
  opacity: 1;
81
- color: var(--color-content-tertiary);
81
+ color: var(--textfield-placeholder-color);
82
82
  }
83
83
 
84
84
  .Textarea-Counter {
@@ -1,22 +1,24 @@
1
1
  /* stylelint-disable */
2
2
  .FieldControl {
3
3
  --textfield-color: var(--color-content-primary);
4
- --textfield-background-color: var(--color-background-primary);
5
4
  --textfield-border-width: var(--border-width-s);
6
5
  --textfield-border-color: var(--color-border-main);
6
+ --textfield-placeholder-color: var(--color-content-tertiary);
7
+ --textfield-background-color: var(--color-background-primary);
7
8
  cursor: text;
8
- display: inline-flex;
9
9
  vertical-align: top;
10
+ display: inline-flex;
10
11
  flex-direction: column;
11
12
  }
12
13
  .FieldControl > * {
13
14
  cursor: text;
14
15
  }
15
16
  .FieldControl_size_2xs {
16
- --textfield-gutter-x: 12px;
17
- --textfield-input-height: 32px;
18
17
  --textfield-input-padding: 8px 0;
19
18
  --textfield-input-gap: var(--spacing-2xs);
19
+ --textfield-gutter-x: var(--control-padding-xs);
20
+ --textfield-border-radius: var(--border-radius-xs);
21
+ --textfield-input-height: var(--control-height-2xs);
20
22
 
21
23
  font: var(--typography-text-2xs-font);
22
24
 
@@ -25,10 +27,11 @@
25
27
  text-transform: var(--typography-text-2xs-text_transform, none);
26
28
  }
27
29
  .FieldControl_size_xs {
28
- --textfield-gutter-x: 12px;
29
- --textfield-input-height: 40px;
30
30
  --textfield-input-padding: 12px 0;
31
31
  --textfield-input-gap: var(--spacing-2xs);
32
+ --textfield-gutter-x: var(--control-padding-xs);
33
+ --textfield-border-radius: var(--border-radius-xs);
34
+ --textfield-input-height: var(--control-height-xs);
32
35
 
33
36
  font: var(--typography-text-xs-font);
34
37
 
@@ -37,10 +40,11 @@
37
40
  text-transform: var(--typography-text-xs-text_transform, none);
38
41
  }
39
42
  .FieldControl_size_s {
40
- --textfield-gutter-x: 16px;
41
- --textfield-input-height: 48px;
42
43
  --textfield-input-padding: 14px 0;
43
44
  --textfield-input-gap: var(--spacing-xs);
45
+ --textfield-gutter-x: var(--control-padding-s);
46
+ --textfield-border-radius: var(--border-radius-xs);
47
+ --textfield-input-height: var(--control-height-s);
44
48
 
45
49
  font: var(--typography-text-s-font);
46
50
 
@@ -49,10 +53,11 @@
49
53
  text-transform: var(--typography-text-s-text_transform, none);
50
54
  }
51
55
  .FieldControl_size_m {
52
- --textfield-gutter-x: 20px;
53
- --textfield-input-height: 56px;
54
56
  --textfield-input-padding: 16px 0;
55
57
  --textfield-input-gap: var(--spacing-xs);
58
+ --textfield-gutter-x: var(--control-padding-m);
59
+ --textfield-border-radius: var(--border-radius-xs);
60
+ --textfield-input-height: var(--control-height-m);
56
61
 
57
62
  font: var(--typography-text-m-font);
58
63
 
@@ -61,10 +66,11 @@
61
66
  text-transform: var(--typography-text-m-text_transform, none);
62
67
  }
63
68
  .FieldControl_size_l {
64
- --textfield-gutter-x: 24px;
65
- --textfield-input-height: 64px;
66
69
  --textfield-input-padding: 18px 0;
67
70
  --textfield-input-gap: var(--spacing-s);
71
+ --textfield-gutter-x: var(--control-padding-l);
72
+ --textfield-border-radius: var(--border-radius-xs);
73
+ --textfield-input-height: var(--control-height-l);
68
74
 
69
75
  font: var(--typography-text-l-font);
70
76
 
@@ -76,16 +82,16 @@
76
82
  --textfield-input-padding: 8px 0 8px;
77
83
  }
78
84
  .FieldControl_hasLabel.FieldControl_size_xs {
79
- --textfield-input-padding: 19px 0 4px;
85
+ --textfield-input-padding: 20px 0 4px;
80
86
  }
81
87
  .FieldControl_hasLabel.FieldControl_size_s {
82
- --textfield-input-padding: 21px 0 6px;
88
+ --textfield-input-padding: 22px 0 6px;
83
89
  }
84
90
  .FieldControl_hasLabel.FieldControl_size_m {
85
- --textfield-input-padding: 24px 0 6px;
91
+ --textfield-input-padding: 24px 0 8px;
86
92
  }
87
93
  .FieldControl_hasLabel.FieldControl_size_l {
88
- --textfield-input-padding: 26px 0 6px;
94
+ --textfield-input-padding: 28px 0 8px;
89
95
  }
90
96
  .FieldControl_hasLabel .FieldInput::placeholder {
91
97
  opacity: 0;
@@ -102,8 +108,8 @@
102
108
  .FieldControl_focused,
103
109
  .FieldControl_focused:hover {
104
110
  --textfield-border-width: var(--border-width-m);
105
- --textfield-background-color: var(--color-background-main);
106
111
  --textfield-border-color: var(--color-border-action);
112
+ --textfield-background-color: var(--color-background-main);
107
113
  }
108
114
  .FieldControl_error,
109
115
  .FieldControl_error.FieldControl:hover,
@@ -112,9 +118,9 @@
112
118
  --textfield-border-color: var(--color-border-error);
113
119
  }
114
120
  .FieldControl_disabled {
121
+ --textfield-color: var(--color-content-secondary);
115
122
  --textfield-border-color: var(--color-border-disabled);
116
123
  --textfield-background-color: var(--color-background-disabled);
117
- --textfield-color: var(--color-content-secondary);
118
- pointer-events: none;
119
124
  cursor: default;
125
+ pointer-events: none;
120
126
  }
@@ -48,22 +48,22 @@
48
48
  .FieldLabel_size_s {
49
49
  --field-label-font: var(--typography-text-s-font);
50
50
  --field-label-scaled: var(--typography-text-3xs-font);
51
- --field-label-translate_y: -9px;
51
+ --field-label-translate_y: -8px;
52
52
  --field-label-top: 14px;
53
53
  }
54
54
 
55
55
  .FieldLabel_size_m {
56
56
  --field-label-font: var(--typography-text-m-font);
57
- --field-label-scaled: var(--typography-text-s-font);
58
- --field-label-translate_y: -10px;
59
- --field-label-top: 15px;
57
+ --field-label-scaled: var(--typography-text-xs-font);
58
+ --field-label-translate_y: -8px;
59
+ --field-label-top: 16px;
60
60
  }
61
61
 
62
62
  .FieldLabel_size_l {
63
63
  --field-label-font: var(--typography-text-l-font);
64
64
  --field-label-scaled: var(--typography-text-s-font);
65
- --field-label-translate_y: -9px;
66
- --field-label-top: 17px;
65
+ --field-label-translate_y: -10px;
66
+ --field-label-top: 18px;
67
67
  }
68
68
 
69
69
  .FieldLabel_disabled {
@@ -4,7 +4,7 @@
4
4
  margin: 0;
5
5
  padding: 0;
6
6
  pointer-events: none;
7
- border-radius: var(--border-radius-xs);
7
+ border-radius: var(--textfield-border-radius);
8
8
  border: var(--textfield-border-width) solid var(--textfield-border-color);
9
9
  transition: border var(--transition-default);
10
10
  }
@@ -1,130 +1,70 @@
1
- /* stylelint-disable */
2
- .FilePicker {
3
- --textfield-color: var(--color-content-tertiary);
4
- --textfield-background-color: var(--color-background-primary);
5
- --textfield-border-width: var(--border-width-s);
6
- --textfield-border-color: var(--color-border-main);
7
- font: var(--textfield-input-font);
8
- display: inline-flex;
9
- vertical-align: top;
10
- flex-direction: column;
11
- }
12
1
  .FilePicker-Body {
13
- position: relative;
14
2
  display: flex;
15
- -moz-column-gap: var(--textfield-input-gap);
16
- column-gap: var(--textfield-input-gap);
3
+ cursor: pointer;
4
+ position: relative;
17
5
  align-items: center;
18
6
  box-sizing: border-box;
7
+ color: var(--textfield-color);
19
8
  padding: 0 var(--textfield-gutter-x);
9
+ -moz-column-gap: var(--textfield-input-gap);
10
+ column-gap: var(--textfield-input-gap);
11
+ border-radius: var(--textfield-border-radius);
20
12
  background-color: var(--textfield-background-color);
21
13
  transition: background-color var(--transition-slow);
22
- color: var(--textfield-color);
23
- border-radius: var(--border-radius-xs);
24
- cursor: pointer;
25
14
  }
26
- .FilePicker-FieldContainer {
15
+ .FilePicker-FieldContainer {
16
+ overflow: hidden;
27
17
  inline-size: 100%;
28
18
  min-inline-size: 0;
29
19
  position: relative;
30
- overflow: hidden;
31
20
  }
32
- .FilePicker-FileName,
21
+ .FilePicker-FileName,
33
22
  .FilePicker-Placeholder {
34
- text-overflow: ellipsis;
35
- white-space: nowrap;
36
- overflow: hidden;
23
+ padding: 0;
37
24
  border: none;
38
- outline: none;
39
- position: relative;
40
25
  display: flex;
41
- align-items: center;
26
+ outline: none;
27
+ overflow: hidden;
42
28
  inline-size: 100%;
43
- padding: 0;
44
29
  background: none;
30
+ position: relative;
31
+ align-items: center;
32
+ white-space: nowrap;
45
33
  box-sizing: border-box;
46
- color: var(--textfield-color);
34
+ text-overflow: ellipsis;
47
35
  block-size: var(--textfield-input-height);
48
36
  }
49
- .FilePicker-Input {
37
+ .FilePicker-Placeholder {
38
+ color: var(--textfield-placeholder-color);
39
+ }
40
+ .FilePicker-Input {
41
+ opacity: 0;
42
+ inline-size: 100%;
50
43
  inset-block-end: 0;
51
- inset-inline-start: 0;
52
44
  position: absolute;
53
- opacity: 0;
54
45
  pointer-events: none;
55
- inline-size: 100%;
46
+ inset-inline-start: 0;
56
47
  }
57
- .FilePicker-Input:focus + .FilePicker-Placeholder {
48
+ .FilePicker-Input:focus + .FilePicker-Placeholder {
58
49
  opacity: 1;
59
50
  }
60
- .FilePicker_size_2xs {
61
- --textfield-gutter-x: 12px;
62
- --textfield-input-height: 32px;
63
- --textfield-input-font: var(--typography-text-2xs-font);
64
- --textfield-input-padding: 8px 0 8px;
65
- --textfield-input-gap: var(--spacing-2xs);
66
- }
67
- .FilePicker_size_xs {
68
- --textfield-gutter-x: 12px;
69
- --textfield-input-height: 40px;
70
- --textfield-input-font: var(--typography-text-xs-font);
71
- --textfield-input-padding: 19px 0 4px;
72
- --textfield-input-gap: var(--spacing-2xs);
73
- }
74
- .FilePicker_size_s {
75
- --textfield-gutter-x: 16px;
76
- --textfield-input-height: 48px;
77
- --textfield-input-font: var(--typography-text-s-font);
78
- --textfield-input-padding: 21px 0 6px;
79
- --textfield-input-gap: var(--spacing-xs);
80
- }
81
- .FilePicker_size_m {
82
- --textfield-gutter-x: 20px;
83
- --textfield-input-height: 56px;
84
- --textfield-input-font: var(--typography-text-m-font);
85
- --textfield-input-padding: 24px 0 6px;
86
- --textfield-input-gap: var(--spacing-xs);
87
- }
88
- .FilePicker_size_l {
89
- --textfield-gutter-x: 24px;
90
- --textfield-input-height: 64px;
91
- --textfield-input-font: var(--typography-text-l-font);
92
- --textfield-input-padding: 26px 0 6px;
93
- --textfield-input-gap: var(--spacing-s);
94
- }
95
- .FilePicker_fullWidth {
96
- inline-size: 100%;
51
+ .FilePicker-ClearButton {
52
+ visibility: hidden;
53
+ transition: visibility var(--transition-default);
97
54
  }
98
- .FilePicker_hasValue {
99
- --textfield-color: var(--color-content-primary);
55
+ .FilePicker-ClearButton_visibility {
56
+ visibility: visible;
57
+ }
58
+ .FilePicker-RenderRight {
59
+ display: flex;
60
+ gap: var(--spacing-2xs);
100
61
  }
101
- .FilePicker_hasLabel .FilePicker-Placeholder {
62
+
63
+ .FieldControl_hasLabel .FilePicker-Placeholder {
102
64
  opacity: 0;
103
65
  }
104
- .FilePicker_hasLabel .FilePicker-FileName,
105
- .FilePicker_hasLabel .FilePicker-Placeholder {
66
+
67
+ .FieldControl_hasLabel .FilePicker-FileName,
68
+ .FieldControl_hasLabel .FilePicker-Placeholder {
106
69
  padding: var(--textfield-input-padding);
107
- font: var(--textfield-input-font);
108
70
  }
109
- .FilePicker:hover {
110
- --textfield-border-color: var(--color-border-main-hover);
111
- }
112
- .FilePicker_focused,
113
- .FilePicker_focused:hover {
114
- --textfield-border-width: var(--border-width-m);
115
- --textfield-background-color: var(--color-background-main);
116
- --textfield-border-color: var(--color-border-action);
117
- }
118
- .FilePicker_error,
119
- .FilePicker_error.FilePicker:hover,
120
- .FilePicker_error.FilePicker_focused,
121
- .FilePicker_error.FilePicker_focused:hover {
122
- --textfield-border-color: var(--color-border-error);
123
- }
124
- .FilePicker_disabled {
125
- --textfield-border-color: var(--color-border-disabled);
126
- --textfield-background-color: var(--color-background-disabled);
127
- --textfield-color: var(--color-content-secondary);
128
- pointer-events: none;
129
- cursor: default;
130
- }
@@ -1,4 +1,72 @@
1
1
  import './FilePicker.css';
2
2
  import React from 'react';
3
3
  export declare const cnFilePicker: import("@bem-react/classname").ClassNameFormatter;
4
- export declare const FilePicker: React.ForwardRefExoticComponent<import("./types").FilePickerBaseProps & Omit<React.HTMLAttributes<HTMLDivElement>, keyof import("./types").FilePickerBaseProps> & React.RefAttributes<HTMLDivElement>>;
4
+ export declare const FilePicker: React.ForwardRefExoticComponent<{
5
+ id?: string | undefined;
6
+ name?: string | undefined;
7
+ size?: "s" | "m" | "l" | "2xs" | "xs" | undefined;
8
+ label?: string | undefined;
9
+ accept?: string | undefined;
10
+ placeholder?: string | undefined;
11
+ onChange?: React.ChangeEventHandler<HTMLInputElement> | undefined;
12
+ multiple?: boolean | undefined;
13
+ fileList?: File[] | undefined;
14
+ fullWidth?: boolean | undefined;
15
+ autoFocus?: boolean | undefined;
16
+ inputProps?: (Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & {
17
+ ref?: ((instance: HTMLInputElement | null) => void) | React.RefObject<HTMLInputElement> | null | undefined;
18
+ } & {
19
+ 'data-testid'?: string | undefined;
20
+ }) | undefined;
21
+ disableTruncate?: boolean | undefined;
22
+ required?: boolean | undefined;
23
+ renderLeft?: string | number | React.FC<React.SVGProps<SVGSVGElement> & {
24
+ color?: string | undefined;
25
+ ref?: React.Ref<SVGSVGElement> | undefined;
26
+ } & {
27
+ size?: import("@ozen-ui/icons").IconSize | undefined;
28
+ }> | React.ReactElement<React.SVGProps<SVGSVGElement> & {
29
+ color?: string | undefined;
30
+ ref?: React.Ref<SVGSVGElement> | undefined;
31
+ } & {
32
+ size?: import("@ozen-ui/icons").IconSize | undefined;
33
+ }, string | React.JSXElementConstructor<any>> | (() => React.ReactElement<React.SVGProps<SVGSVGElement> & {
34
+ color?: string | undefined;
35
+ ref?: React.Ref<SVGSVGElement> | undefined;
36
+ } & {
37
+ size?: import("@ozen-ui/icons").IconSize | undefined;
38
+ }, string | React.JSXElementConstructor<any>>) | undefined;
39
+ renderRight?: string | number | React.FC<React.SVGProps<SVGSVGElement> & {
40
+ color?: string | undefined;
41
+ ref?: React.Ref<SVGSVGElement> | undefined;
42
+ } & {
43
+ size?: import("@ozen-ui/icons").IconSize | undefined;
44
+ }> | React.ReactElement<React.SVGProps<SVGSVGElement> & {
45
+ color?: string | undefined;
46
+ ref?: React.Ref<SVGSVGElement> | undefined;
47
+ } & {
48
+ size?: import("@ozen-ui/icons").IconSize | undefined;
49
+ }, string | React.JSXElementConstructor<any>> | (() => React.ReactElement<React.SVGProps<SVGSVGElement> & {
50
+ color?: string | undefined;
51
+ ref?: React.Ref<SVGSVGElement> | undefined;
52
+ } & {
53
+ size?: import("@ozen-ui/icons").IconSize | undefined;
54
+ }, string | React.JSXElementConstructor<any>>) | undefined;
55
+ hint?: string | null | undefined;
56
+ error?: boolean | undefined;
57
+ disabled?: boolean | undefined;
58
+ labelProps?: import("../FieldLabel").FieldLabelProps | undefined;
59
+ renderValue?: import("./types").FilePickerRenderValue | undefined;
60
+ clearText?: string | undefined;
61
+ onClear?: ((e: React.KeyboardEvent<HTMLInputElement> | React.MouseEvent<HTMLButtonElement, globalThis.MouseEvent>, payload: {
62
+ name?: string | undefined;
63
+ }) => void) | undefined;
64
+ className?: string | undefined;
65
+ 'data-testid'?: string | undefined;
66
+ } & {
67
+ labelRef?: ((instance: HTMLSpanElement | null) => void) | React.RefObject<HTMLSpanElement> | null | undefined;
68
+ inputRef?: React.Ref<HTMLInputElement> | undefined;
69
+ } & Omit<React.HTMLAttributes<HTMLDivElement>, "name" | "label" | "className" | "id" | "onChange" | "autoFocus" | "disabled" | "accept" | "multiple" | "placeholder" | "required" | "size" | "error" | "fullWidth" | "labelProps" | "data-testid" | "hint" | "renderLeft" | "renderRight" | "inputProps" | "clearText" | "onClear" | "fileList" | "disableTruncate" | "renderValue" | keyof {
70
+ labelRef?: ((instance: HTMLSpanElement | null) => void) | React.RefObject<HTMLSpanElement> | null | undefined;
71
+ inputRef?: React.Ref<HTMLInputElement> | undefined;
72
+ }> & React.RefAttributes<HTMLDivElement>>;
@@ -2,26 +2,33 @@ import { __assign, __read, __rest } from "tslib";
2
2
  import './FilePicker.css';
3
3
  import React, { forwardRef, useState, useRef } from 'react';
4
4
  import { AttachmentIcon, CrossIcon } from '@ozen-ui/icons';
5
+ import { deprecate } from '@ozen-ui/logger';
5
6
  import { useMultiRef } from '../../hooks/useMultiRef';
6
7
  import { useThemeProps } from '../../hooks/useThemeProps';
7
8
  import { cn } from '../../utils/classname';
8
9
  import { isKey } from '../../utils/isKey';
10
+ import { FieldControl } from '../FieldControl';
9
11
  import { FieldHint } from '../FieldHint';
10
12
  import { FieldIcon } from '../FieldIcon';
11
13
  import { FieldLabel } from '../FieldLabel';
12
14
  import { Fieldset } from '../Fieldset';
13
- import { IconButton } from '../IconButton';
15
+ import { IconButton } from '../IconButtonNext';
14
16
  import { FILE_PICKER_DEFAULT_SIZE, FILE_PICKER_DEFAULT_DISABLED, FILE_PICKER_DEFAULT_REQUIRED, FILE_PICKER_DEFAULT_FULL_WIDTH, FILE_PICKER_DEFAULT_DISABLE_TRUNCATE, FILE_PICKER_DEFAULT_VALUE_RENDERER, FILE_PICKER_DEFAULT_MULTIPLE, } from './constants';
15
17
  export var cnFilePicker = cn('FilePicker');
16
18
  export var FilePicker = forwardRef(function (inProps, ref) {
17
19
  var _a = useThemeProps({
18
20
  props: inProps,
19
21
  name: 'FilePicker',
20
- }), _b = _a.size, size = _b === void 0 ? FILE_PICKER_DEFAULT_SIZE : _b, _c = _a.disabled, disabled = _c === void 0 ? FILE_PICKER_DEFAULT_DISABLED : _c, _d = _a.required, required = _d === void 0 ? FILE_PICKER_DEFAULT_REQUIRED : _d, _e = _a.fullWidth, fullWidth = _e === void 0 ? FILE_PICKER_DEFAULT_FULL_WIDTH : _e, _f = _a.disableTruncate, disableTruncate = _f === void 0 ? FILE_PICKER_DEFAULT_DISABLE_TRUNCATE : _f, _g = _a.multiple, multiple = _g === void 0 ? FILE_PICKER_DEFAULT_MULTIPLE : _g, placeholder = _a.placeholder, clearText = _a.clearText, _h = _a.renderRight, renderRight = _h === void 0 ? AttachmentIcon : _h, renderValueProp = _a.renderValue, onChangeProp = _a.onChange, onClearProp = _a.onClear, inputRefProp = _a.inputRef, fileList = _a.fileList, accept = _a.accept, id = _a.id, name = _a.name, label = _a.label, autoFocus = _a.autoFocus, error = _a.error, hint = _a.hint, renderLeft = _a.renderLeft, labelProps = _a.labelProps, inputProps = _a.inputProps, labelRef = _a.labelRef, className = _a.className, other = __rest(_a, ["size", "disabled", "required", "fullWidth", "disableTruncate", "multiple", "placeholder", "clearText", "renderRight", "renderValue", "onChange", "onClear", "inputRef", "fileList", "accept", "id", "name", "label", "autoFocus", "error", "hint", "renderLeft", "labelProps", "inputProps", "labelRef", "className"]);
21
- var fieldRef = useRef(null);
22
- var inputRef = useRef(null);
23
- var clearRef = useRef(null);
22
+ }), _b = _a.size, size = _b === void 0 ? FILE_PICKER_DEFAULT_SIZE : _b, _c = _a.disabled, disabled = _c === void 0 ? FILE_PICKER_DEFAULT_DISABLED : _c, _d = _a.required, required = _d === void 0 ? FILE_PICKER_DEFAULT_REQUIRED : _d, _e = _a.fullWidth, fullWidth = _e === void 0 ? FILE_PICKER_DEFAULT_FULL_WIDTH : _e, _f = _a.disableTruncate, disableTruncate = _f === void 0 ? FILE_PICKER_DEFAULT_DISABLE_TRUNCATE : _f, _g = _a.multiple, multiple = _g === void 0 ? FILE_PICKER_DEFAULT_MULTIPLE : _g, placeholder = _a.placeholder, clearText = _a.clearText, _h = _a.renderRight, renderRight = _h === void 0 ? AttachmentIcon : _h, renderValueProp = _a.renderValue, onChangeProp = _a.onChange, onClearProp = _a.onClear, inputRef = _a.inputRef, fileList = _a.fileList, accept = _a.accept, id = _a.id, name = _a.name, label = _a.label, autoFocus = _a.autoFocus, error = _a.error, hint = _a.hint, renderLeft = _a.renderLeft, labelProps = _a.labelProps, inputProps = _a.inputProps, labelRef = _a.labelRef, className = _a.className, other = __rest(_a, ["size", "disabled", "required", "fullWidth", "disableTruncate", "multiple", "placeholder", "clearText", "renderRight", "renderValue", "onChange", "onClear", "inputRef", "fileList", "accept", "id", "name", "label", "autoFocus", "error", "hint", "renderLeft", "labelProps", "inputProps", "labelRef", "className"]);
23
+ if (process.env.NODE_ENV !== 'production' && labelRef) {
24
+ deprecate('Свойство «labelRef» устарело. Для замены используйте «labelProps.ref».');
25
+ }
26
+ if (process.env.NODE_ENV !== 'production' && inputRef) {
27
+ deprecate('Свойство «inputRef» устарело. Для замены используйте «inputProps.ref».');
28
+ }
29
+ var inputInnerRef = useRef(null);
24
30
  var _j = __read(useState(false), 2), focused = _j[0], setFocused = _j[1];
31
+ var hasFiles = !!(fileList === null || fileList === void 0 ? void 0 : fileList.length);
25
32
  var handleFocus = function (e) {
26
33
  var _a;
27
34
  (_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onFocus) === null || _a === void 0 ? void 0 : _a.call(inputProps, e);
@@ -34,8 +41,8 @@ export var FilePicker = forwardRef(function (inProps, ref) {
34
41
  };
35
42
  var onChange = function (e) {
36
43
  onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(e);
37
- if (inputRef.current) {
38
- inputRef.current.value = '';
44
+ if (inputInnerRef.current) {
45
+ inputInnerRef.current.value = '';
39
46
  }
40
47
  };
41
48
  var onClear = function (e) {
@@ -52,25 +59,19 @@ export var FilePicker = forwardRef(function (inProps, ref) {
52
59
  ? renderValueProp(file)
53
60
  : FILE_PICKER_DEFAULT_VALUE_RENDERER(file, disableTruncate);
54
61
  };
55
- return (React.createElement("div", __assign({}, other, { className: cnFilePicker('', {
56
- hasLabel: !!label,
57
- hasValue: !!(fileList === null || fileList === void 0 ? void 0 : fileList.length),
58
- size: size,
59
- error: error,
60
- focused: focused,
61
- disabled: disabled,
62
- required: required,
63
- fullWidth: fullWidth,
64
- }, [className]), ref: useMultiRef([fieldRef, ref]) }),
62
+ return (React.createElement(FieldControl, __assign({ size: size, error: error, focused: focused, disabled: disabled, required: required, fullWidth: fullWidth, filled: hasFiles }, other, { className: cnFilePicker('', [className]), ref: ref }),
65
63
  React.createElement("label", { className: cnFilePicker('Body') },
66
- React.createElement(FieldIcon, { className: cnFilePicker('RenderLeft'), icon: renderLeft, size: size }),
64
+ React.createElement(FieldIcon, { icon: renderLeft }),
67
65
  React.createElement("div", { className: cnFilePicker('FieldContainer') },
68
- label && (React.createElement(FieldLabel, __assign({ filled: !!(fileList === null || fileList === void 0 ? void 0 : fileList.length), focused: focused, required: required, disabled: disabled, size: size }, labelProps, { className: cnFilePicker('Label', [labelProps === null || labelProps === void 0 ? void 0 : labelProps.className]), ref: labelRef }), label)),
69
- React.createElement("input", __assign({ id: id, name: name, autoFocus: autoFocus, onFocus: handleFocus, onBlur: handleBlur, className: cnFilePicker('Input'), required: required, disabled: disabled, accept: accept, multiple: multiple }, inputProps, { onChange: onChange, onKeyDown: onKeyDown, ref: useMultiRef([inputRef, inputRefProp]), type: "file" })),
70
- (fileList === null || fileList === void 0 ? void 0 : fileList.length) ? (React.createElement("span", { className: cnFilePicker('FileName') }, renderValue(fileList, disableTruncate))) : (React.createElement("span", { "aria-placeholder": placeholder, className: cnFilePicker('Placeholder') }, placeholder))),
71
- !!(fileList === null || fileList === void 0 ? void 0 : fileList.length) && onClearProp && (React.createElement(IconButton, { tabIndex: -1, variant: "function", "aria-label": clearText, ref: clearRef, onClick: onClear, size: size, icon: CrossIcon })),
72
- React.createElement(FieldIcon, { className: cnFilePicker('RenderRight'), icon: renderRight, size: size }),
73
- React.createElement(Fieldset, { className: cnFilePicker('Fieldset') })),
74
- React.createElement(FieldHint, { size: size, error: error, disabled: disabled }, hint)));
66
+ React.createElement(FieldLabel, __assign({}, labelProps, { ref: labelRef || (labelProps === null || labelProps === void 0 ? void 0 : labelProps.ref), className: cnFilePicker('Label', [labelProps === null || labelProps === void 0 ? void 0 : labelProps.className]) }), label),
67
+ React.createElement("input", __assign({ id: id, name: name, accept: accept, multiple: multiple, onBlur: handleBlur, required: required, disabled: disabled, autoFocus: autoFocus, onFocus: handleFocus, className: cnFilePicker('Input') }, inputProps, { type: "file", onChange: onChange, onKeyDown: onKeyDown, ref: useMultiRef([inputRef || (inputProps === null || inputProps === void 0 ? void 0 : inputProps.ref), inputInnerRef]) })),
68
+ hasFiles ? (React.createElement("span", { className: cnFilePicker('FileName') }, renderValue(fileList, disableTruncate))) : (React.createElement("span", { "aria-placeholder": placeholder, className: cnFilePicker('Placeholder') }, placeholder))),
69
+ React.createElement("div", { className: cnFilePicker('RenderRight') },
70
+ onClearProp && (React.createElement(IconButton, { size: size, tabIndex: -1, icon: CrossIcon, onClick: onClear, variant: "function", "aria-label": clearText, className: cnFilePicker('ClearButton', {
71
+ visibility: hasFiles,
72
+ }) })),
73
+ React.createElement(FieldIcon, { icon: renderRight })),
74
+ React.createElement(Fieldset, null)),
75
+ React.createElement(FieldHint, null, hint)));
75
76
  });
76
77
  FilePicker.displayName = 'FilePicker';
@@ -1,11 +1,23 @@
1
- import type { Ref, HTMLAttributes, InputHTMLAttributes, MouseEvent, KeyboardEvent, ChangeEventHandler, ReactNode } from 'react';
1
+ import type { Ref, HTMLAttributes, MouseEvent, KeyboardEvent, ChangeEventHandler, ReactNode, ComponentPropsWithRef } from 'react';
2
2
  import type { ExtendableProps } from '../../types/ExtendableProps';
3
3
  import type { FormElementSizeVariant } from '../../types/FormElementSizeVariant';
4
4
  import type { FieldIconProps } from '../FieldIcon';
5
5
  import type { FieldLabelProps } from '../FieldLabel';
6
6
  export type FilePickerSizeVariant = FormElementSizeVariant;
7
7
  export type FilePickerRenderValue = (value: File[]) => ReactNode | null;
8
- type InputElement = InputHTMLAttributes<HTMLInputElement>;
8
+ type InputElement = ComponentPropsWithRef<'input'>;
9
+ type FilePickerPropsDeprecated = {
10
+ /**
11
+ * Ссылка на FieldLabel
12
+ * @deprecated Используйте labelProps.ref
13
+ * */
14
+ labelRef?: FieldLabelProps['ref'];
15
+ /**
16
+ * Ссылка на элемент input
17
+ * @deprecated Используйте inputProps.ref
18
+ * */
19
+ inputRef?: Ref<HTMLInputElement>;
20
+ };
9
21
  export type FilePickerBaseProps = {
10
22
  /** Атрибут id для элемента input */
11
23
  id?: string;
@@ -33,8 +45,6 @@ export type FilePickerBaseProps = {
33
45
  inputProps?: InputElement & {
34
46
  'data-testid'?: string;
35
47
  };
36
- /** Ссылка на элемент input */
37
- inputRef?: Ref<HTMLInputElement>;
38
48
  /** Если {true} отключает сокращение длинного названия файла */
39
49
  disableTruncate?: boolean;
40
50
  /** Если {true} делает элемент обязательным к заполнению */
@@ -51,8 +61,6 @@ export type FilePickerBaseProps = {
51
61
  disabled?: boolean;
52
62
  /** Свойства FieldLabel */
53
63
  labelProps?: FieldLabelProps;
54
- /** Ссылка на FieldLabel */
55
- labelRef?: FieldLabelProps['ref'];
56
64
  /** Функция */
57
65
  renderValue?: FilePickerRenderValue;
58
66
  /** Текст для кнопки очистки поля */
@@ -63,7 +71,8 @@ export type FilePickerBaseProps = {
63
71
  }) => void;
64
72
  /** Дополнительные css-классы */
65
73
  className?: string;
74
+ /** data-атрибут для тестирования */
66
75
  'data-testid'?: string;
67
- };
76
+ } & FilePickerPropsDeprecated;
68
77
  export type FilePickerProps = ExtendableProps<HTMLAttributes<HTMLDivElement>, FilePickerBaseProps>;
69
78
  export {};
@@ -9,7 +9,7 @@
9
9
  background-color: var(--textfield-background-color);
10
10
  transition: background-color var(--transition-slow);
11
11
  color: var(--textfield-color);
12
- border-radius: var(--border-radius-xs);
12
+ border-radius: var(--textfield-border-radius);
13
13
  }
14
14
  .Input-FieldContainer {
15
15
  inline-size: 100%;
@@ -29,7 +29,7 @@
29
29
  }
30
30
  .Input-Field::placeholder {
31
31
  opacity: 1;
32
- color: var(--color-content-tertiary);
32
+ color: var(--textfield-placeholder-color);
33
33
  }
34
34
  .Input-Field:-webkit-autofill,
35
35
  .Input-Field:-webkit-autofill:hover,
@@ -41,7 +41,7 @@
41
41
  color: var(--textfield-color);
42
42
  -moz-column-gap: var(--textfield-input-gap);
43
43
  column-gap: var(--textfield-input-gap);
44
- border-radius: var(--border-radius-xs);
44
+ border-radius: var(--textfield-border-radius);
45
45
  padding: var(--input-number-padding);
46
46
  background-color: var(--textfield-background-color);
47
47
  transition: background-color var(--transition-slow);
@@ -70,7 +70,7 @@
70
70
 
71
71
  .InputNumber-Field::placeholder {
72
72
  opacity: 1;
73
- color: var(--color-content-tertiary);
73
+ color: var(--textfield-placeholder-color);
74
74
  }
75
75
 
76
76
  .InputNumber-Field:-webkit-autofill,
@@ -23,7 +23,7 @@
23
23
  transition: background-color var(--transition-slow);
24
24
  padding: 0 var(--textfield-gutter-x);
25
25
  color: var(--textfield-color);
26
- border-radius: var(--border-radius-xs);
26
+ border-radius: var(--textfield-border-radius);
27
27
  cursor: pointer;
28
28
  outline: none;
29
29
  }
@@ -54,7 +54,7 @@
54
54
  }
55
55
 
56
56
  .Select-Field_asPlaceholder {
57
- color: var(--color-content-tertiary);
57
+ color: var(--textfield-placeholder-color);
58
58
  }
59
59
 
60
60
  .Select_multiline .Select-FieldContainer {
@@ -23,7 +23,7 @@
23
23
  background-color: var(--textfield-background-color);
24
24
  transition: background-color var(--transition-slow);
25
25
  color: var(--textfield-color);
26
- border-radius: var(--border-radius-xs);
26
+ border-radius: var(--textfield-border-radius);
27
27
  min-block-size: inherit;
28
28
  block-size: inherit;
29
29
  padding: var(--textfield-input-padding);
@@ -78,7 +78,7 @@
78
78
 
79
79
  .Textarea-Field::placeholder {
80
80
  opacity: 1;
81
- color: var(--color-content-tertiary);
81
+ color: var(--textfield-placeholder-color);
82
82
  }
83
83
 
84
84
  .Textarea-Counter {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozen-ui/kit",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "React component library",
5
5
  "files": [
6
6
  "*"
@@ -27,9 +27,9 @@
27
27
  "react-popper": "^2.3.0",
28
28
  "react-transition-group": "^4.4.5",
29
29
  "tslib": "^2.6.2",
30
- "@ozen-ui/fonts": "0.40.0",
31
- "@ozen-ui/icons": "0.40.0",
32
- "@ozen-ui/logger": "0.40.0"
30
+ "@ozen-ui/fonts": "0.41.0",
31
+ "@ozen-ui/icons": "0.41.0",
32
+ "@ozen-ui/logger": "0.41.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": ">=17.0.2 <19.0.0",