@hh.ru/magritte-ui-chips-input 1.1.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.
@@ -0,0 +1,3 @@
1
+ import { InputHTMLAttributes } from 'react';
2
+ import { ChipsInputProps } from '@hh.ru/magritte-ui-chips-input/types';
3
+ export declare const ChipsInput: import("react").ForwardRefExoticComponent<ChipsInputProps & Omit<InputHTMLAttributes<HTMLInputElement>, keyof ChipsInputProps> & import("react").RefAttributes<HTMLInputElement>>;
package/ChipsInput.js ADDED
@@ -0,0 +1,122 @@
1
+ import './index.css';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useState, useRef, useCallback, useEffect } from 'react';
4
+ import classnames from 'classnames';
5
+ import { keyboardMatch, keyboardKeys, findNextFocusableElement } from '@hh.ru/magritte-common-keyboard';
6
+ import { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';
7
+ import { CustomChip } from '@hh.ru/magritte-ui-chips';
8
+ import { FormHelper } from '@hh.ru/magritte-ui-form-helper';
9
+ import { ChevronDownOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';
10
+ import { useFocus } from '@hh.ru/magritte-ui-input/useFocus';
11
+
12
+ var styles = {"root":"magritte-root___1YkGM_1-1-0","focused":"magritte-focused___dy9eY_1-1-0","invalid":"magritte-invalid___RJHLG_1-1-0","disabled":"magritte-disabled___hD00s_1-1-0","field":"magritte-field___IMwTW_1-1-0","focus-visible":"magritte-focus-visible___wdNv6_1-1-0","focusVisible":"magritte-focus-visible___wdNv6_1-1-0","large":"magritte-large___OjLba_1-1-0","icon":"magritte-icon___7eYOG_1-1-0","medium":"magritte-medium___SSyhM_1-1-0","scrollable-area":"magritte-scrollable-area___7XKlY_1-1-0","scrollableArea":"magritte-scrollable-area___7XKlY_1-1-0","chips-and-input":"magritte-chips-and-input___wx6To_1-1-0","chipsAndInput":"magritte-chips-and-input___wx6To_1-1-0","icon_expanded":"magritte-icon_expanded___PtihN_1-1-0","iconExpanded":"magritte-icon_expanded___PtihN_1-1-0"};
13
+
14
+ const focusOnLastChip = (event, chipsContainer, input) => {
15
+ if (!chipsContainer || !input) {
16
+ return;
17
+ }
18
+ const nextFocusableElement = findNextFocusableElement(chipsContainer, input, 'left', 'list');
19
+ if (nextFocusableElement !== null) {
20
+ event.preventDefault();
21
+ nextFocusableElement.focus();
22
+ }
23
+ };
24
+ const ChipsInput = forwardRef(({ size = 'large', placeholder, disabled, state, invalid, maxHeight, description, errorMessage, wrapperRef, onChange, onFocus, onBlur, onKeyDown, onChangeInput: onChangeInputExternal, }, ref) => {
25
+ const [expanded, setExpanded] = useState(false);
26
+ const [isFocusVisible, setFocusVisible] = useState(false);
27
+ const chipsRootRef = useRef(null);
28
+ const chipsRootRefCallback = useMultipleRefs(wrapperRef, chipsRootRef);
29
+ const chipsContainerRef = useRef(null);
30
+ const inputRef = useRef(null);
31
+ const inputRefCallback = useMultipleRefs(ref, inputRef);
32
+ const onChangeInput = useCallback((value) => {
33
+ onChange({
34
+ value,
35
+ chips: state.chips,
36
+ eventType: 'changeInputValue',
37
+ });
38
+ onChangeInputExternal?.(value);
39
+ }, [state.chips, onChange, onChangeInputExternal]);
40
+ const { changeHandler, focusHandler, blurHandler, isFocused } = useFocus(onChangeInput, onFocus, onBlur);
41
+ useEffect(() => {
42
+ if (inputRef.current) {
43
+ setFocusVisible(isFocused && inputRef.current.classList.contains('focus-visible'));
44
+ }
45
+ }, [isFocused]);
46
+ const deleteHandler = useCallback((index) => {
47
+ state.chips.splice(index, 1);
48
+ onChange({
49
+ value: state.value,
50
+ chips: [...state.chips],
51
+ eventType: 'removeChipByCross',
52
+ });
53
+ // не теряем фокус с инпута
54
+ inputRef.current?.focus();
55
+ }, [onChange, state.chips, state.value]);
56
+ const keyDownHandler = useCallback((event) => {
57
+ // создаем новый чипс и затираем текстовый инпут
58
+ if (keyboardMatch(event.nativeEvent, keyboardKeys.Enter)) {
59
+ if (state.value.length === 0) {
60
+ return;
61
+ }
62
+ onChange({
63
+ value: '',
64
+ chips: [...state.chips, state.value],
65
+ eventType: 'addChipByEnter',
66
+ });
67
+ onChangeInputExternal?.('');
68
+ }
69
+ // удаляем последний созданный чипс
70
+ if (state.value === '' && keyboardMatch(event.nativeEvent, keyboardKeys.Backspace)) {
71
+ state.chips.pop();
72
+ onChange({
73
+ value: state.value,
74
+ chips: [...state.chips],
75
+ eventType: 'removeChipByBackspace',
76
+ });
77
+ }
78
+ // пытаемся найти ближайший чипс для фокуса
79
+ if (state.value === '' && keyboardMatch(event.nativeEvent, keyboardKeys.ArrowLeft)) {
80
+ focusOnLastChip(event, chipsContainerRef.current, inputRef.current);
81
+ }
82
+ }, [onChange, onChangeInputExternal, state]);
83
+ // при выставлении высоты учитваем падинги
84
+ // иначе высота будет больше значения свойства
85
+ const scrollableAreaStyle = maxHeight
86
+ ? {
87
+ maxHeight: `${maxHeight - (size === 'medium' ? 16 : 24)}px`,
88
+ }
89
+ : undefined;
90
+ return (jsxs(Fragment, { children: [jsxs("div", { ref: chipsRootRefCallback, className: classnames(styles.root, styles[size], {
91
+ [styles.focused]: isFocused,
92
+ [styles.focusVisible]: isFocusVisible,
93
+ [styles.disabled]: !!disabled,
94
+ [styles.invalid]: !!invalid,
95
+ }), onFocus: () => {
96
+ if (disabled) {
97
+ return;
98
+ }
99
+ if (!inputRef.current) {
100
+ return;
101
+ }
102
+ setExpanded(true);
103
+ // добавляем .focus() еще и тут
104
+ // чтобы не сбрасывать фокус во время клика по chip
105
+ // или по клику на враппер
106
+ if (document.activeElement === chipsRootRef.current) {
107
+ inputRef.current.focus();
108
+ }
109
+ }, onBlur: () => {
110
+ setExpanded(false);
111
+ }, onKeyDown: onKeyDown, tabIndex: disabled ? -1 : 0, children: [jsx("div", { style: scrollableAreaStyle, className: styles.scrollableArea, children: jsxs("div", { ref: chipsContainerRef, className: styles.chipsAndInput, children: [state.chips.map((chip, index) => {
112
+ return (jsx(CustomChip, { Element: "button", size: "small", disabled: disabled, onDelete: () => {
113
+ deleteHandler(index);
114
+ }, children: chip }, `${chip}-${index}`));
115
+ }), jsx("input", { ref: inputRefCallback, className: styles.field, type: "text", disabled: disabled, value: state.value, placeholder: state.chips.length === 0 ? placeholder : '', onKeyDown: keyDownHandler, onFocus: focusHandler, onBlur: blurHandler, onChange: changeHandler })] }) }), jsx("div", { className: classnames(styles.icon, {
116
+ [styles.iconExpanded]: expanded,
117
+ }), children: jsx(ChevronDownOutlinedSize24, {}) })] }), jsx(FormHelper, { description: description, errorMessage: errorMessage, disabled: disabled, invalid: invalid })] }));
118
+ });
119
+ ChipsInput.displayName = 'ChipsInput';
120
+
121
+ export { ChipsInput };
122
+ //# sourceMappingURL=ChipsInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChipsInput.js","sources":["../src/ChipsInput.tsx"],"sourcesContent":["import {\n forwardRef,\n InputHTMLAttributes,\n useState,\n useCallback,\n KeyboardEventHandler,\n useRef,\n SyntheticEvent,\n useEffect,\n} from 'react';\nimport classnames from 'classnames';\n\nimport { findNextFocusableElement, keyboardKeys, keyboardMatch } from '@hh.ru/magritte-common-keyboard';\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { CustomChip } from '@hh.ru/magritte-ui-chips';\nimport { ChipsInputProps } from '@hh.ru/magritte-ui-chips-input/types';\nimport { FormHelper } from '@hh.ru/magritte-ui-form-helper';\nimport { ChevronDownOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';\nimport { useFocus } from '@hh.ru/magritte-ui-input/useFocus';\n\nimport styles from './chips-input.less';\n\nconst focusOnLastChip = (event: SyntheticEvent, chipsContainer: HTMLElement | null, input: HTMLElement | null) => {\n if (!chipsContainer || !input) {\n return;\n }\n const nextFocusableElement = findNextFocusableElement(chipsContainer, input, 'left', 'list');\n if (nextFocusableElement !== null) {\n event.preventDefault();\n nextFocusableElement.focus();\n }\n};\n\nexport const ChipsInput = forwardRef<\n HTMLInputElement,\n ChipsInputProps & Omit<InputHTMLAttributes<HTMLInputElement>, keyof ChipsInputProps>\n>(\n (\n {\n size = 'large',\n placeholder,\n disabled,\n state,\n invalid,\n maxHeight,\n description,\n errorMessage,\n wrapperRef,\n onChange,\n onFocus,\n onBlur,\n onKeyDown,\n onChangeInput: onChangeInputExternal,\n },\n ref\n ) => {\n const [expanded, setExpanded] = useState(false);\n const [isFocusVisible, setFocusVisible] = useState(false);\n\n const chipsRootRef = useRef<HTMLDivElement>(null);\n const chipsRootRefCallback = useMultipleRefs(wrapperRef, chipsRootRef);\n const chipsContainerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const inputRefCallback = useMultipleRefs(ref, inputRef);\n\n const onChangeInput = useCallback(\n (value: string) => {\n onChange({\n value,\n chips: state.chips,\n eventType: 'changeInputValue',\n });\n onChangeInputExternal?.(value);\n },\n [state.chips, onChange, onChangeInputExternal]\n );\n const { changeHandler, focusHandler, blurHandler, isFocused } = useFocus(onChangeInput, onFocus, onBlur);\n\n useEffect(() => {\n if (inputRef.current) {\n setFocusVisible(isFocused && inputRef.current.classList.contains('focus-visible'));\n }\n }, [isFocused]);\n\n const deleteHandler = useCallback(\n (index: number) => {\n state.chips.splice(index, 1);\n onChange({\n value: state.value,\n chips: [...state.chips],\n eventType: 'removeChipByCross',\n });\n // не теряем фокус с инпута\n inputRef.current?.focus();\n },\n [onChange, state.chips, state.value]\n );\n\n const keyDownHandler = useCallback<KeyboardEventHandler>(\n (event) => {\n // создаем новый чипс и затираем текстовый инпут\n if (keyboardMatch(event.nativeEvent, keyboardKeys.Enter)) {\n if (state.value.length === 0) {\n return;\n }\n onChange({\n value: '',\n chips: [...state.chips, state.value],\n eventType: 'addChipByEnter',\n });\n onChangeInputExternal?.('');\n }\n // удаляем последний созданный чипс\n if (state.value === '' && keyboardMatch(event.nativeEvent, keyboardKeys.Backspace)) {\n state.chips.pop();\n onChange({\n value: state.value,\n chips: [...state.chips],\n eventType: 'removeChipByBackspace',\n });\n }\n // пытаемся найти ближайший чипс для фокуса\n if (state.value === '' && keyboardMatch(event.nativeEvent, keyboardKeys.ArrowLeft)) {\n focusOnLastChip(event, chipsContainerRef.current, inputRef.current);\n }\n },\n [onChange, onChangeInputExternal, state]\n );\n\n // при выставлении высоты учитваем падинги\n // иначе высота будет больше значения свойства\n const scrollableAreaStyle = maxHeight\n ? {\n maxHeight: `${maxHeight - (size === 'medium' ? 16 : 24)}px`,\n }\n : undefined;\n\n return (\n <>\n <div\n ref={chipsRootRefCallback}\n className={classnames(styles.root, styles[size], {\n [styles.focused]: isFocused,\n [styles.focusVisible]: isFocusVisible,\n [styles.disabled]: !!disabled,\n [styles.invalid]: !!invalid,\n })}\n onFocus={() => {\n if (disabled) {\n return;\n }\n if (!inputRef.current) {\n return;\n }\n setExpanded(true);\n // добавляем .focus() еще и тут\n // чтобы не сбрасывать фокус во время клика по chip\n // или по клику на враппер\n if (document.activeElement === chipsRootRef.current) {\n inputRef.current.focus();\n }\n }}\n onBlur={() => {\n setExpanded(false);\n }}\n onKeyDown={onKeyDown}\n tabIndex={disabled ? -1 : 0}\n >\n <div style={scrollableAreaStyle} className={styles.scrollableArea}>\n <div ref={chipsContainerRef} className={styles.chipsAndInput}>\n {state.chips.map((chip, index) => {\n return (\n <CustomChip\n Element=\"button\"\n key={`${chip}-${index}`}\n size=\"small\"\n disabled={disabled}\n onDelete={() => {\n deleteHandler(index);\n }}\n >\n {chip}\n </CustomChip>\n );\n })}\n <input\n ref={inputRefCallback}\n className={styles.field}\n type=\"text\"\n disabled={disabled}\n value={state.value}\n placeholder={state.chips.length === 0 ? placeholder : ''}\n onKeyDown={keyDownHandler}\n onFocus={focusHandler}\n onBlur={blurHandler}\n onChange={changeHandler}\n />\n </div>\n </div>\n <div\n className={classnames(styles.icon, {\n [styles.iconExpanded]: expanded,\n })}\n >\n <ChevronDownOutlinedSize24 />\n </div>\n </div>\n <FormHelper\n description={description}\n errorMessage={errorMessage}\n disabled={disabled}\n invalid={invalid}\n />\n </>\n );\n }\n);\n\nChipsInput.displayName = 'ChipsInput';\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":"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"}
package/index.css ADDED
@@ -0,0 +1,207 @@
1
+ :root{
2
+ --magritte-color-component-input-stroke-state-field-hovered-v19-0-0:#CCD5DF;
3
+ --magritte-color-component-input-stroke-state-field-focused-v19-0-0:#0070ff;
4
+ --magritte-color-component-input-stroke-state-accent-focused-accessible-v19-0-0:#0070ff7a;
5
+ --magritte-color-component-input-stroke-state-field-invalid-v19-0-0:#ff4d3a;
6
+ --magritte-color-component-input-stroke-state-negative-focused-accessible-v19-0-0:#ff4d3a7a;
7
+ --magritte-color-component-input-stroke-state-field-disabled-v19-0-0:#EEF1F7;
8
+ --magritte-color-component-input-background-field-v19-0-0:#ffffff;
9
+ --magritte-color-component-input-background-state-field-hovered-v19-0-0:#ffffff;
10
+ --magritte-color-component-input-background-state-field-focused-v19-0-0:#ffffff;
11
+ --magritte-color-component-input-background-state-field-invalid-v19-0-0:#ffffff;
12
+ --magritte-color-component-input-background-state-field-disabled-v19-0-0:#F4F6FB;
13
+ --magritte-color-component-input-stroke-field-v19-0-0:#DCE3EB;
14
+ --magritte-color-component-input-text-state-placeholder-disabled-v19-0-0:#AABBCA;
15
+ --magritte-color-component-input-text-state-placeholder-hovered-v19-0-0:#768694;
16
+ --magritte-color-component-input-text-state-placeholder-focused-v19-0-0:#AABBCA;
17
+ --magritte-color-component-input-text-state-placeholder-invalid-v19-0-0:#AABBCA;
18
+ --magritte-color-component-input-icon-content-v19-0-0:#6a7885;
19
+ --magritte-color-component-input-icon-state-content-hovered-v19-0-0:#6a7885;
20
+ --magritte-color-component-input-icon-state-content-focused-v19-0-0:#000000;
21
+ --magritte-color-component-input-icon-state-content-invalid-v19-0-0:#6a7885;
22
+ --magritte-color-component-input-icon-state-content-disabled-v19-0-0:#AABBCA;
23
+ --magritte-color-component-input-icon-state-chevron-focused-v19-0-0:#000000;
24
+ --magritte-color-component-input-text-placeholder-v19-0-0:#AABBCA;
25
+ --magritte-color-component-input-chips-background-state-neutral-disable-v19-0-0:#DCE3EB;
26
+ --magritte-color-component-input-chips-text-state-neutral-disable-v19-0-0:#96aabb;
27
+ }
28
+ :root{
29
+ --magritte-typography-label-2-regular-font-family-v19-0-0:"Inter";
30
+ --magritte-typography-label-2-regular-font-weight-v19-0-0:400;
31
+ --magritte-typography-label-2-regular-line-height-v19-0-0:22px;
32
+ --magritte-typography-label-2-regular-font-size-v19-0-0:16px;
33
+ --magritte-typography-label-2-regular-letter-spacing-v19-0-0:0em;
34
+ --magritte-typography-label-2-regular-text-indent-v19-0-0:0px;
35
+ --magritte-typography-label-2-regular-text-transform-v19-0-0:none;
36
+ --magritte-typography-label-2-regular-text-decoration-v19-0-0:none;
37
+ --magritte-semantic-animation-ease-in-out-100-timing-function-v19-0-0:cubic-bezier(0.25, 0.1, 0.25, 1);
38
+ --magritte-semantic-animation-ease-in-out-100-duration-v19-0-0:100ms;
39
+ --magritte-static-space-100-v19-0-0:4px;
40
+ --magritte-static-space-200-v19-0-0:8px;
41
+ --magritte-static-space-300-v19-0-0:12px;
42
+ --magritte-static-space-400-v19-0-0:16px;
43
+ --magritte-core-border-radius-3-x-v19-0-0:12px;
44
+ }
45
+ .magritte-night-theme{
46
+ --magritte-color-component-input-stroke-state-field-hovered-v19-0-0:#3B3B3B;
47
+ --magritte-color-component-input-stroke-state-field-focused-v19-0-0:#0070ff;
48
+ --magritte-color-component-input-stroke-state-accent-focused-accessible-v19-0-0:#0070ff7a;
49
+ --magritte-color-component-input-stroke-state-field-invalid-v19-0-0:#ff4d3a;
50
+ --magritte-color-component-input-stroke-state-negative-focused-accessible-v19-0-0:#ff4d3a7a;
51
+ --magritte-color-component-input-stroke-state-field-disabled-v19-0-0:#111;
52
+ --magritte-color-component-input-background-field-v19-0-0:#1B1B1B;
53
+ --magritte-color-component-input-background-state-field-hovered-v19-0-0:#1B1B1B;
54
+ --magritte-color-component-input-background-state-field-focused-v19-0-0:#1B1B1B;
55
+ --magritte-color-component-input-background-state-field-invalid-v19-0-0:#1B1B1B;
56
+ --magritte-color-component-input-background-state-field-disabled-v19-0-0:#111;
57
+ --magritte-color-component-input-stroke-field-v19-0-0:#303030;
58
+ --magritte-color-component-input-text-placeholder-v19-0-0:#535353;
59
+ --magritte-color-component-input-text-state-placeholder-disabled-v19-0-0:#474747;
60
+ --magritte-color-component-input-text-state-placeholder-hovered-v19-0-0:#5E5E5E;
61
+ --magritte-color-component-input-text-state-placeholder-focused-v19-0-0:#535353;
62
+ --magritte-color-component-input-text-state-placeholder-invalid-v19-0-0:#535353;
63
+ --magritte-color-component-input-icon-state-content-hovered-v19-0-0:#5E5E5E;
64
+ --magritte-color-component-input-icon-state-content-focused-v19-0-0:#ffffff;
65
+ --magritte-color-component-input-icon-state-content-invalid-v19-0-0:#767676;
66
+ --magritte-color-component-input-icon-state-content-disabled-v19-0-0:#474747;
67
+ --magritte-color-component-input-icon-state-chevron-focused-v19-0-0:#ffffff;
68
+ --magritte-color-component-input-icon-content-v19-0-0:#ABABAB;
69
+ --magritte-color-component-input-chips-background-state-neutral-disable-v19-0-0:#1B1B1B;
70
+ --magritte-color-component-input-chips-text-state-neutral-disable-v19-0-0:#474747;
71
+ }
72
+ .magritte-root___1YkGM_1-1-0{
73
+ display:inline-flex;
74
+ position:relative;
75
+ width:100%;
76
+ box-sizing:border-box;
77
+ user-select:none;
78
+ white-space:nowrap;
79
+ appearance:none;
80
+ overflow-y:auto;
81
+ background-color:var(--magritte-color-component-input-background-field-v19-0-0);
82
+ box-shadow:inset 0 0 0 1px var(--magritte-color-component-input-stroke-field-v19-0-0);
83
+ border-radius:var(--magritte-core-border-radius-3-x-v19-0-0);
84
+ --magritte-ui-icon-color-override:var(--magritte-color-component-input-icon-content-v19-0-0);
85
+ }
86
+ @media (min-width: 1020px){
87
+ body.magritte-old-layout .magritte-root___1YkGM_1-1-0:not(.magritte-focused___dy9eY_1-1-0):not(.magritte-invalid___RJHLG_1-1-0):not(.magritte-disabled___hD00s_1-1-0):hover{
88
+ background-color:var(--magritte-color-component-input-background-state-field-hovered-v19-0-0);
89
+ box-shadow:inset 0 0 0 1px var(--magritte-color-component-input-stroke-state-field-hovered-v19-0-0);
90
+ --magritte-ui-icon-color-override:var(--magritte-color-component-input-icon-state-content-hovered-v19-0-0);
91
+ }
92
+ body.magritte-old-layout .magritte-root___1YkGM_1-1-0:not(.magritte-focused___dy9eY_1-1-0):not(.magritte-invalid___RJHLG_1-1-0):not(.magritte-disabled___hD00s_1-1-0):hover .magritte-field___IMwTW_1-1-0::placeholder{
93
+ color:var(--magritte-color-component-input-text-state-placeholder-hovered-v19-0-0);
94
+ }
95
+ }
96
+ @media (min-width: 1024px){
97
+ body:not(.magritte-old-layout) .magritte-root___1YkGM_1-1-0:not(.magritte-focused___dy9eY_1-1-0):not(.magritte-invalid___RJHLG_1-1-0):not(.magritte-disabled___hD00s_1-1-0):hover{
98
+ background-color:var(--magritte-color-component-input-background-state-field-hovered-v19-0-0);
99
+ box-shadow:inset 0 0 0 1px var(--magritte-color-component-input-stroke-state-field-hovered-v19-0-0);
100
+ --magritte-ui-icon-color-override:var(--magritte-color-component-input-icon-state-content-hovered-v19-0-0);
101
+ }
102
+ body:not(.magritte-old-layout) .magritte-root___1YkGM_1-1-0:not(.magritte-focused___dy9eY_1-1-0):not(.magritte-invalid___RJHLG_1-1-0):not(.magritte-disabled___hD00s_1-1-0):hover .magritte-field___IMwTW_1-1-0::placeholder{
103
+ color:var(--magritte-color-component-input-text-state-placeholder-hovered-v19-0-0);
104
+ }
105
+ }
106
+ .magritte-root___1YkGM_1-1-0:not(.magritte-disabled___hD00s_1-1-0){
107
+ cursor:text;
108
+ }
109
+ .magritte-root___1YkGM_1-1-0.magritte-focused___dy9eY_1-1-0{
110
+ background-color:var(--magritte-color-component-input-background-state-field-focused-v19-0-0);
111
+ box-shadow:inset 0 0 0 2px var(--magritte-color-component-input-stroke-state-field-focused-v19-0-0);
112
+ --magritte-ui-icon-color-override:var(--magritte-color-component-input-icon-state-content-focused-v19-0-0);
113
+ }
114
+ .magritte-root___1YkGM_1-1-0.magritte-focused___dy9eY_1-1-0 .magritte-field___IMwTW_1-1-0::placeholder{
115
+ color:var(--magritte-color-component-input-text-state-placeholder-focused-v19-0-0);
116
+ }
117
+ .magritte-root___1YkGM_1-1-0.magritte-invalid___RJHLG_1-1-0{
118
+ background-color:var(--magritte-color-component-input-background-state-field-invalid-v19-0-0);
119
+ box-shadow:inset 0 0 0 1px var(--magritte-color-component-input-stroke-state-field-invalid-v19-0-0);
120
+ --magritte-ui-icon-color-override:var(--magritte-color-component-input-icon-state-content-invalid-v19-0-0);
121
+ }
122
+ .magritte-root___1YkGM_1-1-0.magritte-invalid___RJHLG_1-1-0 .magritte-field___IMwTW_1-1-0::placeholder{
123
+ color:var(--magritte-color-component-input-text-state-placeholder-invalid-v19-0-0);
124
+ }
125
+ .magritte-root___1YkGM_1-1-0.magritte-disabled___hD00s_1-1-0{
126
+ background-color:var(--magritte-color-component-input-background-state-field-disabled-v19-0-0);
127
+ box-shadow:inset 0 0 0 1px var(--magritte-color-component-input-stroke-state-field-disabled-v19-0-0);
128
+ --magritte-ui-icon-color-override:var(--magritte-color-component-input-icon-state-content-disabled-v19-0-0);
129
+ --magritte-ui-chip-text-color-override:var(--magritte-color-component-input-chips-text-state-neutral-disable-v19-0-0);
130
+ --magritte-ui-chip-background-color-override:var(--magritte-color-component-input-chips-background-state-neutral-disable-v19-0-0);
131
+ }
132
+ .magritte-root___1YkGM_1-1-0.magritte-disabled___hD00s_1-1-0 .magritte-field___IMwTW_1-1-0::placeholder{
133
+ color:var(--magritte-color-component-input-text-state-placeholder-disabled-v19-0-0);
134
+ }
135
+ .magritte-root___1YkGM_1-1-0.magritte-focus-visible___wdNv6_1-1-0{
136
+ outline:var(--magritte-color-component-input-stroke-state-accent-focused-accessible-v19-0-0) solid 4px;
137
+ }
138
+ .magritte-root___1YkGM_1-1-0.magritte-focus-visible___wdNv6_1-1-0.magritte-invalid___RJHLG_1-1-0{
139
+ outline-color:var(--magritte-color-component-input-stroke-state-negative-focused-accessible-v19-0-0);
140
+ }
141
+ .magritte-large___OjLba_1-1-0{
142
+ padding:var(--magritte-static-space-300-v19-0-0);
143
+ }
144
+ .magritte-large___OjLba_1-1-0 .magritte-field___IMwTW_1-1-0{
145
+ padding-left:var(--magritte-static-space-100-v19-0-0);
146
+ }
147
+ .magritte-large___OjLba_1-1-0 .magritte-icon___7eYOG_1-1-0{
148
+ top:var(--magritte-static-space-300-v19-0-0);
149
+ right:var(--magritte-static-space-400-v19-0-0);
150
+ }
151
+ .magritte-medium___SSyhM_1-1-0{
152
+ padding:var(--magritte-static-space-200-v19-0-0);
153
+ }
154
+ .magritte-medium___SSyhM_1-1-0 .magritte-field___IMwTW_1-1-0{
155
+ padding-left:var(--magritte-static-space-100-v19-0-0);
156
+ }
157
+ .magritte-medium___SSyhM_1-1-0 .magritte-icon___7eYOG_1-1-0{
158
+ top:var(--magritte-static-space-200-v19-0-0);
159
+ right:var(--magritte-static-space-300-v19-0-0);
160
+ }
161
+ .magritte-scrollable-area___7XKlY_1-1-0{
162
+ display:flex;
163
+ align-items:flex-start;
164
+ overflow-y:auto;
165
+ width:100%;
166
+ padding-right:24px;
167
+ }
168
+ .magritte-chips-and-input___wx6To_1-1-0{
169
+ display:flex;
170
+ gap:6px;
171
+ flex-wrap:wrap;
172
+ align-items:center;
173
+ width:100%;
174
+ margin-right:var(--magritte-static-space-300-v19-0-0);
175
+ }
176
+ .magritte-field___IMwTW_1-1-0{
177
+ border:0;
178
+ background:none;
179
+ flex-grow:1;
180
+ height:32px;
181
+ width:50px;
182
+ outline:none;
183
+ font-family:var(--magritte-typography-label-2-regular-font-family-v19-0-0);
184
+ font-weight:var(--magritte-typography-label-2-regular-font-weight-v19-0-0);
185
+ line-height:var(--magritte-typography-label-2-regular-line-height-v19-0-0);
186
+ font-size:var(--magritte-typography-label-2-regular-font-size-v19-0-0);
187
+ letter-spacing:var(--magritte-typography-label-2-regular-letter-spacing-v19-0-0);
188
+ text-indent:var(--magritte-typography-label-2-regular-text-indent-v19-0-0);
189
+ text-transform:var(--magritte-typography-label-2-regular-text-transform-v19-0-0);
190
+ text-decoration:var(--magritte-typography-label-2-regular-text-decoration-v19-0-0);
191
+ }
192
+ .magritte-field___IMwTW_1-1-0::placeholder{
193
+ color:var(--magritte-color-component-input-text-placeholder-v19-0-0);
194
+ }
195
+ .magritte-icon___7eYOG_1-1-0{
196
+ display:inline-flex;
197
+ margin-left:auto;
198
+ padding:var(--magritte-static-space-100-v19-0-0) 0;
199
+ position:absolute;
200
+ transition-property:transform;
201
+ transition-duration:var(--magritte-semantic-animation-ease-in-out-100-duration-v19-0-0);
202
+ transition-timing-function:var(--magritte-semantic-animation-ease-in-out-100-timing-function-v19-0-0);
203
+ }
204
+ .magritte-icon_expanded___PtihN_1-1-0{
205
+ transform:rotate(-180deg);
206
+ --magritte-ui-icon-color-override:var(--magritte-color-component-input-icon-state-chevron-focused-v19-0-0);
207
+ }
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from '@hh.ru/magritte-ui-chips-input/ChipsInput';
2
+ export * from '@hh.ru/magritte-ui-chips-input/types';
package/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import './index.css';
2
+ export { ChipsInput } from './ChipsInput.js';
3
+ import 'react/jsx-runtime';
4
+ import 'react';
5
+ import 'classnames';
6
+ import '@hh.ru/magritte-common-keyboard';
7
+ import '@hh.ru/magritte-common-use-multiple-refs';
8
+ import '@hh.ru/magritte-ui-chips';
9
+ import '@hh.ru/magritte-ui-form-helper';
10
+ import '@hh.ru/magritte-ui-icon/icon';
11
+ import '@hh.ru/magritte-ui-input/useFocus';
12
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@hh.ru/magritte-ui-chips-input",
3
+ "version": "1.1.0",
4
+ "main": "index.js",
5
+ "types": "index.d.ts",
6
+ "sideEffects": [
7
+ "index.css"
8
+ ],
9
+ "scripts": {
10
+ "build": "yarn root:build $(pwd)",
11
+ "build-test-branch": "yarn root:build-test-branch $(pwd)",
12
+ "changelog": "yarn root:changelog $(pwd)",
13
+ "prepack": "yarn root:prepack $(pwd)",
14
+ "postpublish": "yarn root:postpublish $(pwd)",
15
+ "stylelint-test": "yarn root:stylelint-test $(pwd)",
16
+ "eslint-test": "yarn root:eslint-test $(pwd)",
17
+ "ts-config": "yarn root:ts-config $(pwd)",
18
+ "ts-check": "yarn root:ts-check $(pwd)",
19
+ "test": "yarn root:test $(pwd)",
20
+ "watch": "yarn root:watch $(pwd)"
21
+ },
22
+ "peerDependencies": {
23
+ "classnames": ">=2.3.2",
24
+ "react": ">=18.2.0"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "dependencies": {
30
+ "@hh.ru/magritte-common-keyboard": "4.0.2",
31
+ "@hh.ru/magritte-common-use-multiple-refs": "1.1.4",
32
+ "@hh.ru/magritte-ui-chips": "5.2.14",
33
+ "@hh.ru/magritte-ui-form-helper": "1.0.9",
34
+ "@hh.ru/magritte-ui-icon": "7.8.1",
35
+ "@hh.ru/magritte-ui-input": "6.0.13"
36
+ },
37
+ "gitHead": "bf7f56dd64799c73041f10f1ddc88dd5658faa86"
38
+ }
package/types.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ import type { FocusEventHandler, ForwardedRef, ReactNode, KeyboardEventHandler } from 'react';
2
+ export type ChipsInputSize = 'medium' | 'large';
3
+ export type ChipsInputEventType = 'changeInputValue' | 'removeChipByCross' | 'addChipByEnter' | 'removeChipByBackspace';
4
+ export interface ChipsInputState {
5
+ value: string;
6
+ chips: string[];
7
+ eventType?: ChipsInputEventType;
8
+ }
9
+ export interface ChipsInputProps {
10
+ /** Размер для chips-input */
11
+ size?: ChipsInputSize;
12
+ /** Текст плейсхолдера */
13
+ placeholder?: string;
14
+ /** Флаг отключения инпута */
15
+ disabled?: boolean;
16
+ /** Признак невалидности */
17
+ invalid?: boolean;
18
+ /** Обработчик события изменения состояния компонента (chip+input) */
19
+ onChange: (state: ChipsInputState) => void;
20
+ /** Обработчик события изменения состояния input */
21
+ onChangeInput?: (value: string) => void;
22
+ /** Значение инпута */
23
+ state: ChipsInputState;
24
+ /** Обработчик события получения фокуса */
25
+ onFocus?: FocusEventHandler<HTMLInputElement>;
26
+ /** Обработчик события потери фокуса */
27
+ onBlur?: FocusEventHandler<HTMLInputElement>;
28
+ /** Обработчик события keydown */
29
+ onKeyDown?: KeyboardEventHandler<HTMLElement>;
30
+ /** Максимальная высота chips-input */
31
+ maxHeight?: number;
32
+ /** Текст подсказки под инпутом */
33
+ description?: ReactNode;
34
+ /** Текст сообщения об ошибке */
35
+ errorMessage?: ReactNode;
36
+ /** ref root контейнера */
37
+ wrapperRef?: ForwardedRef<HTMLElement>;
38
+ }
package/types.js ADDED
@@ -0,0 +1,3 @@
1
+ import './index.css';
2
+
3
+ //# sourceMappingURL=types.js.map
package/types.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}