@snack-uikit/fields 0.8.3-preview-85c5f47b.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 (172) hide show
  1. package/CHANGELOG.md +655 -0
  2. package/LICENSE +201 -0
  3. package/README.md +329 -0
  4. package/dist/components/FieldDate/FieldDate.d.ts +29 -0
  5. package/dist/components/FieldDate/FieldDate.js +152 -0
  6. package/dist/components/FieldDate/constants.d.ts +10 -0
  7. package/dist/components/FieldDate/constants.js +28 -0
  8. package/dist/components/FieldDate/hooks/index.d.ts +1 -0
  9. package/dist/components/FieldDate/hooks/index.js +1 -0
  10. package/dist/components/FieldDate/hooks/useDateField.d.ts +20 -0
  11. package/dist/components/FieldDate/hooks/useDateField.js +180 -0
  12. package/dist/components/FieldDate/hooks/useDateFieldHelpers.d.ts +10 -0
  13. package/dist/components/FieldDate/hooks/useDateFieldHelpers.js +66 -0
  14. package/dist/components/FieldDate/hooks/useFocusHandlers.d.ts +15 -0
  15. package/dist/components/FieldDate/hooks/useFocusHandlers.js +33 -0
  16. package/dist/components/FieldDate/hooks/useHandlers.d.ts +6 -0
  17. package/dist/components/FieldDate/hooks/useHandlers.js +9 -0
  18. package/dist/components/FieldDate/index.d.ts +1 -0
  19. package/dist/components/FieldDate/index.js +1 -0
  20. package/dist/components/FieldDate/styles.module.css +44 -0
  21. package/dist/components/FieldDate/types.d.ts +6 -0
  22. package/dist/components/FieldDate/types.js +1 -0
  23. package/dist/components/FieldDate/utils.d.ts +5 -0
  24. package/dist/components/FieldDate/utils.js +39 -0
  25. package/dist/components/FieldDecorator/FieldDecorator.d.ts +20 -0
  26. package/dist/components/FieldDecorator/FieldDecorator.js +26 -0
  27. package/dist/components/FieldDecorator/Footer.d.ts +24 -0
  28. package/dist/components/FieldDecorator/Footer.js +39 -0
  29. package/dist/components/FieldDecorator/Header.d.ts +20 -0
  30. package/dist/components/FieldDecorator/Header.js +8 -0
  31. package/dist/components/FieldDecorator/index.d.ts +1 -0
  32. package/dist/components/FieldDecorator/index.js +1 -0
  33. package/dist/components/FieldDecorator/styles.module.css +177 -0
  34. package/dist/components/FieldSecure/FieldSecure.d.ts +29 -0
  35. package/dist/components/FieldSecure/FieldSecure.js +55 -0
  36. package/dist/components/FieldSecure/index.d.ts +1 -0
  37. package/dist/components/FieldSecure/index.js +1 -0
  38. package/dist/components/FieldSelect/FieldSelect.d.ts +16 -0
  39. package/dist/components/FieldSelect/FieldSelect.js +34 -0
  40. package/dist/components/FieldSelect/FieldSelectBase.d.ts +30 -0
  41. package/dist/components/FieldSelect/FieldSelectBase.js +51 -0
  42. package/dist/components/FieldSelect/FieldSelectMulti.d.ts +36 -0
  43. package/dist/components/FieldSelect/FieldSelectMulti.js +89 -0
  44. package/dist/components/FieldSelect/FieldSelectSingle.d.ts +35 -0
  45. package/dist/components/FieldSelect/FieldSelectSingle.js +76 -0
  46. package/dist/components/FieldSelect/constants.d.ts +3 -0
  47. package/dist/components/FieldSelect/constants.js +2 -0
  48. package/dist/components/FieldSelect/helpers/getArrowIcon.d.ts +8 -0
  49. package/dist/components/FieldSelect/helpers/getArrowIcon.js +5 -0
  50. package/dist/components/FieldSelect/helpers/getDisplayedValue.d.ts +9 -0
  51. package/dist/components/FieldSelect/helpers/getDisplayedValue.js +12 -0
  52. package/dist/components/FieldSelect/helpers/index.d.ts +2 -0
  53. package/dist/components/FieldSelect/helpers/index.js +2 -0
  54. package/dist/components/FieldSelect/hooks/index.d.ts +3 -0
  55. package/dist/components/FieldSelect/hooks/index.js +3 -0
  56. package/dist/components/FieldSelect/hooks/useFilteredOptions.d.ts +7 -0
  57. package/dist/components/FieldSelect/hooks/useFilteredOptions.js +6 -0
  58. package/dist/components/FieldSelect/hooks/useList.d.ts +36 -0
  59. package/dist/components/FieldSelect/hooks/useList.js +52 -0
  60. package/dist/components/FieldSelect/hooks/useListNavigation.d.ts +26 -0
  61. package/dist/components/FieldSelect/hooks/useListNavigation.js +48 -0
  62. package/dist/components/FieldSelect/index.d.ts +1 -0
  63. package/dist/components/FieldSelect/index.js +1 -0
  64. package/dist/components/FieldSelect/styles.module.css +74 -0
  65. package/dist/components/FieldSelect/types.d.ts +53 -0
  66. package/dist/components/FieldSelect/types.js +5 -0
  67. package/dist/components/FieldText/FieldText.d.ts +25 -0
  68. package/dist/components/FieldText/FieldText.js +52 -0
  69. package/dist/components/FieldText/index.d.ts +1 -0
  70. package/dist/components/FieldText/index.js +1 -0
  71. package/dist/components/FieldTextArea/FieldTextArea.d.ts +30 -0
  72. package/dist/components/FieldTextArea/FieldTextArea.js +54 -0
  73. package/dist/components/FieldTextArea/index.d.ts +1 -0
  74. package/dist/components/FieldTextArea/index.js +1 -0
  75. package/dist/components/FieldTextArea/styles.module.css +48 -0
  76. package/dist/components/index.d.ts +6 -0
  77. package/dist/components/index.js +6 -0
  78. package/dist/constants.d.ts +10 -0
  79. package/dist/constants.js +12 -0
  80. package/dist/helperComponents/ButtonCopyValue/ButtonCopyValue.d.ts +11 -0
  81. package/dist/helperComponents/ButtonCopyValue/ButtonCopyValue.js +24 -0
  82. package/dist/helperComponents/ButtonCopyValue/helpers.d.ts +7 -0
  83. package/dist/helperComponents/ButtonCopyValue/helpers.js +14 -0
  84. package/dist/helperComponents/ButtonCopyValue/index.d.ts +1 -0
  85. package/dist/helperComponents/ButtonCopyValue/index.js +1 -0
  86. package/dist/helperComponents/ButtonCopyValue/styles.module.css +47 -0
  87. package/dist/helperComponents/ButtonHideValue/ButtonHideValue.d.ts +12 -0
  88. package/dist/helperComponents/ButtonHideValue/ButtonHideValue.js +15 -0
  89. package/dist/helperComponents/ButtonHideValue/index.d.ts +1 -0
  90. package/dist/helperComponents/ButtonHideValue/index.js +1 -0
  91. package/dist/helperComponents/ButtonHideValue/styles.module.css +47 -0
  92. package/dist/helperComponents/FieldContainerPrivate/FieldContainerPrivate.d.ts +21 -0
  93. package/dist/helperComponents/FieldContainerPrivate/FieldContainerPrivate.js +27 -0
  94. package/dist/helperComponents/FieldContainerPrivate/index.d.ts +1 -0
  95. package/dist/helperComponents/FieldContainerPrivate/index.js +1 -0
  96. package/dist/helperComponents/FieldContainerPrivate/styles.module.css +197 -0
  97. package/dist/helperComponents/TextArea/TextArea.d.ts +32 -0
  98. package/dist/helperComponents/TextArea/TextArea.js +27 -0
  99. package/dist/helperComponents/TextArea/index.d.ts +1 -0
  100. package/dist/helperComponents/TextArea/index.js +1 -0
  101. package/dist/helperComponents/TextArea/styles.module.css +32 -0
  102. package/dist/helperComponents/index.d.ts +4 -0
  103. package/dist/helperComponents/index.js +4 -0
  104. package/dist/hooks/index.d.ts +2 -0
  105. package/dist/hooks/index.js +2 -0
  106. package/dist/hooks/useCopyButton.d.ts +10 -0
  107. package/dist/hooks/useCopyButton.js +12 -0
  108. package/dist/hooks/useHideButton.d.ts +12 -0
  109. package/dist/hooks/useHideButton.js +20 -0
  110. package/dist/index.d.ts +1 -0
  111. package/dist/index.js +1 -0
  112. package/dist/styles.module.css +0 -0
  113. package/package.json +53 -0
  114. package/src/components/FieldDate/FieldDate.tsx +339 -0
  115. package/src/components/FieldDate/constants.ts +33 -0
  116. package/src/components/FieldDate/hooks/index.ts +1 -0
  117. package/src/components/FieldDate/hooks/useDateField.ts +227 -0
  118. package/src/components/FieldDate/hooks/useDateFieldHelpers.ts +96 -0
  119. package/src/components/FieldDate/hooks/useFocusHandlers.ts +46 -0
  120. package/src/components/FieldDate/hooks/useHandlers.ts +15 -0
  121. package/src/components/FieldDate/index.ts +1 -0
  122. package/src/components/FieldDate/styles.module.scss +58 -0
  123. package/src/components/FieldDate/types.ts +6 -0
  124. package/src/components/FieldDate/utils.ts +44 -0
  125. package/src/components/FieldDecorator/FieldDecorator.tsx +69 -0
  126. package/src/components/FieldDecorator/Footer.tsx +105 -0
  127. package/src/components/FieldDecorator/Header.tsx +52 -0
  128. package/src/components/FieldDecorator/index.ts +1 -0
  129. package/src/components/FieldDecorator/styles.module.scss +176 -0
  130. package/src/components/FieldSecure/FieldSecure.tsx +170 -0
  131. package/src/components/FieldSecure/index.ts +1 -0
  132. package/src/components/FieldSelect/FieldSelect.tsx +41 -0
  133. package/src/components/FieldSelect/FieldSelectBase.tsx +221 -0
  134. package/src/components/FieldSelect/FieldSelectMulti.tsx +161 -0
  135. package/src/components/FieldSelect/FieldSelectSingle.tsx +131 -0
  136. package/src/components/FieldSelect/constants.ts +4 -0
  137. package/src/components/FieldSelect/helpers/getArrowIcon.ts +6 -0
  138. package/src/components/FieldSelect/helpers/getDisplayedValue.ts +24 -0
  139. package/src/components/FieldSelect/helpers/index.ts +2 -0
  140. package/src/components/FieldSelect/hooks/index.ts +3 -0
  141. package/src/components/FieldSelect/hooks/useFilteredOptions.ts +23 -0
  142. package/src/components/FieldSelect/hooks/useList.ts +85 -0
  143. package/src/components/FieldSelect/hooks/useListNavigation.ts +81 -0
  144. package/src/components/FieldSelect/index.ts +1 -0
  145. package/src/components/FieldSelect/styles.module.scss +87 -0
  146. package/src/components/FieldSelect/types.ts +78 -0
  147. package/src/components/FieldText/FieldText.tsx +154 -0
  148. package/src/components/FieldText/index.ts +1 -0
  149. package/src/components/FieldTextArea/FieldTextArea.tsx +171 -0
  150. package/src/components/FieldTextArea/index.ts +1 -0
  151. package/src/components/FieldTextArea/styles.module.scss +41 -0
  152. package/src/components/index.ts +6 -0
  153. package/src/constants.ts +11 -0
  154. package/src/helperComponents/ButtonCopyValue/ButtonCopyValue.tsx +55 -0
  155. package/src/helperComponents/ButtonCopyValue/helpers.tsx +19 -0
  156. package/src/helperComponents/ButtonCopyValue/index.ts +1 -0
  157. package/src/helperComponents/ButtonCopyValue/styles.module.scss +5 -0
  158. package/src/helperComponents/ButtonHideValue/ButtonHideValue.tsx +55 -0
  159. package/src/helperComponents/ButtonHideValue/index.ts +1 -0
  160. package/src/helperComponents/ButtonHideValue/styles.module.scss +5 -0
  161. package/src/helperComponents/FieldContainerPrivate/FieldContainerPrivate.tsx +78 -0
  162. package/src/helperComponents/FieldContainerPrivate/index.ts +1 -0
  163. package/src/helperComponents/FieldContainerPrivate/styles.module.scss +162 -0
  164. package/src/helperComponents/TextArea/TextArea.tsx +102 -0
  165. package/src/helperComponents/TextArea/index.ts +1 -0
  166. package/src/helperComponents/TextArea/styles.module.scss +35 -0
  167. package/src/helperComponents/index.ts +4 -0
  168. package/src/hooks/index.ts +2 -0
  169. package/src/hooks/useCopyButton.tsx +24 -0
  170. package/src/hooks/useHideButton.tsx +50 -0
  171. package/src/index.ts +1 -0
  172. package/src/styles.module.scss +55 -0
@@ -0,0 +1,89 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
14
+ import { useUncontrolledProp } from 'uncontrollable';
15
+ import { DEFAULT_LOCALE } from './constants';
16
+ import { FieldSelectBase } from './FieldSelectBase';
17
+ import { getDisplayedValue } from './helpers';
18
+ import { useList } from './hooks';
19
+ import { SelectionMode } from './types';
20
+ export const FieldSelectMulti = forwardRef((_a, ref) => {
21
+ var { value: valueProp, onChange, options, disabled = false, readonly = false, searchable = true, required = false, open, onOpenChange, locale = DEFAULT_LOCALE, getSelectedItemsText = number => ((locale === null || locale === void 0 ? void 0 : locale.language) === 'ru' ? `Выбрано: ${number}` : `Selected: ${number}`), showCopyButton: showCopyButtonProp = true, onFocus, onBlur } = _a, rest = __rest(_a, ["value", "onChange", "options", "disabled", "readonly", "searchable", "required", "open", "onOpenChange", "locale", "getSelectedItemsText", "showCopyButton", "onFocus", "onBlur"]);
22
+ const selectionMode = SelectionMode.Multi;
23
+ const [value, setValue] = useUncontrolledProp(valueProp, [], onChange);
24
+ const selected = useMemo(() => options.filter(option => value === null || value === void 0 ? void 0 : value.includes(option.value)), [options, value]);
25
+ const displayedValue = getDisplayedValue({ selectionMode, selected, getSelectedItemsText });
26
+ const valueToCopy = selected.map(op => op.label).join(', ');
27
+ const [inputValue, setInputValue] = useState('');
28
+ const showAdditionalButton = Boolean((value === null || value === void 0 ? void 0 : value.length) && value.length > 0 && !disabled);
29
+ const isChecked = useCallback((option) => Boolean(selected.find(op => op.value === option.value)), [selected]);
30
+ const [isFocused, setIsFocused] = useState(false);
31
+ const stayOpen = useRef(false);
32
+ const waitingForSearchStart = searchable && !isFocused;
33
+ const showDisplayValue = displayedValue && (!searchable || waitingForSearchStart);
34
+ const { isOpen, setIsOpen, localRef, extendedOptions, onInputKeyDown, onInputValueChange, onButtonKeyDown, clearButtonRef, copyButtonRef, showClearButton, showCopyButton, onDroplistFocusLeave, firstDroplistItemRefCallback, } = useList({
35
+ open,
36
+ onOpenChange,
37
+ disabled,
38
+ readonly,
39
+ inputValue,
40
+ setInputValue,
41
+ searchable,
42
+ options,
43
+ isChecked,
44
+ showAdditionalButton,
45
+ showCopyButton: showCopyButtonProp,
46
+ });
47
+ const handleOpenChange = (isOpen) => {
48
+ if (stayOpen.current) {
49
+ stayOpen.current = false;
50
+ return;
51
+ }
52
+ setInputValue('');
53
+ setIsOpen(isOpen);
54
+ };
55
+ const handlePreventListClose = event => {
56
+ event.preventDefault();
57
+ if (isOpen && waitingForSearchStart) {
58
+ stayOpen.current = true;
59
+ }
60
+ };
61
+ const handleClear = () => {
62
+ var _a, _b;
63
+ setValue([]);
64
+ setInputValue('');
65
+ stayOpen.current = false;
66
+ if (required) {
67
+ (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
68
+ setIsOpen(true);
69
+ }
70
+ else {
71
+ (_b = localRef.current) === null || _b === void 0 ? void 0 : _b.blur();
72
+ setIsOpen(false);
73
+ }
74
+ };
75
+ const handleChange = (option) => () => {
76
+ setValue((selected.find(op => op.value === option.value)
77
+ ? selected.filter(op => op.value !== option.value)
78
+ : [...selected, option]).map(op => op.value));
79
+ };
80
+ const handleFocus = event => {
81
+ setIsFocused(true);
82
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
83
+ };
84
+ const handleBlur = event => {
85
+ setIsFocused(false);
86
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
87
+ };
88
+ return (_jsx(FieldSelectBase, Object.assign({}, rest, { ref: ref, localRef: localRef, selectionMode: selectionMode, options: extendedOptions, selected: selected, disabled: disabled, readonly: readonly, required: required, searchable: searchable, onChange: handleChange, onClear: handleClear, displayedValue: showDisplayValue ? displayedValue : '', valueToCopy: valueToCopy, inputValue: inputValue, onInputValueChange: onInputValueChange, onInputKeyDown: onInputKeyDown, clearButtonRef: clearButtonRef, copyButtonRef: copyButtonRef, onButtonKeyDown: onButtonKeyDown, open: isOpen, onOpenChange: handleOpenChange, locale: locale, showCopyButton: showCopyButton, showClearButton: showClearButton, onFocus: handleFocus, onBlur: handleBlur, onContainerPrivateMouseDown: handlePreventListClose, onDroplistFocusLeave: onDroplistFocusLeave, firstDroplistItemRefCallback: firstDroplistItemRefCallback })));
89
+ });
@@ -0,0 +1,35 @@
1
+ /// <reference types="react" />
2
+ import { Option } from './types';
3
+ export declare const FieldSelectSingle: import("react").ForwardRefExoticComponent<{
4
+ 'data-test-id'?: string | undefined;
5
+ } & import("react").AriaAttributes & {
6
+ options: Option[];
7
+ open?: boolean | undefined;
8
+ onOpenChange?(value: boolean): void;
9
+ searchable?: boolean | undefined;
10
+ showCopyButton?: boolean | undefined;
11
+ prefixIcon?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
12
+ noDataText?: string | undefined;
13
+ locale?: Intl.Locale | undefined;
14
+ } & {
15
+ disabled?: boolean | undefined;
16
+ readonly?: boolean | undefined;
17
+ name?: string | undefined;
18
+ placeholder?: string | undefined;
19
+ id?: string | undefined;
20
+ onFocus?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
21
+ onBlur?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
22
+ } & {
23
+ showHintIcon?: boolean | undefined;
24
+ validationState?: import("../../constants").ValidationState | undefined;
25
+ hint?: string | undefined;
26
+ size?: import("@snack-uikit/input-private").Size | undefined;
27
+ label?: string | undefined;
28
+ className?: string | undefined;
29
+ labelTooltip?: string | undefined;
30
+ required?: boolean | undefined;
31
+ labelTooltipPlacement?: import("@snack-uikit/popover-private/dist/constants").Placement | undefined;
32
+ } & {
33
+ value?: string | undefined;
34
+ onChange?(value: string): void;
35
+ } & import("react").RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,76 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react';
14
+ import { useUncontrolledProp } from 'uncontrollable';
15
+ import { selectAll } from '@snack-uikit/input-private';
16
+ import { DEFAULT_LOCALE, EMPTY_OPTION } from './constants';
17
+ import { FieldSelectBase } from './FieldSelectBase';
18
+ import { getDisplayedValue } from './helpers';
19
+ import { useList } from './hooks';
20
+ import { SelectionMode } from './types';
21
+ export const FieldSelectSingle = forwardRef((_a, ref) => {
22
+ var { value: valueProp, onChange, options, disabled = false, readonly = false, searchable = true, required = false, locale = DEFAULT_LOCALE, open, onOpenChange, showCopyButton: showCopyButtonProp = true } = _a, rest = __rest(_a, ["value", "onChange", "options", "disabled", "readonly", "searchable", "required", "locale", "open", "onOpenChange", "showCopyButton"]);
23
+ const selectionMode = SelectionMode.Single;
24
+ const [value, setValue] = useUncontrolledProp(valueProp, '', onChange);
25
+ const selected = useMemo(() => { var _a; return (_a = options.find(option => option.value === value)) !== null && _a !== void 0 ? _a : EMPTY_OPTION; }, [options, value]);
26
+ const displayedValue = getDisplayedValue({ selectionMode, selected });
27
+ const [inputValue, setInputValue] = useState(selected.label);
28
+ const showAdditionalButton = Boolean(value && !disabled);
29
+ const isChecked = useCallback((option) => selected.value === option.value, [selected.value]);
30
+ const { isOpen, setIsOpen, localRef, extendedOptions, onInputKeyDown, onInputValueChange, onButtonKeyDown, clearButtonRef, copyButtonRef, showClearButton, showCopyButton, onDroplistFocusLeave, firstDroplistItemRefCallback, } = useList({
31
+ open,
32
+ onOpenChange,
33
+ disabled,
34
+ readonly,
35
+ inputValue,
36
+ setInputValue,
37
+ searchable,
38
+ options,
39
+ isChecked,
40
+ showCopyButton: showCopyButtonProp,
41
+ showAdditionalButton,
42
+ });
43
+ const handleOpenChange = (isOpen) => {
44
+ if (isOpen) {
45
+ searchable && selectAll(localRef.current);
46
+ }
47
+ else {
48
+ setInputValue(displayedValue);
49
+ }
50
+ setIsOpen(isOpen);
51
+ };
52
+ const handleClear = () => {
53
+ var _a, _b;
54
+ setValue('');
55
+ setInputValue('');
56
+ if (required) {
57
+ (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
58
+ setIsOpen(true);
59
+ }
60
+ else {
61
+ (_b = localRef.current) === null || _b === void 0 ? void 0 : _b.blur();
62
+ setIsOpen(false);
63
+ }
64
+ };
65
+ const handleChange = (option) => () => {
66
+ var _a;
67
+ setValue(option.value);
68
+ setInputValue(option.label);
69
+ setIsOpen(false);
70
+ (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
71
+ };
72
+ useEffect(() => {
73
+ setInputValue(selected.label);
74
+ }, [selected]);
75
+ return (_jsx(FieldSelectBase, Object.assign({}, rest, { ref: ref, localRef: localRef, selectionMode: selectionMode, options: extendedOptions, selected: selected, disabled: disabled, readonly: readonly, required: required, searchable: searchable, onChange: handleChange, onClear: handleClear, valueToCopy: displayedValue, inputValue: searchable ? inputValue : displayedValue, onInputValueChange: onInputValueChange, onInputKeyDown: onInputKeyDown, clearButtonRef: clearButtonRef, copyButtonRef: copyButtonRef, onButtonKeyDown: onButtonKeyDown, open: isOpen, onOpenChange: handleOpenChange, locale: locale, showCopyButton: showCopyButton, showClearButton: showClearButton, onDroplistFocusLeave: onDroplistFocusLeave, firstDroplistItemRefCallback: firstDroplistItemRefCallback })));
76
+ });
@@ -0,0 +1,3 @@
1
+ import { Option } from './types';
2
+ export declare const EMPTY_OPTION: Option;
3
+ export declare const DEFAULT_LOCALE: Intl.Locale;
@@ -0,0 +1,2 @@
1
+ export const EMPTY_OPTION = { value: '', label: '' };
2
+ export const DEFAULT_LOCALE = new Intl.Locale('ru-RU');
@@ -0,0 +1,8 @@
1
+ import { IconSize, Size } from '@snack-uikit/input-private';
2
+ export declare function getArrowIcon({ size, open }: {
3
+ size: Size;
4
+ open: boolean;
5
+ }): {
6
+ ArrowIcon: ({ size, ...props }: import("@snack-uikit/icons/dist/components/interface-icons/chevronUp").ISvgIconProps) => import("react/jsx-runtime").JSX.Element;
7
+ arrowIconSize: IconSize;
8
+ };
@@ -0,0 +1,5 @@
1
+ import { ChevronDownSVG, ChevronUpSVG } from '@snack-uikit/icons';
2
+ import { IconSize, Size } from '@snack-uikit/input-private';
3
+ export function getArrowIcon({ size, open }) {
4
+ return { ArrowIcon: open ? ChevronUpSVG : ChevronDownSVG, arrowIconSize: size === Size.S ? IconSize.Xs : IconSize.S };
5
+ }
@@ -0,0 +1,9 @@
1
+ import { Option, SelectionMode } from '../types';
2
+ export declare const getDisplayedValue: (props: {
3
+ selectionMode: SelectionMode.Single;
4
+ selected: Option;
5
+ } | {
6
+ selectionMode: SelectionMode.Multi;
7
+ selected: Option[];
8
+ getSelectedItemsText(amount: number): string;
9
+ }) => string;
@@ -0,0 +1,12 @@
1
+ import { SelectionMode } from '../types';
2
+ export const getDisplayedValue = (props) => {
3
+ if (props.selectionMode === SelectionMode.Single) {
4
+ return props.selected.label;
5
+ }
6
+ const { selected, getSelectedItemsText } = props;
7
+ const selectedOptions = selected;
8
+ if (selectedOptions.length > 1) {
9
+ return getSelectedItemsText(selectedOptions.length);
10
+ }
11
+ return selectedOptions.reduce((res, cur, index, arr) => `${res}${cur.label}${index === arr.length - 1 ? '' : ','}`, '');
12
+ };
@@ -0,0 +1,2 @@
1
+ export * from './getArrowIcon';
2
+ export * from './getDisplayedValue';
@@ -0,0 +1,2 @@
1
+ export * from './getArrowIcon';
2
+ export * from './getDisplayedValue';
@@ -0,0 +1,3 @@
1
+ export * from './useFilteredOptions';
2
+ export * from './useList';
3
+ export * from './useListNavigation';
@@ -0,0 +1,3 @@
1
+ export * from './useFilteredOptions';
2
+ export * from './useList';
3
+ export * from './useListNavigation';
@@ -0,0 +1,7 @@
1
+ import { Option } from '../types';
2
+ export declare function useFilteredOptions({ searchable, touched, inputValue, options, }: {
3
+ searchable: boolean;
4
+ touched: boolean;
5
+ inputValue: string;
6
+ options: Option[];
7
+ }): Option[];
@@ -0,0 +1,6 @@
1
+ import { useMemo } from 'react';
2
+ export function useFilteredOptions({ searchable, touched, inputValue, options, }) {
3
+ return useMemo(() => searchable && touched && inputValue
4
+ ? options.filter(item => item.label.toLowerCase().includes(inputValue.toLowerCase().trim()))
5
+ : options, [inputValue, options, searchable, touched]);
6
+ }
@@ -0,0 +1,36 @@
1
+ /// <reference types="react" />
2
+ import { FieldSelectProps } from '../FieldSelect';
3
+ import { Option } from '../types';
4
+ type UseListProps = Pick<FieldSelectProps, 'readonly' | 'disabled' | 'open' | 'onOpenChange' | 'options' | 'showCopyButton'> & {
5
+ searchable: NonNullable<FieldSelectProps['searchable']>;
6
+ showAdditionalButton: boolean;
7
+ inputValue: string;
8
+ setInputValue(value: string): void;
9
+ isChecked(option: Option): boolean;
10
+ };
11
+ export declare function useList({ open, onOpenChange, readonly, disabled, searchable, showAdditionalButton, showCopyButton: showCopyButtonProp, inputValue, setInputValue, options, isChecked, }: UseListProps): {
12
+ isOpen: boolean;
13
+ setIsOpen: (value: boolean) => void;
14
+ localRef: import("react").RefObject<HTMLInputElement>;
15
+ clearButtonRef: import("react").RefObject<HTMLButtonElement>;
16
+ showClearButton: boolean;
17
+ copyButtonRef: import("react").RefObject<HTMLButtonElement>;
18
+ showCopyButton: boolean;
19
+ extendedOptions: {
20
+ checked: boolean;
21
+ disabled?: boolean | undefined;
22
+ caption?: string | undefined;
23
+ icon?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
24
+ description?: string | undefined;
25
+ tagLabel?: string | undefined;
26
+ avatar?: Omit<import("@snack-uikit/avatar").AvatarProps, "size"> | undefined;
27
+ value: string;
28
+ label: string;
29
+ }[];
30
+ onInputKeyDown: import("react").KeyboardEventHandler<HTMLInputElement>;
31
+ onButtonKeyDown: (event: import("react").KeyboardEvent<Element>) => void;
32
+ onInputValueChange: (value: string) => void;
33
+ firstDroplistItemRefCallback: (element: HTMLButtonElement | null) => void;
34
+ onDroplistFocusLeave: (direction: string) => void;
35
+ };
36
+ export {};
@@ -0,0 +1,52 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { useUncontrolledProp } from 'uncontrollable';
3
+ import { useFilteredOptions } from './useFilteredOptions';
4
+ import { useListNavigation } from './useListNavigation';
5
+ export function useList({ open, onOpenChange, readonly, disabled, searchable, showAdditionalButton, showCopyButton: showCopyButtonProp, inputValue, setInputValue, options, isChecked, }) {
6
+ const touched = useRef(false);
7
+ const localRef = useRef(null);
8
+ const clearButtonRef = useRef(null);
9
+ const copyButtonRef = useRef(null);
10
+ const [isOpen, setIsOpen] = useUncontrolledProp(open, false, onOpenChange);
11
+ const showDropList = isOpen && !readonly && !disabled;
12
+ const showClearButton = !readonly && (showAdditionalButton || inputValue.length > 0);
13
+ const showCopyButton = Boolean(showAdditionalButton && showCopyButtonProp && readonly);
14
+ const { extendedOptions, onInputKeyDown, onButtonKeyDown, onDroplistFocusLeave, firstDroplistItemRefCallback } = useListNavigation({
15
+ inputRef: localRef,
16
+ options: useFilteredOptions({ searchable, options, touched: touched.current, inputValue }),
17
+ toggleListOpen: setIsOpen,
18
+ isChecked,
19
+ });
20
+ const handleOpenChange = (value) => {
21
+ if (!value) {
22
+ touched.current = false;
23
+ }
24
+ setIsOpen(value);
25
+ };
26
+ const handleInputValueChange = (value) => {
27
+ touched.current = true;
28
+ setIsOpen(true);
29
+ setInputValue(value);
30
+ };
31
+ useEffect(() => {
32
+ var _a;
33
+ if (open) {
34
+ (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
35
+ }
36
+ }, [localRef, open]);
37
+ return {
38
+ isOpen: showDropList,
39
+ setIsOpen: handleOpenChange,
40
+ localRef,
41
+ clearButtonRef,
42
+ showClearButton,
43
+ copyButtonRef,
44
+ showCopyButton,
45
+ extendedOptions,
46
+ onInputKeyDown,
47
+ onButtonKeyDown,
48
+ onInputValueChange: handleInputValueChange,
49
+ firstDroplistItemRefCallback,
50
+ onDroplistFocusLeave,
51
+ };
52
+ }
@@ -0,0 +1,26 @@
1
+ import { KeyboardEvent, KeyboardEventHandler, RefObject } from 'react';
2
+ import { Option } from '../types';
3
+ type UseListNavigationProps = {
4
+ options: Option[];
5
+ toggleListOpen(value: boolean): void;
6
+ inputRef: RefObject<HTMLInputElement>;
7
+ isChecked(option: Option): boolean;
8
+ };
9
+ export declare function useListNavigation({ options, toggleListOpen, inputRef, isChecked }: UseListNavigationProps): {
10
+ onInputKeyDown: KeyboardEventHandler<HTMLInputElement>;
11
+ onButtonKeyDown: (event: KeyboardEvent) => void;
12
+ onDroplistFocusLeave: (direction: string) => void;
13
+ extendedOptions: {
14
+ checked: boolean;
15
+ disabled?: boolean | undefined;
16
+ caption?: string | undefined;
17
+ icon?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
18
+ description?: string | undefined;
19
+ tagLabel?: string | undefined;
20
+ avatar?: Omit<import("@snack-uikit/avatar").AvatarProps, "size"> | undefined;
21
+ value: string;
22
+ label: string;
23
+ }[];
24
+ firstDroplistItemRefCallback: (element: HTMLButtonElement | null) => void;
25
+ };
26
+ export {};
@@ -0,0 +1,48 @@
1
+ import { useCallback, useMemo, useRef } from 'react';
2
+ import { moveCursorToEnd, runAfterRerender } from '@snack-uikit/input-private';
3
+ export function useListNavigation({ options, toggleListOpen, inputRef, isChecked }) {
4
+ const setInputFocus = useCallback(() => {
5
+ runAfterRerender(() => {
6
+ var _a;
7
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
8
+ moveCursorToEnd(inputRef.current);
9
+ });
10
+ }, [inputRef]);
11
+ const firstDroplistItemRef = useRef(null);
12
+ const firstDroplistItemRefCallback = useCallback((element) => {
13
+ firstDroplistItemRef.current = element;
14
+ }, [firstDroplistItemRef]);
15
+ const setOptionFocus = useCallback(() => {
16
+ runAfterRerender(() => { var _a; return (_a = firstDroplistItemRef.current) === null || _a === void 0 ? void 0 : _a.focus(); });
17
+ }, [firstDroplistItemRef]);
18
+ const leaveElement = (event) => {
19
+ if (event.key === 'ArrowDown') {
20
+ event.preventDefault();
21
+ toggleListOpen(true);
22
+ setOptionFocus();
23
+ }
24
+ if (event.key === 'Tab') {
25
+ toggleListOpen(false);
26
+ }
27
+ };
28
+ const handleInputKeyDown = event => {
29
+ leaveElement(event);
30
+ if (event.key === 'Enter') {
31
+ toggleListOpen(true);
32
+ setOptionFocus();
33
+ }
34
+ };
35
+ const onDroplistFocusLeave = useCallback((direction) => {
36
+ if (['top', 'common'].includes(direction)) {
37
+ setInputFocus();
38
+ }
39
+ }, [setInputFocus]);
40
+ const extendedOptions = useMemo(() => options.map(option => (Object.assign(Object.assign({}, option), { checked: isChecked(option) }))), [isChecked, options]);
41
+ return {
42
+ onInputKeyDown: handleInputKeyDown,
43
+ onButtonKeyDown: leaveElement,
44
+ onDroplistFocusLeave,
45
+ extendedOptions,
46
+ firstDroplistItemRefCallback,
47
+ };
48
+ }
@@ -0,0 +1 @@
1
+ export * from './FieldSelect';
@@ -0,0 +1 @@
1
+ export * from './FieldSelect';
@@ -0,0 +1,74 @@
1
+ .triggerClassName{
2
+ --offset:var(--space-drop-list-drop-offset, 4px);
3
+ width:100%;
4
+ }
5
+
6
+ .scrollContainerS{
7
+ max-height:256px;
8
+ }
9
+
10
+ .scrollContainerM{
11
+ max-height:320px;
12
+ }
13
+
14
+ .scrollContainerL{
15
+ max-height:384px;
16
+ }
17
+
18
+ .displayValue{
19
+ pointer-events:none;
20
+ position:absolute;
21
+ top:0;
22
+ left:0;
23
+ overflow:hidden;
24
+ display:flex;
25
+ align-items:center;
26
+ box-sizing:border-box;
27
+ height:100%;
28
+ background-color:inherit;
29
+ border:none;
30
+ outline:none;
31
+ }
32
+
33
+ .container{
34
+ flex:1 1 0;
35
+ }
36
+ .container[data-size=s] .arrowIcon{
37
+ width:var(--dimension-2m, 16px) !important;
38
+ height:var(--dimension-2m, 16px) !important;
39
+ color:var(--sys-neutral-text-light, #898989);
40
+ }
41
+ .container[data-size=s][data-variant=single-line-container] .displayValue{
42
+ width:calc(100% - (var(--space-fields-single-line-container-s-right, 6px) + var(--space-fields-single-line-container-s-gap, 4px) + calc(var(var(--space-fields-postfix-gap, 4px)) + var(--dimension-2m, 16px) * 2)));
43
+ margin-right:calc(var(--space-fields-single-line-container-s-right, 6px) + var(--space-fields-single-line-container-s-gap, 4px) + calc(var(var(--space-fields-postfix-gap, 4px)) + var(--dimension-2m, 16px) * 2));
44
+ padding-left:var(--space-fields-single-line-container-s-left, 6px);
45
+ border-radius:var(--radius-fields-s, 12px);
46
+ }
47
+ .container[data-size=m] .arrowIcon{
48
+ width:var(--dimension-3m, 24px) !important;
49
+ height:var(--dimension-3m, 24px) !important;
50
+ color:var(--sys-neutral-text-light, #898989);
51
+ }
52
+ .container[data-size=m][data-variant=single-line-container] .displayValue{
53
+ width:calc(100% - (var(--space-fields-single-line-container-m-right, 8px) + var(--space-fields-single-line-container-m-gap, 4px) + calc(var(var(--space-fields-postfix-gap, 4px)) + var(--dimension-3m, 24px) * 2)));
54
+ margin-right:calc(var(--space-fields-single-line-container-m-right, 8px) + var(--space-fields-single-line-container-m-gap, 4px) + calc(var(var(--space-fields-postfix-gap, 4px)) + var(--dimension-3m, 24px) * 2));
55
+ padding-left:var(--space-fields-single-line-container-m-left, 8px);
56
+ border-radius:var(--radius-fields-m, 14px);
57
+ }
58
+ .container[data-size=l] .arrowIcon{
59
+ width:var(--dimension-3m, 24px) !important;
60
+ height:var(--dimension-3m, 24px) !important;
61
+ color:var(--sys-neutral-text-light, #898989);
62
+ }
63
+ .container[data-size=l][data-variant=single-line-container] .displayValue{
64
+ width:calc(100% - (var(--space-fields-single-line-container-l-right, 10px) + var(--space-fields-single-line-container-l-gap, 8px) + calc(var(var(--space-fields-postfix-gap, 4px)) + var(--dimension-3m, 24px) * 2)));
65
+ margin-right:calc(var(--space-fields-single-line-container-l-right, 10px) + var(--space-fields-single-line-container-l-gap, 8px) + calc(var(var(--space-fields-postfix-gap, 4px)) + var(--dimension-3m, 24px) * 2));
66
+ padding-left:var(--space-fields-single-line-container-l-left, 10px);
67
+ border-radius:var(--radius-fields-l, 16px);
68
+ }
69
+ .container:hover .arrowIcon, .container:focus-within .arrowIcon, .container[data-focused] .arrowIcon{
70
+ color:var(--sys-neutral-text-support, #565656);
71
+ }
72
+ .container[data-disabled] .arrowIcon, .container[data-readonly] .arrowIcon{
73
+ color:var(--sys-neutral-text-disabled, #9e9e9e);
74
+ }
@@ -0,0 +1,53 @@
1
+ import { ReactElement } from 'react';
2
+ import { ItemSingleProps } from '@snack-uikit/droplist';
3
+ import { InputPrivateProps } from '@snack-uikit/input-private';
4
+ import { WithSupportProps } from '@snack-uikit/utils';
5
+ import { FieldDecoratorProps } from '../FieldDecorator';
6
+ export declare enum SelectionMode {
7
+ Single = "single",
8
+ Multi = "multi"
9
+ }
10
+ export type Option = Pick<ItemSingleProps, 'caption' | 'description' | 'tagLabel' | 'icon' | 'avatar' | 'disabled'> & {
11
+ value: string;
12
+ label: string;
13
+ };
14
+ export type ExtendedOption = Option & {
15
+ checked: boolean;
16
+ };
17
+ type InputProps = Pick<InputPrivateProps, 'id' | 'name' | 'placeholder' | 'disabled' | 'readonly' | 'onFocus' | 'onBlur'>;
18
+ type WrapperProps = Pick<FieldDecoratorProps, 'className' | 'label' | 'labelTooltip' | 'required' | 'hint' | 'showHintIcon' | 'size' | 'validationState' | 'labelTooltipPlacement'>;
19
+ type FieldSelectOwnProps = {
20
+ /** Массив опций выпадающего списка */
21
+ options: Option[];
22
+ /** Открыт ли выпадающий список */
23
+ open?: boolean;
24
+ /** Колбек открытия выпадающего списка */
25
+ onOpenChange?(value: boolean): void;
26
+ /** Можно ли искать опции внутри списка */
27
+ searchable?: boolean;
28
+ /** Показывать ли кнопку Копировать для поля (актуально только для readonly = true) */
29
+ showCopyButton?: boolean;
30
+ /** Иконка-префикс для поля */
31
+ prefixIcon?: ReactElement;
32
+ /** Текст отсутствия доступных значений */
33
+ noDataText?: string;
34
+ /** Текущая локаль */
35
+ locale?: Intl.Locale;
36
+ };
37
+ export type FieldSelectBaseProps = FieldSelectOwnProps & InputProps & WrapperProps;
38
+ type SingleModeProps = {
39
+ /** Выбранное значение: <br> - одно для single mode */
40
+ value?: Option['value'];
41
+ /** Колбек смены значения */
42
+ onChange?(value: Option['value']): void;
43
+ };
44
+ type MultiModeProps = {
45
+ /** <br> - массив для multi mode */
46
+ value?: Option['value'][];
47
+ onChange?(value: Option['value'][]): void;
48
+ /** Колбек формирования текста */
49
+ getSelectedItemsText?(amount: number): string;
50
+ };
51
+ export type FieldSelectSingleProps = WithSupportProps<FieldSelectBaseProps & SingleModeProps>;
52
+ export type FieldSelectMultiProps = WithSupportProps<FieldSelectBaseProps & MultiModeProps>;
53
+ export {};
@@ -0,0 +1,5 @@
1
+ export var SelectionMode;
2
+ (function (SelectionMode) {
3
+ SelectionMode["Single"] = "single";
4
+ SelectionMode["Multi"] = "multi";
5
+ })(SelectionMode || (SelectionMode = {}));
@@ -0,0 +1,25 @@
1
+ import { ReactElement } from 'react';
2
+ import { InputPrivateProps, Size } from '@snack-uikit/input-private';
3
+ import { Tooltip } from '@snack-uikit/tooltip';
4
+ import { WithSupportProps } from '@snack-uikit/utils';
5
+ import { ValidationState } from '../../constants';
6
+ import { FieldDecoratorProps } from '../FieldDecorator';
7
+ type InputProps = Pick<Partial<InputPrivateProps>, 'value' | 'onChange'> & Pick<InputPrivateProps, 'id' | 'name' | 'placeholder' | 'maxLength' | 'disabled' | 'readonly' | 'onFocus' | 'onBlur'>;
8
+ type WrapperProps = Pick<FieldDecoratorProps, 'className' | 'label' | 'labelTooltip' | 'required' | 'hint' | 'showHintIcon' | 'size' | 'validationState' | 'labelTooltipPlacement'>;
9
+ type FieldTextOwnProps = {
10
+ /** Показывать ли кнопку Копировать для поля (актуально только для `readonly = true`) */
11
+ showCopyButton?: boolean;
12
+ /** Можно ли вводить больше разрешённого кол-ва символов */
13
+ allowMoreThanMaxLength?: boolean;
14
+ /** Иконка-префикс для поля */
15
+ prefixIcon?: ReactElement;
16
+ };
17
+ export type FieldTextProps = WithSupportProps<FieldTextOwnProps & InputProps & WrapperProps>;
18
+ export declare const FieldText: import("react").ForwardRefExoticComponent<{
19
+ 'data-test-id'?: string | undefined;
20
+ } & import("react").AriaAttributes & FieldTextOwnProps & Pick<Partial<InputPrivateProps>, "value" | "onChange"> & Pick<InputPrivateProps, "disabled" | "readonly" | "name" | "placeholder" | "id" | "maxLength" | "onFocus" | "onBlur"> & WrapperProps & import("react").RefAttributes<HTMLInputElement>> & {
21
+ sizes: typeof Size;
22
+ validationStates: typeof ValidationState;
23
+ labelTooltipPlacements: typeof Tooltip.placements;
24
+ };
25
+ export {};