@hh.ru/magritte-ui-suggest 7.0.9 → 8.0.1

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.
package/Suggest.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactElement, ForwardedRef } from 'react';
2
2
  import { SuggestProps, SuggestInputComponent } from '@hh.ru/magritte-ui-suggest/types';
3
- declare const Suggest: (<K, T extends SuggestInputComponent>(props: SuggestProps<K, T> & {
3
+ declare const Suggest: (<DataType, InputType extends SuggestInputComponent>(props: SuggestProps<DataType, InputType> & {
4
4
  ref?: ForwardedRef<HTMLElement>;
5
5
  }) => ReactElement | null) & {
6
6
  displayName: string;
package/Suggest.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import './index.css';
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
3
  import { forwardRef, useState, useRef, useCallback, useEffect } from 'react';
4
+ import { DataProviderError } from '@hh.ru/magritte-common-data-provider';
4
5
  import { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';
5
6
  import { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';
6
7
  import { getSearchResultCount, SuggestPicker } from './SuggestPicker.js';
7
- import { DataProviderError } from './dataProvider.js';
8
8
  import { useSuggestKeyboardNav } from './useSuggestKeyboardNav.js';
9
- import { s as styles } from './sectionRenderers-DUmKzPLp.js';
9
+ import { s as styles } from './sectionRenderers-DJgoxD4F.js';
10
10
  import 'classnames';
11
11
  import '@hh.ru/magritte-common-keyboard';
12
12
  import '@hh.ru/magritte-ui-bottom-sheet';
@@ -14,9 +14,6 @@ import '@hh.ru/magritte-ui-button';
14
14
  import '@hh.ru/magritte-ui-drop';
15
15
  import '@hh.ru/magritte-ui-icon/icon';
16
16
  import '@hh.ru/magritte-ui-navigation-bar';
17
- import 'axios';
18
- import '@hh.ru/magritte-common-func-utils';
19
- import '@hh.ru/magritte-common-fuzzy-search';
20
17
  import '@hh.ru/magritte-ui-card';
21
18
  import '@hh.ru/magritte-ui-cell';
22
19
  import '@hh.ru/magritte-ui-chips';
@@ -26,7 +23,7 @@ const SuggestTriggerDefault = (props) => {
26
23
  const { component: TriggerComponent, props: triggerProps } = props;
27
24
  return (jsx(TriggerComponent, { ...triggerProps }));
28
25
  };
29
- const SuggestComponent = function ({ dataProvider, input, inputValue, onSelectValidator = () => true, navigationBarProps, maxHeight = 460, itemsGap = 4, onBlur, topContent, bottomContent, dropWidth, errorPlaceholder, trls, onChange, onDropOpen, onDropClose, onBottomSheetOpen, onBottomSheetClose, onSearchSubmit, renderTrigger = SuggestTriggerDefault, }, ref) {
26
+ const SuggestComponent = function ({ dataProvider, input, inputValue, onSelectValidator = () => true, navigationBarProps, maxHeight = 460, itemsGap = 4, onBlur, topContent, bottomContent, dropWidth, errorPlaceholder, trls, onChange, onDropOpen, onDropClose, onBottomSheetOpen, onBottomSheetClose, onSearchSubmit, renderTrigger = SuggestTriggerDefault, renderItem, }, ref) {
30
27
  const { component: InputComponent, props: inputProps } = input;
31
28
  const [inputValueState, setInputValueState] = useState(inputProps.value || '');
32
29
  const { onChange: onInputChange, onFocus: onInputFocus, onKeyDown: onInputKeyDown } = inputProps;
@@ -119,7 +116,7 @@ const SuggestComponent = function ({ dataProvider, input, inputValue, onSelectVa
119
116
  autoComplete: 'off',
120
117
  },
121
118
  optionsCount: getSearchResultCount(requestResult?.result),
122
- }) }), jsx(SuggestPicker, { data: requestResult?.result, activatorRef: wrapperRef, inputRef: inputRef, inputFocused: focused, currentInputValueSelectedFromSuggest: valueSelectedFromSuggest !== false, onValueSelect: onValueSelectHandler, maxHeight: maxHeight, navigationBarProps: navigationBarProps, suggestContainerRef: suggestContainerRef, itemsGap: itemsGap, onBottomSheetClose: handleBottomSheetClose, onBottomSheetOpen: onBottomSheetOpen, onDropOpen: onDropOpen, onDropClose: onDropClose, inputValue: actualInputValue, topContent: topContent, bottomContent: bottomContent, dropWidth: dropWidth, isError: isError, trls: trls, errorPlaceholder: errorPlaceholder, onClickReload: () => {
119
+ }) }), jsx(SuggestPicker, { data: requestResult?.result, activatorRef: wrapperRef, inputRef: inputRef, inputFocused: focused, currentInputValueSelectedFromSuggest: valueSelectedFromSuggest !== false, onValueSelect: onValueSelectHandler, maxHeight: maxHeight, navigationBarProps: navigationBarProps, suggestContainerRef: suggestContainerRef, itemsGap: itemsGap, onBottomSheetClose: handleBottomSheetClose, onBottomSheetOpen: onBottomSheetOpen, onDropOpen: onDropOpen, onDropClose: onDropClose, inputValue: actualInputValue, topContent: topContent, bottomContent: bottomContent, dropWidth: dropWidth, isError: isError, trls: trls, errorPlaceholder: errorPlaceholder, renderItem: renderItem, onClickReload: () => {
123
120
  requestData(actualInputValue);
124
121
  }, onSearchSubmit: onSearchSubmit, input: {
125
122
  component: InputComponent,
package/Suggest.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Suggest.js","sources":["../src/Suggest.tsx"],"sourcesContent":["import {\n FocusEventHandler,\n ReactElement,\n useCallback,\n useEffect,\n useRef,\n useState,\n KeyboardEventHandler,\n forwardRef,\n ForwardedRef,\n} from 'react';\n\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { SuggestPicker, getSearchResultCount } from '@hh.ru/magritte-ui-suggest/SuggestPicker';\nimport { DataProviderError } from '@hh.ru/magritte-ui-suggest/dataProvider';\nimport {\n DataProviderRequest,\n DataProviderResult,\n SuggestProps,\n SuggestInputComponent,\n InputProp,\n ControlledInputProps,\n NativeFocusEventHandler,\n OptionsCount,\n} from '@hh.ru/magritte-ui-suggest/types';\nimport { useSuggestKeyboardNav } from '@hh.ru/magritte-ui-suggest/useSuggestKeyboardNav';\n\nimport styles from './suggest.less';\n\nconst SuggestTriggerDefault = <T extends SuggestInputComponent>(props: InputProp<T> & OptionsCount): ReactElement => {\n const { component: TriggerComponent, props: triggerProps } = props;\n return (\n <TriggerComponent\n {...(triggerProps as unknown as JSX.IntrinsicAttributes &\n JSX.LibraryManagedAttributes<T, ControlledInputProps>)}\n />\n );\n};\n\nconst SuggestComponent = function <K, T extends SuggestInputComponent>(\n {\n dataProvider,\n input,\n inputValue,\n onSelectValidator = () => true,\n navigationBarProps,\n maxHeight = 460,\n itemsGap = 4,\n onBlur,\n topContent,\n bottomContent,\n dropWidth,\n errorPlaceholder,\n trls,\n onChange,\n onDropOpen,\n onDropClose,\n onBottomSheetOpen,\n onBottomSheetClose,\n onSearchSubmit,\n renderTrigger = SuggestTriggerDefault,\n }: SuggestProps<K, T>,\n ref: ForwardedRef<HTMLElement>\n): ReactElement | null {\n const { component: InputComponent, props: inputProps } = input;\n const [inputValueState, setInputValueState] = useState(inputProps.value || '');\n const { onChange: onInputChange, onFocus: onInputFocus, onKeyDown: onInputKeyDown } = inputProps;\n const [requestResult, setRequestResult] = useState<{ query: string; result: DataProviderResult<K> } | null>(null);\n const [valueSelectedFromSuggest, setValueSelectedFromSuggest] = useState<string | false>(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const wrapperRef = useRef<HTMLElement>(null);\n const suggestContainerRef = useRef<HTMLElement>(null);\n const inputContainerRef = useRef<HTMLDivElement>(null);\n const inputRefMulti = useMultipleRefs(inputRef, ref);\n const onBlurRef = useRef<NativeFocusEventHandler | undefined>(onBlur);\n onBlurRef.current = onBlur; // update actual callback\n const { isMobile } = useBreakpoint();\n const [isError, setIsError] = useState(false);\n\n const currentRequestRef = useRef<DataProviderRequest>();\n const actualInputValue = inputValue === undefined ? inputValueState : inputValue;\n\n const { focused, onKeyDown, onFocus, ...rest } = useSuggestKeyboardNav(\n suggestContainerRef,\n inputContainerRef,\n setValueSelectedFromSuggest,\n actualInputValue,\n inputRef,\n onBlurRef\n );\n\n const handleBottomSheetClose = () => {\n rest.onBottomSheetClose();\n onBottomSheetClose?.();\n };\n\n const onChangeHandler = useCallback(\n (value: string, skipSuggestChangeHandler = false) => {\n if (inputValue === undefined) {\n setInputValueState(value);\n }\n !skipSuggestChangeHandler && onChange?.(value, false);\n onInputChange?.(value);\n },\n [inputValue, setInputValueState, onInputChange, onChange]\n );\n\n const requestData = useCallback(\n (query: string) => {\n setIsError(false);\n currentRequestRef.current?.cancel();\n const request = dataProvider(query);\n request.then(\n (result) => {\n setRequestResult({ query, result });\n },\n (event) => {\n // включаем error state если это НЕ ошибка, вызванная `minCharsCount` или отменненым запросом\n if (!(event instanceof DataProviderError)) {\n setIsError(true);\n }\n setRequestResult(null);\n }\n );\n currentRequestRef.current = request;\n },\n [dataProvider]\n );\n\n useEffect(() => {\n if (valueSelectedFromSuggest !== false && requestResult?.query !== actualInputValue) {\n setRequestResult(null);\n }\n if (valueSelectedFromSuggest !== actualInputValue.trim()) {\n setValueSelectedFromSuggest(false);\n if (focused) {\n requestData(actualInputValue);\n }\n }\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n }, [actualInputValue, requestData, focused]);\n\n const onFocusHandler = useCallback<FocusEventHandler<HTMLElement>>(\n (event) => {\n setValueSelectedFromSuggest(false);\n if (actualInputValue !== requestResult?.query) {\n setRequestResult(null);\n requestData(actualInputValue);\n }\n\n onInputFocus?.(event);\n onFocus(event);\n },\n [actualInputValue, requestResult?.query, onInputFocus, onFocus, requestData]\n );\n\n const onValueSelectHandler = useCallback(\n (value: string, data: K | undefined) => {\n if (!onSelectValidator(value, data)) {\n return;\n }\n if (!isMobile) {\n inputRef.current?.focus();\n }\n onChangeHandler(value, true);\n onChange?.(value, true, data);\n setValueSelectedFromSuggest(value);\n },\n [onSelectValidator, isMobile, onChangeHandler, onChange]\n );\n\n const onKeyDownHandler = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (event) => {\n onKeyDown(event);\n onInputKeyDown?.(event);\n },\n [onInputKeyDown, onKeyDown]\n );\n\n return (\n <>\n <div ref={inputContainerRef} className={styles.suggestInputContainer}>\n {renderTrigger({\n component: InputComponent,\n props: {\n ...inputProps,\n value: actualInputValue,\n onFocus: onFocusHandler,\n onChange: onChangeHandler,\n onKeyDown: onKeyDownHandler,\n ref: inputRefMulti,\n wrapperRef,\n autoComplete: 'off',\n },\n optionsCount: getSearchResultCount(requestResult?.result),\n } as unknown as InputProp<T> & OptionsCount)}\n </div>\n <SuggestPicker\n data={requestResult?.result}\n activatorRef={wrapperRef}\n inputRef={inputRef}\n inputFocused={focused}\n currentInputValueSelectedFromSuggest={valueSelectedFromSuggest !== false}\n onValueSelect={onValueSelectHandler}\n maxHeight={maxHeight}\n navigationBarProps={navigationBarProps}\n suggestContainerRef={suggestContainerRef}\n itemsGap={itemsGap}\n onBottomSheetClose={handleBottomSheetClose}\n onBottomSheetOpen={onBottomSheetOpen}\n onDropOpen={onDropOpen}\n onDropClose={onDropClose}\n inputValue={actualInputValue}\n topContent={topContent}\n bottomContent={bottomContent}\n dropWidth={dropWidth}\n isError={isError}\n trls={trls}\n errorPlaceholder={errorPlaceholder}\n onClickReload={() => {\n requestData(actualInputValue);\n }}\n onSearchSubmit={onSearchSubmit}\n input={\n {\n component: InputComponent,\n props: {\n ...input.props,\n onFocus: onFocusHandler,\n onChange: onChangeHandler,\n value: actualInputValue,\n onKeyDown: onKeyDownHandler,\n },\n } as InputProp<T>\n }\n />\n </>\n );\n};\n\nconst Suggest = forwardRef(SuggestComponent) as (<K, T extends SuggestInputComponent>(\n props: SuggestProps<K, T> & { ref?: ForwardedRef<HTMLElement> }\n) => ReactElement | null) & { displayName: string };\n\nSuggest.displayName = 'Suggest';\n\nexport { Suggest };\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"Suggest.js","sources":["../src/Suggest.tsx"],"sourcesContent":["import {\n FocusEventHandler,\n ReactElement,\n useCallback,\n useEffect,\n useRef,\n useState,\n KeyboardEventHandler,\n forwardRef,\n ForwardedRef,\n} from 'react';\n\nimport { DataProviderRequest, DataProviderResult, DataProviderError } from '@hh.ru/magritte-common-data-provider';\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { SuggestPicker, getSearchResultCount } from '@hh.ru/magritte-ui-suggest/SuggestPicker';\nimport {\n SuggestProps,\n SuggestInputComponent,\n InputProp,\n ControlledInputProps,\n NativeFocusEventHandler,\n OptionsCount,\n} from '@hh.ru/magritte-ui-suggest/types';\nimport { useSuggestKeyboardNav } from '@hh.ru/magritte-ui-suggest/useSuggestKeyboardNav';\n\nimport styles from './suggest.less';\n\nconst SuggestTriggerDefault = <InputType extends SuggestInputComponent>(\n props: InputProp<InputType> & OptionsCount\n): ReactElement => {\n const { component: TriggerComponent, props: triggerProps } = props;\n return (\n <TriggerComponent\n {...(triggerProps as unknown as JSX.IntrinsicAttributes &\n JSX.LibraryManagedAttributes<InputType, ControlledInputProps>)}\n />\n );\n};\n\nconst SuggestComponent = function <DataType, InputType extends SuggestInputComponent>(\n {\n dataProvider,\n input,\n inputValue,\n onSelectValidator = () => true,\n navigationBarProps,\n maxHeight = 460,\n itemsGap = 4,\n onBlur,\n topContent,\n bottomContent,\n dropWidth,\n errorPlaceholder,\n trls,\n onChange,\n onDropOpen,\n onDropClose,\n onBottomSheetOpen,\n onBottomSheetClose,\n onSearchSubmit,\n renderTrigger = SuggestTriggerDefault,\n renderItem,\n }: SuggestProps<DataType, InputType>,\n ref: ForwardedRef<HTMLElement>\n): ReactElement | null {\n const { component: InputComponent, props: inputProps } = input;\n const [inputValueState, setInputValueState] = useState(inputProps.value || '');\n const { onChange: onInputChange, onFocus: onInputFocus, onKeyDown: onInputKeyDown } = inputProps;\n const [requestResult, setRequestResult] = useState<{ query: string; result: DataProviderResult<DataType> } | null>(\n null\n );\n const [valueSelectedFromSuggest, setValueSelectedFromSuggest] = useState<string | false>(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const wrapperRef = useRef<HTMLElement>(null);\n const suggestContainerRef = useRef<HTMLElement>(null);\n const inputContainerRef = useRef<HTMLDivElement>(null);\n const inputRefMulti = useMultipleRefs(inputRef, ref);\n const onBlurRef = useRef<NativeFocusEventHandler | undefined>(onBlur);\n onBlurRef.current = onBlur; // update actual callback\n const { isMobile } = useBreakpoint();\n const [isError, setIsError] = useState(false);\n\n const currentRequestRef = useRef<DataProviderRequest>();\n const actualInputValue = inputValue === undefined ? inputValueState : inputValue;\n\n const { focused, onKeyDown, onFocus, ...rest } = useSuggestKeyboardNav(\n suggestContainerRef,\n inputContainerRef,\n setValueSelectedFromSuggest,\n actualInputValue,\n inputRef,\n onBlurRef\n );\n\n const handleBottomSheetClose = () => {\n rest.onBottomSheetClose();\n onBottomSheetClose?.();\n };\n\n const onChangeHandler = useCallback(\n (value: string, skipSuggestChangeHandler = false) => {\n if (inputValue === undefined) {\n setInputValueState(value);\n }\n !skipSuggestChangeHandler && onChange?.(value, false);\n onInputChange?.(value);\n },\n [inputValue, setInputValueState, onInputChange, onChange]\n );\n\n const requestData = useCallback(\n (query: string) => {\n setIsError(false);\n currentRequestRef.current?.cancel();\n const request = dataProvider(query);\n request.then(\n (result) => {\n setRequestResult({ query, result });\n },\n (event) => {\n // включаем error state если это НЕ ошибка, вызванная `minCharsCount` или отменненым запросом\n if (!(event instanceof DataProviderError)) {\n setIsError(true);\n }\n setRequestResult(null);\n }\n );\n currentRequestRef.current = request;\n },\n [dataProvider]\n );\n\n useEffect(() => {\n if (valueSelectedFromSuggest !== false && requestResult?.query !== actualInputValue) {\n setRequestResult(null);\n }\n if (valueSelectedFromSuggest !== actualInputValue.trim()) {\n setValueSelectedFromSuggest(false);\n if (focused) {\n requestData(actualInputValue);\n }\n }\n\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n }, [actualInputValue, requestData, focused]);\n\n const onFocusHandler = useCallback<FocusEventHandler<HTMLElement>>(\n (event) => {\n setValueSelectedFromSuggest(false);\n if (actualInputValue !== requestResult?.query) {\n setRequestResult(null);\n requestData(actualInputValue);\n }\n\n onInputFocus?.(event);\n onFocus(event);\n },\n [actualInputValue, requestResult?.query, onInputFocus, onFocus, requestData]\n );\n\n const onValueSelectHandler = useCallback(\n (value: string, data: DataType | undefined) => {\n if (!onSelectValidator(value, data)) {\n return;\n }\n if (!isMobile) {\n inputRef.current?.focus();\n }\n onChangeHandler(value, true);\n onChange?.(value, true, data);\n setValueSelectedFromSuggest(value);\n },\n [onSelectValidator, isMobile, onChangeHandler, onChange]\n );\n\n const onKeyDownHandler = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (event) => {\n onKeyDown(event);\n onInputKeyDown?.(event);\n },\n [onInputKeyDown, onKeyDown]\n );\n\n return (\n <>\n <div ref={inputContainerRef} className={styles.suggestInputContainer}>\n {renderTrigger({\n component: InputComponent,\n props: {\n ...inputProps,\n value: actualInputValue,\n onFocus: onFocusHandler,\n onChange: onChangeHandler,\n onKeyDown: onKeyDownHandler,\n ref: inputRefMulti,\n wrapperRef,\n autoComplete: 'off',\n },\n optionsCount: getSearchResultCount(requestResult?.result),\n } as unknown as InputProp<InputType> & OptionsCount)}\n </div>\n <SuggestPicker\n data={requestResult?.result}\n activatorRef={wrapperRef}\n inputRef={inputRef}\n inputFocused={focused}\n currentInputValueSelectedFromSuggest={valueSelectedFromSuggest !== false}\n onValueSelect={onValueSelectHandler}\n maxHeight={maxHeight}\n navigationBarProps={navigationBarProps}\n suggestContainerRef={suggestContainerRef}\n itemsGap={itemsGap}\n onBottomSheetClose={handleBottomSheetClose}\n onBottomSheetOpen={onBottomSheetOpen}\n onDropOpen={onDropOpen}\n onDropClose={onDropClose}\n inputValue={actualInputValue}\n topContent={topContent}\n bottomContent={bottomContent}\n dropWidth={dropWidth}\n isError={isError}\n trls={trls}\n errorPlaceholder={errorPlaceholder}\n renderItem={renderItem}\n onClickReload={() => {\n requestData(actualInputValue);\n }}\n onSearchSubmit={onSearchSubmit}\n input={\n {\n component: InputComponent,\n props: {\n ...input.props,\n onFocus: onFocusHandler,\n onChange: onChangeHandler,\n value: actualInputValue,\n onKeyDown: onKeyDownHandler,\n },\n } as InputProp<InputType>\n }\n />\n </>\n );\n};\n\nconst Suggest = forwardRef(SuggestComponent) as (<DataType, InputType extends SuggestInputComponent>(\n props: SuggestProps<DataType, InputType> & { ref?: ForwardedRef<HTMLElement> }\n) => ReactElement | null) & { displayName: string };\n\nSuggest.displayName = 'Suggest';\n\nexport { Suggest };\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4BA,MAAM,qBAAqB,GAAG,CAC1B,KAA0C,KAC5B;IACd,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;AACnE,IAAA,QACIA,GAAC,CAAA,gBAAgB,OACR,YAC6D,EAAA,CACpE,EACJ;AACN,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,UACrB,EACI,YAAY,EACZ,KAAK,EACL,UAAU,EACV,iBAAiB,GAAG,MAAM,IAAI,EAC9B,kBAAkB,EAClB,SAAS,GAAG,GAAG,EACf,QAAQ,GAAG,CAAC,EACZ,MAAM,EACN,UAAU,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,aAAa,GAAG,qBAAqB,EACrC,UAAU,GACsB,EACpC,GAA8B,EAAA;IAE9B,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;AAC/D,IAAA,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAC/E,IAAA,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC;IACjG,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAC9C,IAAI,CACP,CAAC;IACF,MAAM,CAAC,wBAAwB,EAAE,2BAA2B,CAAC,GAAG,QAAQ,CAAiB,KAAK,CAAC,CAAC;AAChG,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;AAChD,IAAA,MAAM,UAAU,GAAG,MAAM,CAAc,IAAI,CAAC,CAAC;AAC7C,IAAA,MAAM,mBAAmB,GAAG,MAAM,CAAc,IAAI,CAAC,CAAC;AACtD,IAAA,MAAM,iBAAiB,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACrD,IAAA,MAAM,SAAS,GAAG,MAAM,CAAsC,MAAM,CAAC,CAAC;AACtE,IAAA,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;AAC3B,IAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,EAAE,CAAC;IACrC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE9C,IAAA,MAAM,iBAAiB,GAAG,MAAM,EAAuB,CAAC;AACxD,IAAA,MAAM,gBAAgB,GAAG,UAAU,KAAK,SAAS,GAAG,eAAe,GAAG,UAAU,CAAC;IAEjF,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,qBAAqB,CAClE,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC3B,gBAAgB,EAChB,QAAQ,EACR,SAAS,CACZ,CAAC;IAEF,MAAM,sBAAsB,GAAG,MAAK;QAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,kBAAkB,IAAI,CAAC;AAC3B,KAAC,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CAC/B,CAAC,KAAa,EAAE,wBAAwB,GAAG,KAAK,KAAI;AAChD,QAAA,IAAI,UAAU,KAAK,SAAS,EAAE;YAC1B,kBAAkB,CAAC,KAAK,CAAC,CAAC;SAC7B;QACD,CAAC,wBAAwB,IAAI,QAAQ,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC;AACtD,QAAA,aAAa,GAAG,KAAK,CAAC,CAAC;KAC1B,EACD,CAAC,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,QAAQ,CAAC,CAC5D,CAAC;AAEF,IAAA,MAAM,WAAW,GAAG,WAAW,CAC3B,CAAC,KAAa,KAAI;QACd,UAAU,CAAC,KAAK,CAAC,CAAC;AAClB,QAAA,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;AACpC,QAAA,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AACpC,QAAA,OAAO,CAAC,IAAI,CACR,CAAC,MAAM,KAAI;AACP,YAAA,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;AACxC,SAAC,EACD,CAAC,KAAK,KAAI;;AAEN,YAAA,IAAI,EAAE,KAAK,YAAY,iBAAiB,CAAC,EAAE;gBACvC,UAAU,CAAC,IAAI,CAAC,CAAC;aACpB;YACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC3B,SAAC,CACJ,CAAC;AACF,QAAA,iBAAiB,CAAC,OAAO,GAAG,OAAO,CAAC;AACxC,KAAC,EACD,CAAC,YAAY,CAAC,CACjB,CAAC;IAEF,SAAS,CAAC,MAAK;QACX,IAAI,wBAAwB,KAAK,KAAK,IAAI,aAAa,EAAE,KAAK,KAAK,gBAAgB,EAAE;YACjF,gBAAgB,CAAC,IAAI,CAAC,CAAC;SAC1B;AACD,QAAA,IAAI,wBAAwB,KAAK,gBAAgB,CAAC,IAAI,EAAE,EAAE;YACtD,2BAA2B,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,OAAO,EAAE;gBACT,WAAW,CAAC,gBAAgB,CAAC,CAAC;aACjC;SACJ;;KAGJ,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7C,IAAA,MAAM,cAAc,GAAG,WAAW,CAC9B,CAAC,KAAK,KAAI;QACN,2BAA2B,CAAC,KAAK,CAAC,CAAC;AACnC,QAAA,IAAI,gBAAgB,KAAK,aAAa,EAAE,KAAK,EAAE;YAC3C,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,WAAW,CAAC,gBAAgB,CAAC,CAAC;SACjC;AAED,QAAA,YAAY,GAAG,KAAK,CAAC,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,CAAC;AACnB,KAAC,EACD,CAAC,gBAAgB,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,CAAC,CAC/E,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CACpC,CAAC,KAAa,EAAE,IAA0B,KAAI;QAC1C,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE;YACjC,OAAO;SACV;QACD,IAAI,CAAC,QAAQ,EAAE;AACX,YAAA,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;SAC7B;AACD,QAAA,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7B,QAAQ,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9B,2BAA2B,CAAC,KAAK,CAAC,CAAC;KACtC,EACD,CAAC,iBAAiB,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,CAAC,CAC3D,CAAC;AAEF,IAAA,MAAM,gBAAgB,GAAG,WAAW,CAChC,CAAC,KAAK,KAAI;QACN,SAAS,CAAC,KAAK,CAAC,CAAC;AACjB,QAAA,cAAc,GAAG,KAAK,CAAC,CAAC;AAC5B,KAAC,EACD,CAAC,cAAc,EAAE,SAAS,CAAC,CAC9B,CAAC;AAEF,IAAA,QACIC,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACIF,GAAK,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,CAAC,qBAAqB,EAAA,QAAA,EAC/D,aAAa,CAAC;AACX,oBAAA,SAAS,EAAE,cAAc;AACzB,oBAAA,KAAK,EAAE;AACH,wBAAA,GAAG,UAAU;AACb,wBAAA,KAAK,EAAE,gBAAgB;AACvB,wBAAA,OAAO,EAAE,cAAc;AACvB,wBAAA,QAAQ,EAAE,eAAe;AACzB,wBAAA,SAAS,EAAE,gBAAgB;AAC3B,wBAAA,GAAG,EAAE,aAAa;wBAClB,UAAU;AACV,wBAAA,YAAY,EAAE,KAAK;AACtB,qBAAA;AACD,oBAAA,YAAY,EAAE,oBAAoB,CAAC,aAAa,EAAE,MAAM,CAAC;iBACV,CAAC,EAAA,CAClD,EACNA,GAAC,CAAA,aAAa,IACV,IAAI,EAAE,aAAa,EAAE,MAAM,EAC3B,YAAY,EAAE,UAAU,EACxB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,OAAO,EACrB,oCAAoC,EAAE,wBAAwB,KAAK,KAAK,EACxE,aAAa,EAAE,oBAAoB,EACnC,SAAS,EAAE,SAAS,EACpB,kBAAkB,EAAE,kBAAkB,EACtC,mBAAmB,EAAE,mBAAmB,EACxC,QAAQ,EAAE,QAAQ,EAClB,kBAAkB,EAAE,sBAAsB,EAC1C,iBAAiB,EAAE,iBAAiB,EACpC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,gBAAgB,EAC5B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAK;oBAChB,WAAW,CAAC,gBAAgB,CAAC,CAAC;AAClC,iBAAC,EACD,cAAc,EAAE,cAAc,EAC9B,KAAK,EACD;AACI,oBAAA,SAAS,EAAE,cAAc;AACzB,oBAAA,KAAK,EAAE;wBACH,GAAG,KAAK,CAAC,KAAK;AACd,wBAAA,OAAO,EAAE,cAAc;AACvB,wBAAA,QAAQ,EAAE,eAAe;AACzB,wBAAA,KAAK,EAAE,gBAAgB;AACvB,wBAAA,SAAS,EAAE,gBAAgB;AAC9B,qBAAA;iBACoB,EAE/B,CAAA,CAAA,EAAA,CACH,EACL;AACN,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,EAES;AAEpD,OAAO,CAAC,WAAW,GAAG,SAAS;;;;"}
@@ -1,15 +1,18 @@
1
1
  import { RefObject, ReactElement, ReactNode } from 'react';
2
+ import { DataProviderResult } from '@hh.ru/magritte-common-data-provider';
2
3
  import { type TokenBaseCoreSpace } from '@hh.ru/magritte-design-tokens/types';
3
- import { DataProviderResult, SuggestProps, SuggestInputComponent, InputProp, SearchSubmitType } from '@hh.ru/magritte-ui-suggest/types';
4
- interface SuggestPickerProps<K, P extends SuggestInputComponent = SuggestInputComponent> {
5
- data: DataProviderResult<K> | null | undefined;
4
+ import { type NavigationBarProps } from '@hh.ru/magritte-ui-navigation-bar';
5
+ import { SuggestInputComponent, InputProp, SearchSubmitType, SuggestTrls, RenderOptionType } from '@hh.ru/magritte-ui-suggest/types';
6
+ interface SuggestPickerProps<DataType, InputType extends SuggestInputComponent> {
7
+ data: DataProviderResult<DataType> | null | undefined;
6
8
  activatorRef: RefObject<HTMLElement>;
7
9
  inputRef: RefObject<HTMLElement>;
8
- onValueSelect: (value: string, data: K | undefined) => void;
10
+ onValueSelect: (value: string, data: DataType | undefined) => void;
9
11
  maxHeight: number;
10
- navigationBarProps: SuggestProps<unknown, SuggestInputComponent>['navigationBarProps'];
11
- input: InputProp<P>;
12
+ navigationBarProps?: NavigationBarProps;
13
+ input: InputProp<InputType>;
12
14
  inputFocused: boolean;
15
+ renderItem?: RenderOptionType<DataType>;
13
16
  currentInputValueSelectedFromSuggest: boolean;
14
17
  suggestContainerRef: RefObject<HTMLElement>;
15
18
  itemsGap: TokenBaseCoreSpace;
@@ -19,7 +22,7 @@ interface SuggestPickerProps<K, P extends SuggestInputComponent = SuggestInputCo
19
22
  bottomContent?: ReactNode;
20
23
  dropWidth?: number;
21
24
  isError: boolean;
22
- trls: SuggestProps<unknown, SuggestInputComponent>['trls'];
25
+ trls: SuggestTrls;
23
26
  errorPlaceholder: ReactNode;
24
27
  onClickReload: VoidFunction;
25
28
  onBottomSheetOpen?: VoidFunction;
@@ -29,7 +32,7 @@ interface SuggestPickerProps<K, P extends SuggestInputComponent = SuggestInputCo
29
32
  }
30
33
  export declare const getSearchResultCount: <K>(options: DataProviderResult<K> | null | undefined) => number;
31
34
  export declare const SuggestPicker: {
32
- <K, P extends SuggestInputComponent>({ data, activatorRef, inputRef, onValueSelect, maxHeight, navigationBarProps, input, inputFocused, currentInputValueSelectedFromSuggest, suggestContainerRef, itemsGap, onBottomSheetClose, onBottomSheetOpen, inputValue, topContent, bottomContent, dropWidth, isError, trls, errorPlaceholder, onClickReload, onDropOpen, onDropClose, onSearchSubmit, }: SuggestPickerProps<K, P>): ReactElement | null;
35
+ <DataType, InputType extends SuggestInputComponent>({ data, activatorRef, inputRef, onValueSelect, maxHeight, navigationBarProps, input, inputFocused, currentInputValueSelectedFromSuggest, suggestContainerRef, itemsGap, onBottomSheetClose, onBottomSheetOpen, inputValue, topContent, bottomContent, dropWidth, isError, trls, errorPlaceholder, onClickReload, onDropOpen, onDropClose, onSearchSubmit, renderItem, }: SuggestPickerProps<DataType, InputType>): ReactElement | null;
33
36
  displayName: string;
34
37
  };
35
38
  export {};
package/SuggestPicker.js CHANGED
@@ -9,7 +9,7 @@ import { Button } from '@hh.ru/magritte-ui-button';
9
9
  import { Drop } from '@hh.ru/magritte-ui-drop';
10
10
  import { ArrowPathOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';
11
11
  import { NavigationBar } from '@hh.ru/magritte-ui-navigation-bar';
12
- import { r as renderSection, s as styles } from './sectionRenderers-DUmKzPLp.js';
12
+ import { r as renderSection, s as styles } from './sectionRenderers-DJgoxD4F.js';
13
13
  import '@hh.ru/magritte-ui-card';
14
14
  import '@hh.ru/magritte-ui-cell';
15
15
  import '@hh.ru/magritte-ui-chips';
@@ -17,12 +17,14 @@ import '@hh.ru/magritte-ui-typography';
17
17
 
18
18
  const getSearchResultCount = (options) => options?.filter(({ type, searchable = true }) => type !== 'delimiter' && searchable).length || 0;
19
19
  const dropPlacement = ['bottom-left', 'top-left'];
20
- const SuggestPicker = function ({ data, activatorRef, inputRef, onValueSelect, maxHeight, navigationBarProps, input, inputFocused, currentInputValueSelectedFromSuggest, suggestContainerRef, itemsGap, onBottomSheetClose, onBottomSheetOpen, inputValue, topContent, bottomContent, dropWidth, isError, trls, errorPlaceholder, onClickReload, onDropOpen, onDropClose, onSearchSubmit, }) {
20
+ const SuggestPicker = function ({ data, activatorRef, inputRef, onValueSelect, maxHeight, navigationBarProps, input, inputFocused, currentInputValueSelectedFromSuggest, suggestContainerRef, itemsGap, onBottomSheetClose, onBottomSheetOpen, inputValue, topContent, bottomContent, dropWidth, isError, trls, errorPlaceholder, onClickReload, onDropOpen, onDropClose, onSearchSubmit, renderItem, }) {
21
21
  const { isMobile, breakpoint } = useBreakpoint();
22
22
  const [showBottomSheet, setShowBottomSheet] = useState(false);
23
23
  const [showDrop, setShowDrop] = useState(true);
24
24
  const bottomSheetInputRef = useRef(null);
25
25
  const [caretVisible, setCaretVisible] = useState(false);
26
+ const renderItemRef = useRef(renderItem);
27
+ renderItemRef.current = renderItem;
26
28
  useEffect(() => {
27
29
  if (inputFocused) {
28
30
  setShowBottomSheet(true);
@@ -56,7 +58,7 @@ const SuggestPicker = function ({ data, activatorRef, inputRef, onValueSelect, m
56
58
  return null;
57
59
  }
58
60
  return data.reduce((result, section, index) => {
59
- const renderResult = renderSection(section, index, onValueSelect, breakpoint, data.length, Boolean(bottomContent));
61
+ const renderResult = renderSection(section, index, onValueSelect, breakpoint, data.length, Boolean(bottomContent), renderItemRef.current);
60
62
  result.push(...renderResult);
61
63
  return result;
62
64
  }, []);
@@ -1 +1 @@
1
- {"version":3,"file":"SuggestPicker.js","sources":["../src/SuggestPicker.tsx"],"sourcesContent":["import {\n RefObject,\n useMemo,\n useEffect,\n useRef,\n useState,\n ReactElement,\n KeyboardEventHandler,\n ReactNode,\n useCallback,\n} from 'react';\nimport classnames from 'classnames';\n\nimport { keyboardKeys, keyboardMatch } from '@hh.ru/magritte-common-keyboard';\nimport { type TokenBaseCoreSpace } from '@hh.ru/magritte-design-tokens/types';\nimport { BottomSheet, BottomSheetFooter } from '@hh.ru/magritte-ui-bottom-sheet';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { Button } from '@hh.ru/magritte-ui-button';\nimport { Drop } from '@hh.ru/magritte-ui-drop';\nimport { ArrowPathOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';\nimport { ControlledInputProps } from '@hh.ru/magritte-ui-input';\nimport { NavigationBar } from '@hh.ru/magritte-ui-navigation-bar';\nimport { renderSection } from '@hh.ru/magritte-ui-suggest/sectionRenderers';\nimport {\n DataProviderResult,\n SuggestProps,\n SuggestInputComponent,\n InputProp,\n SearchSubmitType,\n} from '@hh.ru/magritte-ui-suggest/types';\n\nimport styles from './suggest.less';\n\ninterface SuggestPickerProps<K, P extends SuggestInputComponent = SuggestInputComponent> {\n data: DataProviderResult<K> | null | undefined;\n activatorRef: RefObject<HTMLElement>;\n inputRef: RefObject<HTMLElement>;\n onValueSelect: (value: string, data: K | undefined) => void;\n maxHeight: number;\n navigationBarProps: SuggestProps<unknown, SuggestInputComponent>['navigationBarProps'];\n input: InputProp<P>;\n inputFocused: boolean;\n currentInputValueSelectedFromSuggest: boolean;\n suggestContainerRef: RefObject<HTMLElement>;\n itemsGap: TokenBaseCoreSpace;\n onBottomSheetClose: VoidFunction;\n inputValue: string;\n topContent?: ReactNode;\n bottomContent?: ReactNode;\n dropWidth?: number;\n isError: boolean;\n trls: SuggestProps<unknown, SuggestInputComponent>['trls'];\n errorPlaceholder: ReactNode;\n onClickReload: VoidFunction;\n onBottomSheetOpen?: VoidFunction;\n onDropOpen?: VoidFunction;\n onDropClose?: VoidFunction;\n onSearchSubmit?: SearchSubmitType;\n}\n\nexport const getSearchResultCount = <K,>(options: DataProviderResult<K> | null | undefined): number =>\n options?.filter(({ type, searchable = true }) => type !== 'delimiter' && searchable).length || 0;\n\nconst dropPlacement = ['bottom-left', 'top-left'];\n\nexport const SuggestPicker = function <K, P extends SuggestInputComponent>({\n data,\n activatorRef,\n inputRef,\n onValueSelect,\n maxHeight,\n navigationBarProps,\n input,\n inputFocused,\n currentInputValueSelectedFromSuggest,\n suggestContainerRef,\n itemsGap,\n onBottomSheetClose,\n onBottomSheetOpen,\n inputValue,\n topContent,\n bottomContent,\n dropWidth,\n isError,\n trls,\n errorPlaceholder,\n onClickReload,\n onDropOpen,\n onDropClose,\n onSearchSubmit,\n}: SuggestPickerProps<K, P>): ReactElement | null {\n const { isMobile, breakpoint } = useBreakpoint();\n const [showBottomSheet, setShowBottomSheet] = useState(false);\n const [showDrop, setShowDrop] = useState(true);\n const bottomSheetInputRef = useRef<HTMLInputElement>(null);\n const [caretVisible, setCaretVisible] = useState(false);\n\n useEffect(() => {\n if (inputFocused) {\n setShowBottomSheet(true);\n } else if (!isMobile) {\n setShowBottomSheet(false);\n }\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n }, [inputFocused, setShowBottomSheet]);\n\n useEffect(() => {\n if (currentInputValueSelectedFromSuggest) {\n setShowBottomSheet(false);\n }\n }, [currentInputValueSelectedFromSuggest, isMobile]);\n\n // если скрыли дроп из-за скрытия активатора под скроллом, то при следующем изменении данных нужно его показать\n useEffect(() => {\n setShowDrop(true);\n }, [inputValue, inputFocused]);\n\n const onKeyDownHandler = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (event) => {\n input.props.onKeyDown?.(event);\n if (onSearchSubmit && keyboardMatch(event.nativeEvent, keyboardKeys.Enter)) {\n const onCloseBottomSheet = () => {\n setShowBottomSheet(false);\n };\n // в onSearchSubmit нужно вернуть количество результатов поиска\n onSearchSubmit(event, onCloseBottomSheet, getSearchResultCount(data));\n }\n },\n [input.props, onSearchSubmit, data]\n );\n\n const suggestContent = useMemo(() => {\n if (!data) {\n return null;\n }\n\n return data.reduce<Array<JSX.Element>>((result, section, index) => {\n const renderResult = renderSection(\n section,\n index,\n onValueSelect,\n breakpoint,\n data.length,\n Boolean(bottomContent)\n );\n result.push(...renderResult);\n return result;\n }, []);\n }, [data, onValueSelect, breakpoint, bottomContent]);\n\n const dropVisible =\n suggestContent !== null &&\n suggestContent.length > 0 &&\n !currentInputValueSelectedFromSuggest &&\n inputFocused &&\n showDrop;\n\n const InputComponent = input.component;\n const processInput =\n (ref: RefObject<HTMLElement>): KeyboardEventHandler<HTMLElement> =>\n (event) => {\n const hasPrintableRepresentation = event.key.replace(/\\s/g, '').length === 1;\n if (!hasPrintableRepresentation) {\n return;\n }\n ref.current?.focus();\n const newEvent = new KeyboardEvent('keydown', event.nativeEvent);\n ref.current?.dispatchEvent(newEvent);\n };\n\n return (\n <>\n <BottomSheet\n visible={showBottomSheet}\n height=\"full-screen\"\n onAfterExit={onBottomSheetClose}\n keyboardOverlaysFooter={false}\n header={\n <NavigationBar\n {...navigationBarProps}\n options={\n <div\n className={classnames({\n [styles.bottomSheetInputHideCaret]: !caretVisible,\n })}\n >\n <InputComponent\n {...({\n ...input.props,\n invalid: false,\n ref: bottomSheetInputRef,\n autoComplete: 'off',\n onKeyDown: onKeyDownHandler,\n } as unknown as JSX.IntrinsicAttributes &\n JSX.LibraryManagedAttributes<P, ControlledInputProps>)}\n />\n </div>\n }\n />\n }\n onAppear={() => {\n bottomSheetInputRef?.current?.focus();\n setCaretVisible(true);\n onBottomSheetOpen?.();\n }}\n onBeforeExit={() => {\n bottomSheetInputRef?.current?.blur();\n setCaretVisible(false);\n }}\n onClose={() => {\n setShowBottomSheet(false);\n }}\n footer={\n isError && (\n <BottomSheetFooter>\n <Button\n mode=\"secondary\"\n style=\"negative\"\n icon={<ArrowPathOutlinedSize24 />}\n onClick={onClickReload}\n data-qa=\"suggest-reload-button\"\n stretched\n >\n {trls.resetButton}\n </Button>\n </BottomSheetFooter>\n )\n }\n ref={suggestContainerRef}\n allowScrollWhileFocused\n >\n {!isError && (\n <div\n onKeyDown={processInput(bottomSheetInputRef)}\n className={styles.suggestItemsContainer}\n style={{ gap: itemsGap }}\n >\n {topContent}\n {suggestContent}\n {bottomContent}\n </div>\n )}\n {isError && <div className={styles.errorWrapper}>{errorPlaceholder}</div>}\n </BottomSheet>\n <Drop\n autoFocusWhenOpened={false}\n placement={dropPlacement}\n lockPlacement\n visible={dropVisible}\n onClose={() => setShowDrop(false)}\n activatorRef={activatorRef}\n role=\"status\"\n space={400}\n widthEqualToActivator={!dropWidth}\n width={dropWidth}\n forcePlacement\n keyboardNavigationMode=\"list\"\n data-qa=\"suggest-drop\"\n ref={suggestContainerRef}\n onAppear={onDropOpen}\n onAfterExit={onDropClose}\n >\n <div onKeyDown={processInput(inputRef)} className={styles.suggestItemsContainer} style={{ maxHeight }}>\n <div className={styles.suggestItemsContainerWrapper} style={{ gap: itemsGap }}>\n {topContent}\n {suggestContent}\n {bottomContent}\n </div>\n </div>\n </Drop>\n </>\n );\n};\n\nSuggestPicker.displayName = 'SuggestPicker';\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":";;;;;;;;;;;;;;;;AA4DO,MAAM,oBAAoB,GAAG,CAAK,OAAiD,KACtF,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,KAAK,IAAI,KAAK,WAAW,IAAI,UAAU,CAAC,CAAC,MAAM,IAAI,EAAE;AAErG,MAAM,aAAa,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;AAErC,MAAA,aAAa,GAAG,UAA8C,EACvE,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,KAAK,EACL,YAAY,EACZ,oCAAoC,EACpC,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,UAAU,EACV,aAAa,EACb,SAAS,EACT,OAAO,EACP,IAAI,EACJ,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,WAAW,EACX,cAAc,GACS,EAAA;IACvB,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,aAAa,EAAE,CAAC;IACjD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC/C,IAAA,MAAM,mBAAmB,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,SAAS,CAAC,MAAK;QACX,IAAI,YAAY,EAAE;YACd,kBAAkB,CAAC,IAAI,CAAC,CAAC;SAC5B;aAAM,IAAI,CAAC,QAAQ,EAAE;YAClB,kBAAkB,CAAC,KAAK,CAAC,CAAC;SAC7B;;AAEL,KAAC,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAEvC,SAAS,CAAC,MAAK;QACX,IAAI,oCAAoC,EAAE;YACtC,kBAAkB,CAAC,KAAK,CAAC,CAAC;SAC7B;AACL,KAAC,EAAE,CAAC,oCAAoC,EAAE,QAAQ,CAAC,CAAC,CAAC;;IAGrD,SAAS,CAAC,MAAK;QACX,WAAW,CAAC,IAAI,CAAC,CAAC;AACtB,KAAC,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;AAE/B,IAAA,MAAM,gBAAgB,GAAG,WAAW,CAChC,CAAC,KAAK,KAAI;QACN,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;AAC/B,QAAA,IAAI,cAAc,IAAI,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE;YACxE,MAAM,kBAAkB,GAAG,MAAK;gBAC5B,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAC9B,aAAC,CAAC;;YAEF,cAAc,CAAC,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;SACzE;KACJ,EACD,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,CACtC,CAAC;AAEF,IAAA,MAAM,cAAc,GAAG,OAAO,CAAC,MAAK;QAChC,IAAI,CAAC,IAAI,EAAE;AACP,YAAA,OAAO,IAAI,CAAC;SACf;QAED,OAAO,IAAI,CAAC,MAAM,CAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,KAAI;YAC9D,MAAM,YAAY,GAAG,aAAa,CAC9B,OAAO,EACP,KAAK,EACL,aAAa,EACb,UAAU,EACV,IAAI,CAAC,MAAM,EACX,OAAO,CAAC,aAAa,CAAC,CACzB,CAAC;AACF,YAAA,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;AAC7B,YAAA,OAAO,MAAM,CAAC;SACjB,EAAE,EAAE,CAAC,CAAC;KACV,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;AAErD,IAAA,MAAM,WAAW,GACb,cAAc,KAAK,IAAI;QACvB,cAAc,CAAC,MAAM,GAAG,CAAC;AACzB,QAAA,CAAC,oCAAoC;QACrC,YAAY;AACZ,QAAA,QAAQ,CAAC;AAEb,IAAA,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,CAAC;IACvC,MAAM,YAAY,GACd,CAAC,GAA2B,KAC5B,CAAC,KAAK,KAAI;AACN,QAAA,MAAM,0BAA0B,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QAC7E,IAAI,CAAC,0BAA0B,EAAE;YAC7B,OAAO;SACV;AACD,QAAA,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;AACjE,QAAA,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;AACzC,KAAC,CAAC;AAEN,IAAA,QACIA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACID,IAAC,CAAA,WAAW,IACR,OAAO,EAAE,eAAe,EACxB,MAAM,EAAC,aAAa,EACpB,WAAW,EAAE,kBAAkB,EAC/B,sBAAsB,EAAE,KAAK,EAC7B,MAAM,EACFE,IAAC,aAAa,EAAA,EAAA,GACN,kBAAkB,EACtB,OAAO,EACHA,GAAA,CAAA,KAAA,EAAA,EACI,SAAS,EAAE,UAAU,CAAC;AAClB,4BAAA,CAAC,MAAM,CAAC,yBAAyB,GAAG,CAAC,YAAY;yBACpD,CAAC,EAAA,QAAA,EAEFA,GAAC,CAAA,cAAc,EACN,EAAA,GAAA;gCACD,GAAG,KAAK,CAAC,KAAK;AACd,gCAAA,OAAO,EAAE,KAAK;AACd,gCAAA,GAAG,EAAE,mBAAmB;AACxB,gCAAA,YAAY,EAAE,KAAK;AACnB,gCAAA,SAAS,EAAE,gBAAgB;AAE2B,6BAAA,EAAA,CAC5D,GACA,EAEZ,CAAA,EAEN,QAAQ,EAAE,MAAK;AACX,oBAAA,mBAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;oBACtC,eAAe,CAAC,IAAI,CAAC,CAAC;oBACtB,iBAAiB,IAAI,CAAC;AAC1B,iBAAC,EACD,YAAY,EAAE,MAAK;AACf,oBAAA,mBAAmB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;oBACrC,eAAe,CAAC,KAAK,CAAC,CAAC;AAC3B,iBAAC,EACD,OAAO,EAAE,MAAK;oBACV,kBAAkB,CAAC,KAAK,CAAC,CAAC;iBAC7B,EACD,MAAM,EACF,OAAO,KACHA,GAAA,CAAC,iBAAiB,EAAA,EAAA,QAAA,EACdA,GAAC,CAAA,MAAM,IACH,IAAI,EAAC,WAAW,EAChB,KAAK,EAAC,UAAU,EAChB,IAAI,EAAEA,GAAC,CAAA,uBAAuB,KAAG,EACjC,OAAO,EAAE,aAAa,EAAA,SAAA,EACd,uBAAuB,EAC/B,SAAS,EAER,IAAA,EAAA,QAAA,EAAA,IAAI,CAAC,WAAW,GACZ,EACO,CAAA,CACvB,EAEL,GAAG,EAAE,mBAAmB,EACxB,uBAAuB,EAEtB,IAAA,EAAA,QAAA,EAAA,CAAA,CAAC,OAAO,KACLF,IACI,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,YAAY,CAAC,mBAAmB,CAAC,EAC5C,SAAS,EAAE,MAAM,CAAC,qBAAqB,EACvC,KAAK,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAEvB,QAAA,EAAA,CAAA,UAAU,EACV,cAAc,EACd,aAAa,CAAA,EAAA,CACZ,CACT,EACA,OAAO,IAAIE,GAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,YAAY,YAAG,gBAAgB,EAAA,CAAO,CAC/D,EAAA,CAAA,EACdA,GAAC,CAAA,IAAI,IACD,mBAAmB,EAAE,KAAK,EAC1B,SAAS,EAAE,aAAa,EACxB,aAAa,QACb,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,WAAW,CAAC,KAAK,CAAC,EACjC,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,GAAG,EACV,qBAAqB,EAAE,CAAC,SAAS,EACjC,KAAK,EAAE,SAAS,EAChB,cAAc,EACd,IAAA,EAAA,sBAAsB,EAAC,MAAM,EACrB,SAAA,EAAA,cAAc,EACtB,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,UAAU,EACpB,WAAW,EAAE,WAAW,EAAA,QAAA,EAExBA,aAAK,SAAS,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,qBAAqB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAA,QAAA,EACjGF,cAAK,SAAS,EAAE,MAAM,CAAC,4BAA4B,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EACxE,QAAA,EAAA,CAAA,UAAU,EACV,cAAc,EACd,aAAa,IACZ,EACJ,CAAA,EAAA,CACH,CACR,EAAA,CAAA,EACL;AACN,EAAE;AAEF,aAAa,CAAC,WAAW,GAAG,eAAe;;;;"}
1
+ {"version":3,"file":"SuggestPicker.js","sources":["../src/SuggestPicker.tsx"],"sourcesContent":["import {\n RefObject,\n useMemo,\n useEffect,\n useRef,\n useState,\n ReactElement,\n KeyboardEventHandler,\n ReactNode,\n useCallback,\n} from 'react';\nimport classnames from 'classnames';\n\nimport { DataProviderResult } from '@hh.ru/magritte-common-data-provider';\nimport { keyboardKeys, keyboardMatch } from '@hh.ru/magritte-common-keyboard';\nimport { type TokenBaseCoreSpace } from '@hh.ru/magritte-design-tokens/types';\nimport { BottomSheet, BottomSheetFooter } from '@hh.ru/magritte-ui-bottom-sheet';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { Button } from '@hh.ru/magritte-ui-button';\nimport { Drop } from '@hh.ru/magritte-ui-drop';\nimport { ArrowPathOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';\nimport { ControlledInputProps } from '@hh.ru/magritte-ui-input';\nimport { NavigationBar, type NavigationBarProps } from '@hh.ru/magritte-ui-navigation-bar';\nimport { renderSection } from '@hh.ru/magritte-ui-suggest/sectionRenderers';\nimport {\n SuggestInputComponent,\n InputProp,\n SearchSubmitType,\n SuggestTrls,\n RenderOptionType,\n} from '@hh.ru/magritte-ui-suggest/types';\n\nimport styles from './suggest.less';\n\ninterface SuggestPickerProps<DataType, InputType extends SuggestInputComponent> {\n data: DataProviderResult<DataType> | null | undefined;\n activatorRef: RefObject<HTMLElement>;\n inputRef: RefObject<HTMLElement>;\n onValueSelect: (value: string, data: DataType | undefined) => void;\n maxHeight: number;\n navigationBarProps?: NavigationBarProps;\n input: InputProp<InputType>;\n inputFocused: boolean;\n renderItem?: RenderOptionType<DataType>;\n currentInputValueSelectedFromSuggest: boolean;\n suggestContainerRef: RefObject<HTMLElement>;\n itemsGap: TokenBaseCoreSpace;\n onBottomSheetClose: VoidFunction;\n inputValue: string;\n topContent?: ReactNode;\n bottomContent?: ReactNode;\n dropWidth?: number;\n isError: boolean;\n trls: SuggestTrls;\n errorPlaceholder: ReactNode;\n onClickReload: VoidFunction;\n onBottomSheetOpen?: VoidFunction;\n onDropOpen?: VoidFunction;\n onDropClose?: VoidFunction;\n onSearchSubmit?: SearchSubmitType;\n}\n\nexport const getSearchResultCount = <K,>(options: DataProviderResult<K> | null | undefined): number =>\n options?.filter(({ type, searchable = true }) => type !== 'delimiter' && searchable).length || 0;\n\nconst dropPlacement = ['bottom-left', 'top-left'];\n\nexport const SuggestPicker = function <DataType, InputType extends SuggestInputComponent>({\n data,\n activatorRef,\n inputRef,\n onValueSelect,\n maxHeight,\n navigationBarProps,\n input,\n inputFocused,\n currentInputValueSelectedFromSuggest,\n suggestContainerRef,\n itemsGap,\n onBottomSheetClose,\n onBottomSheetOpen,\n inputValue,\n topContent,\n bottomContent,\n dropWidth,\n isError,\n trls,\n errorPlaceholder,\n onClickReload,\n onDropOpen,\n onDropClose,\n onSearchSubmit,\n renderItem,\n}: SuggestPickerProps<DataType, InputType>): ReactElement | null {\n const { isMobile, breakpoint } = useBreakpoint();\n const [showBottomSheet, setShowBottomSheet] = useState(false);\n const [showDrop, setShowDrop] = useState(true);\n const bottomSheetInputRef = useRef<HTMLInputElement>(null);\n const [caretVisible, setCaretVisible] = useState(false);\n const renderItemRef = useRef<RenderOptionType<DataType> | undefined>(renderItem);\n renderItemRef.current = renderItem;\n\n useEffect(() => {\n if (inputFocused) {\n setShowBottomSheet(true);\n } else if (!isMobile) {\n setShowBottomSheet(false);\n }\n // eslint-disable-next-line disable-autofix/react-hooks/exhaustive-deps\n }, [inputFocused, setShowBottomSheet]);\n\n useEffect(() => {\n if (currentInputValueSelectedFromSuggest) {\n setShowBottomSheet(false);\n }\n }, [currentInputValueSelectedFromSuggest, isMobile]);\n\n // если скрыли дроп из-за скрытия активатора под скроллом, то при следующем изменении данных нужно его показать\n useEffect(() => {\n setShowDrop(true);\n }, [inputValue, inputFocused]);\n\n const onKeyDownHandler = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (event) => {\n input.props.onKeyDown?.(event);\n if (onSearchSubmit && keyboardMatch(event.nativeEvent, keyboardKeys.Enter)) {\n const onCloseBottomSheet = () => {\n setShowBottomSheet(false);\n };\n // в onSearchSubmit нужно вернуть количество результатов поиска\n onSearchSubmit(event, onCloseBottomSheet, getSearchResultCount(data));\n }\n },\n [input.props, onSearchSubmit, data]\n );\n\n const suggestContent = useMemo(() => {\n if (!data) {\n return null;\n }\n\n return data.reduce<Array<JSX.Element>>((result, section, index) => {\n const renderResult = renderSection(\n section,\n index,\n onValueSelect,\n breakpoint,\n data.length,\n Boolean(bottomContent),\n renderItemRef.current\n );\n result.push(...renderResult);\n return result;\n }, []);\n }, [data, onValueSelect, breakpoint, bottomContent]);\n\n const dropVisible =\n suggestContent !== null &&\n suggestContent.length > 0 &&\n !currentInputValueSelectedFromSuggest &&\n inputFocused &&\n showDrop;\n\n const InputComponent = input.component;\n const processInput =\n (ref: RefObject<HTMLElement>): KeyboardEventHandler<HTMLElement> =>\n (event) => {\n const hasPrintableRepresentation = event.key.replace(/\\s/g, '').length === 1;\n if (!hasPrintableRepresentation) {\n return;\n }\n ref.current?.focus();\n const newEvent = new KeyboardEvent('keydown', event.nativeEvent);\n ref.current?.dispatchEvent(newEvent);\n };\n\n return (\n <>\n <BottomSheet\n visible={showBottomSheet}\n height=\"full-screen\"\n onAfterExit={onBottomSheetClose}\n keyboardOverlaysFooter={false}\n header={\n <NavigationBar\n {...navigationBarProps}\n options={\n <div\n className={classnames({\n [styles.bottomSheetInputHideCaret]: !caretVisible,\n })}\n >\n <InputComponent\n {...({\n ...input.props,\n invalid: false,\n ref: bottomSheetInputRef,\n autoComplete: 'off',\n onKeyDown: onKeyDownHandler,\n } as unknown as JSX.IntrinsicAttributes &\n JSX.LibraryManagedAttributes<InputType, ControlledInputProps>)}\n />\n </div>\n }\n />\n }\n onAppear={() => {\n bottomSheetInputRef?.current?.focus();\n setCaretVisible(true);\n onBottomSheetOpen?.();\n }}\n onBeforeExit={() => {\n bottomSheetInputRef?.current?.blur();\n setCaretVisible(false);\n }}\n onClose={() => {\n setShowBottomSheet(false);\n }}\n footer={\n isError && (\n <BottomSheetFooter>\n <Button\n mode=\"secondary\"\n style=\"negative\"\n icon={<ArrowPathOutlinedSize24 />}\n onClick={onClickReload}\n data-qa=\"suggest-reload-button\"\n stretched\n >\n {trls.resetButton}\n </Button>\n </BottomSheetFooter>\n )\n }\n ref={suggestContainerRef}\n allowScrollWhileFocused\n >\n {!isError && (\n <div\n onKeyDown={processInput(bottomSheetInputRef)}\n className={styles.suggestItemsContainer}\n style={{ gap: itemsGap }}\n >\n {topContent}\n {suggestContent}\n {bottomContent}\n </div>\n )}\n {isError && <div className={styles.errorWrapper}>{errorPlaceholder}</div>}\n </BottomSheet>\n <Drop\n autoFocusWhenOpened={false}\n placement={dropPlacement}\n lockPlacement\n visible={dropVisible}\n onClose={() => setShowDrop(false)}\n activatorRef={activatorRef}\n role=\"status\"\n space={400}\n widthEqualToActivator={!dropWidth}\n width={dropWidth}\n forcePlacement\n keyboardNavigationMode=\"list\"\n data-qa=\"suggest-drop\"\n ref={suggestContainerRef}\n onAppear={onDropOpen}\n onAfterExit={onDropClose}\n >\n <div onKeyDown={processInput(inputRef)} className={styles.suggestItemsContainer} style={{ maxHeight }}>\n <div className={styles.suggestItemsContainerWrapper} style={{ gap: itemsGap }}>\n {topContent}\n {suggestContent}\n {bottomContent}\n </div>\n </div>\n </Drop>\n </>\n );\n};\n\nSuggestPicker.displayName = 'SuggestPicker';\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":"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"}
package/index.css CHANGED
@@ -8,57 +8,57 @@
8
8
  .magritte-night-theme{
9
9
  --magritte-color-text-primary-v21-3-2:#ffffff;
10
10
  }
11
- .magritte-chips-section-container___Z7N-E_7-0-9{
11
+ .magritte-chips-section-container___Z7N-E_8-0-1{
12
12
  display:flex;
13
13
  gap:12px;
14
14
  flex:1 1;
15
15
  flex-wrap:wrap;
16
16
  }
17
- .magritte-chips-section-container_with-other-items___eJZAr_7-0-9{
17
+ .magritte-chips-section-container_with-other-items___eJZAr_8-0-1{
18
18
  padding-bottom:16px;
19
19
  }
20
- .magritte-suggest-items-container___SKj-g_7-0-9{
20
+ .magritte-suggest-items-container___SKj-g_8-0-1{
21
21
  display:flex;
22
22
  flex-direction:column;
23
23
  }
24
- .magritte-suggest-items-container___SKj-g_7-0-9 .focus-visible{
24
+ .magritte-suggest-items-container___SKj-g_8-0-1 .focus-visible{
25
25
  z-index:1;
26
26
  position:relative;
27
27
  }
28
- .magritte-suggest-items-container-wrapper___T2L5U_7-0-9{
28
+ .magritte-suggest-items-container-wrapper___T2L5U_8-0-1{
29
29
  padding:var(--magritte-static-space-400-v21-3-2);
30
30
  margin:calc(-1 * var(--magritte-static-space-400-v21-3-2));
31
31
  display:flex;
32
32
  flex-direction:column;
33
33
  }
34
34
  @media (min-width: 1020px){
35
- body.magritte-old-layout .magritte-suggest-items-container-wrapper___T2L5U_7-0-9{
35
+ body.magritte-old-layout .magritte-suggest-items-container-wrapper___T2L5U_8-0-1{
36
36
  padding:var(--magritte-static-space-300-v21-3-2);
37
37
  }
38
38
  }
39
39
  @media (min-width: 1024px){
40
- body:not(.magritte-old-layout) .magritte-suggest-items-container-wrapper___T2L5U_7-0-9{
40
+ body:not(.magritte-old-layout) .magritte-suggest-items-container-wrapper___T2L5U_8-0-1{
41
41
  padding:var(--magritte-static-space-300-v21-3-2);
42
42
  }
43
43
  }
44
- .magritte-suggest-input-container___l3OkM_7-0-9{
44
+ .magritte-suggest-input-container___l3OkM_8-0-1{
45
45
  --magritte-ui-input-caret-color-override:transparent;
46
46
  display:inline-block;
47
47
  width:100%;
48
48
  }
49
49
  @media (min-width: 700px){
50
- body.magritte-old-layout .magritte-suggest-input-container___l3OkM_7-0-9{
50
+ body.magritte-old-layout .magritte-suggest-input-container___l3OkM_8-0-1{
51
51
  --magritte-ui-input-caret-color-override:var(--magritte-color-text-primary-v21-3-2);
52
52
  }
53
53
  }
54
54
  @media (min-width: 600px){
55
- body:not(.magritte-old-layout) .magritte-suggest-input-container___l3OkM_7-0-9{
55
+ body:not(.magritte-old-layout) .magritte-suggest-input-container___l3OkM_8-0-1{
56
56
  --magritte-ui-input-caret-color-override:var(--magritte-color-text-primary-v21-3-2);
57
57
  }
58
58
  }
59
- .magritte-bottom-sheet-input-hide-caret___ikoig_7-0-9{
59
+ .magritte-bottom-sheet-input-hide-caret___ikoig_8-0-1{
60
60
  --magritte-ui-input-caret-color-override:transparent;
61
61
  }
62
- .magritte-error-wrapper___Ui4xt_7-0-9{
62
+ .magritte-error-wrapper___Ui4xt_8-0-1{
63
63
  height:100%;
64
64
  }
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from '@hh.ru/magritte-ui-theme-provider';
2
2
  export * from '@hh.ru/magritte-ui-suggest/Suggest';
3
- export { createDataProvider, decorateWithQueryTransofrmer, decorateWithResponseFormatter, defaultFetcher, createStaticDataFetcher, combineProviders, type AsyncDataFetcher, } from '@hh.ru/magritte-ui-suggest/dataProvider';
4
- export type { DataSection, DataSectionOfType, DataProviderResult, DataProvider, SuggestInputProps, SuggestProps, SuggestInputComponent, } from '@hh.ru/magritte-ui-suggest/types';
3
+ export { RenderItemDefault } from '@hh.ru/magritte-ui-suggest/sectionRenderers';
4
+ export type { SuggestInputProps, SuggestProps, SuggestInputComponent, RenderOptionType as RenderSuggestOptionType, SuggestOptionProps, SuggestOptionWithText, } from '@hh.ru/magritte-ui-suggest/types';
package/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import './index.css';
2
2
  export * from '@hh.ru/magritte-ui-theme-provider';
3
3
  export { Suggest } from './Suggest.js';
4
- export { combineProviders, createDataProvider, createStaticDataFetcher, decorateWithQueryTransofrmer, decorateWithResponseFormatter, defaultFetcher } from './dataProvider.js';
4
+ export { R as RenderItemDefault } from './sectionRenderers-DJgoxD4F.js';
5
5
  import 'react/jsx-runtime';
6
6
  import 'react';
7
+ import '@hh.ru/magritte-common-data-provider';
7
8
  import '@hh.ru/magritte-common-use-multiple-refs';
8
9
  import '@hh.ru/magritte-ui-breakpoint';
9
10
  import './SuggestPicker.js';
@@ -14,13 +15,9 @@ import '@hh.ru/magritte-ui-button';
14
15
  import '@hh.ru/magritte-ui-drop';
15
16
  import '@hh.ru/magritte-ui-icon/icon';
16
17
  import '@hh.ru/magritte-ui-navigation-bar';
17
- import './sectionRenderers-DUmKzPLp.js';
18
+ import './useSuggestKeyboardNav.js';
18
19
  import '@hh.ru/magritte-ui-card';
19
20
  import '@hh.ru/magritte-ui-cell';
20
21
  import '@hh.ru/magritte-ui-chips';
21
22
  import '@hh.ru/magritte-ui-typography';
22
- import './useSuggestKeyboardNav.js';
23
- import 'axios';
24
- import '@hh.ru/magritte-common-func-utils';
25
- import '@hh.ru/magritte-common-fuzzy-search';
26
23
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
package/index.mock.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ForwardRefExoticComponent } from 'react';
2
- export { type AsyncDataFetcher } from '@hh.ru/magritte-ui-suggest/dataProvider';
3
- export type { DataSection, DataSectionOfType, DataProviderResult, DataProvider, SuggestInputProps, } from '@hh.ru/magritte-ui-suggest/types';
2
+ export type { SuggestInputProps } from '@hh.ru/magritte-ui-suggest/types';
4
3
  declare const ThemeProvider: any;
5
4
  export { ThemeProvider };
6
5
  export declare const Input: ForwardRefExoticComponent<Record<string, unknown>>;
package/index.mock.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mock.js","sources":["../src/index.mock.ts"],"sourcesContent":["import { ForwardRefExoticComponent } from 'react';\n\nimport { mockComponent } from '@hh.ru/magritte-ui-mock-component';\n\nexport { type AsyncDataFetcher } from '@hh.ru/magritte-ui-suggest/dataProvider';\n\nexport type {\n DataSection,\n DataSectionOfType,\n DataProviderResult,\n DataProvider,\n SuggestInputProps,\n} from '@hh.ru/magritte-ui-suggest/types';\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nconst { ThemeProvider } = jest.requireActual('@hh.ru/magritte-ui-theme-provider/index');\n\nexport { ThemeProvider };\n\nexport const Input: ForwardRefExoticComponent<Record<string, unknown>> = mockComponent('Suggest', undefined, {\n withChildren: false,\n});\n"],"names":[],"mappings":";;AAcA;AACM,MAAA,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,yCAAyC,EAAE;MAI3E,KAAK,GAAuD,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE;AACzG,IAAA,YAAY,EAAE,KAAK;AACtB,CAAA;;;;"}
1
+ {"version":3,"file":"index.mock.js","sources":["../src/index.mock.ts"],"sourcesContent":["import { ForwardRefExoticComponent } from 'react';\n\nimport { mockComponent } from '@hh.ru/magritte-ui-mock-component';\n\nexport type { SuggestInputProps } from '@hh.ru/magritte-ui-suggest/types';\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nconst { ThemeProvider } = jest.requireActual('@hh.ru/magritte-ui-theme-provider/index');\n\nexport { ThemeProvider };\n\nexport const Input: ForwardRefExoticComponent<Record<string, unknown>> = mockComponent('Suggest', undefined, {\n withChildren: false,\n});\n"],"names":[],"mappings":";;AAMA;AACM,MAAA,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,yCAAyC,EAAE;MAI3E,KAAK,GAAuD,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE;AACzG,IAAA,YAAY,EAAE,KAAK;AACtB,CAAA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hh.ru/magritte-ui-suggest",
3
- "version": "7.0.9",
3
+ "version": "8.0.1",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "sideEffects": [
@@ -20,12 +20,13 @@
20
20
  "watch": "yarn root:watch $(pwd)"
21
21
  },
22
22
  "dependencies": {
23
+ "@hh.ru/magritte-common-data-provider": "1.2.0",
23
24
  "@hh.ru/magritte-common-func-utils": "1.3.9",
24
25
  "@hh.ru/magritte-common-fuzzy-search": "1.0.5",
25
26
  "@hh.ru/magritte-common-keyboard": "4.1.0",
26
27
  "@hh.ru/magritte-common-use-multiple-refs": "1.1.5",
27
28
  "@hh.ru/magritte-design-tokens": "21.3.2",
28
- "@hh.ru/magritte-ui-bottom-sheet": "7.0.6",
29
+ "@hh.ru/magritte-ui-bottom-sheet": "7.0.7",
29
30
  "@hh.ru/magritte-ui-breakpoint": "5.0.0",
30
31
  "@hh.ru/magritte-ui-button": "5.2.26",
31
32
  "@hh.ru/magritte-ui-card": "7.0.3",
@@ -37,16 +38,15 @@
37
38
  "@hh.ru/magritte-ui-mock-component": "1.0.12",
38
39
  "@hh.ru/magritte-ui-navigation-bar": "7.0.6",
39
40
  "@hh.ru/magritte-ui-theme-provider": "1.1.41",
40
- "@hh.ru/magritte-ui-trigger": "3.0.28",
41
+ "@hh.ru/magritte-ui-trigger": "3.0.29",
41
42
  "@hh.ru/magritte-ui-typography": "3.0.31"
42
43
  },
43
44
  "peerDependencies": {
44
- "axios": ">=0.26.0",
45
45
  "classnames": ">=2.3.2",
46
46
  "react": ">=18.2.0"
47
47
  },
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "gitHead": "d77d66dde37efbf4f169985c1ed243ba9bbdc67e"
51
+ "gitHead": "45423cebe8915eca05c73df986715979d386f7be"
52
52
  }
@@ -0,0 +1,69 @@
1
+ import './index.css';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { Fragment } from 'react';
4
+ import classnames from 'classnames';
5
+ import { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';
6
+ import { Card } from '@hh.ru/magritte-ui-card';
7
+ import { Cell, CellText } from '@hh.ru/magritte-ui-cell';
8
+ import { CustomChip } from '@hh.ru/magritte-ui-chips';
9
+ import { Text } from '@hh.ru/magritte-ui-typography';
10
+
11
+ var styles = {"chips-section-container":"magritte-chips-section-container___Z7N-E_8-0-1","chipsSectionContainer":"magritte-chips-section-container___Z7N-E_8-0-1","chips-section-container_with-other-items":"magritte-chips-section-container_with-other-items___eJZAr_8-0-1","chipsSectionContainerWithOtherItems":"magritte-chips-section-container_with-other-items___eJZAr_8-0-1","suggest-items-container":"magritte-suggest-items-container___SKj-g_8-0-1","suggestItemsContainer":"magritte-suggest-items-container___SKj-g_8-0-1","suggest-items-container-wrapper":"magritte-suggest-items-container-wrapper___T2L5U_8-0-1","suggestItemsContainerWrapper":"magritte-suggest-items-container-wrapper___T2L5U_8-0-1","suggest-input-container":"magritte-suggest-input-container___l3OkM_8-0-1","suggestInputContainer":"magritte-suggest-input-container___l3OkM_8-0-1","bottom-sheet-input-hide-caret":"magritte-bottom-sheet-input-hide-caret___ikoig_8-0-1","bottomSheetInputHideCaret":"magritte-bottom-sheet-input-hide-caret___ikoig_8-0-1","error-wrapper":"magritte-error-wrapper___Ui4xt_8-0-1","errorWrapper":"magritte-error-wrapper___Ui4xt_8-0-1"};
12
+
13
+ const RenderItemDefault = ({ type, data, item, onValueSelect, 'data-qa': dataQa, }) => {
14
+ if (type === 'cells') {
15
+ return (jsx(Cell, { children: jsx(CellText, { children: data?.text || item.value }) }));
16
+ }
17
+ if (type === 'chips') {
18
+ return (jsx(CustomChip, { onMouseDown: (event) => event.preventDefault(), onClick: () => onValueSelect(item.value, item.data), "data-qa": dataQa, children: item.value }));
19
+ }
20
+ return null;
21
+ };
22
+ const renderSection = (section, sectionId, onValueSelect, breakpoint, length, haveBottomContent, renderItem = RenderItemDefault) => {
23
+ if (section.type === 'cells') {
24
+ const cellsSection = section;
25
+ return cellsSection.items.map((item) => {
26
+ return (jsx(Card, { style: "primary", stretched: true, hoverStyle: "secondary", onMouseDown: (event) => {
27
+ event.preventDefault();
28
+ }, onClick: (event) => {
29
+ event.preventDefault();
30
+ onValueSelect(item.value, item.data);
31
+ }, padding: [Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12, paddingTop: 12, paddingBottom: 12, borderRadius: 12, "data-qa": "suggest-item-cell", children: renderItem({
32
+ type: section.type,
33
+ item,
34
+ data: item.data,
35
+ onValueSelect,
36
+ breakpoint,
37
+ 'data-qa': 'suggest-item-cell-text',
38
+ }) }, `cell_${sectionId}_${item.value}`));
39
+ });
40
+ }
41
+ if (section.type === 'chips') {
42
+ const chipsSection = section;
43
+ return [
44
+ jsx("div", { className: classnames(styles.chipsSectionContainer, {
45
+ // чипсы - не последний элемент или есть нижний контент
46
+ [styles.chipsSectionContainerWithOtherItems]: sectionId !== length - 1 || haveBottomContent,
47
+ }), children: chipsSection.items.map((item) => {
48
+ return (jsx(Fragment, { children: renderItem({
49
+ type: section.type,
50
+ item,
51
+ data: item.data,
52
+ onValueSelect,
53
+ breakpoint,
54
+ 'data-qa': 'suggest-item-chips',
55
+ }) }, `chips_${sectionId}_${item.value}`));
56
+ }) }, `chips_section_${sectionId}`),
57
+ ];
58
+ }
59
+ if (section.type === 'delimiter') {
60
+ const delimiterSection = section;
61
+ return [
62
+ jsx(Card, { style: "primary", stretched: true, padding: [Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12, paddingTop: 8, paddingBottom: 8, "data-qa": "suggest-item-delimiter", children: jsx(Text, { style: "secondary", typography: "label-3-regular", children: delimiterSection.text }) }, `delimiter_${delimiterSection.text}`),
63
+ ];
64
+ }
65
+ return [];
66
+ };
67
+
68
+ export { RenderItemDefault as R, renderSection as r, styles as s };
69
+ //# sourceMappingURL=sectionRenderers-DJgoxD4F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionRenderers-DJgoxD4F.js","sources":["../src/sectionRenderers.tsx"],"sourcesContent":["import { ReactElement, Fragment } from 'react';\nimport classnames from 'classnames';\n\nimport { DataSection, DataSectionOfType } from '@hh.ru/magritte-common-data-provider';\nimport { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { Card } from '@hh.ru/magritte-ui-card';\nimport { Cell, CellText } from '@hh.ru/magritte-ui-cell';\nimport { CustomChip } from '@hh.ru/magritte-ui-chips';\nimport {\n RenderOptionType,\n SuggestOptionProps,\n ValueSelectHandler,\n SuggestOptionWithText,\n} from '@hh.ru/magritte-ui-suggest/types';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './suggest.less';\n\nexport const RenderItemDefault = <DataType,>({\n type,\n data,\n item,\n onValueSelect,\n 'data-qa': dataQa,\n}: SuggestOptionProps<DataType>): ReactElement | null => {\n if (type === 'cells') {\n return (\n <Cell>\n <CellText>{(data as SuggestOptionWithText)?.text || item.value}</CellText>\n </Cell>\n );\n }\n if (type === 'chips') {\n return (\n <CustomChip\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onValueSelect(item.value, item.data)}\n data-qa={dataQa}\n >\n {item.value}\n </CustomChip>\n );\n }\n return null;\n};\n\nexport const renderSection = <DataSectionType extends DataSection['type'], DataType>(\n section: DataSectionOfType<DataSectionType>,\n sectionId: number,\n onValueSelect: ValueSelectHandler<DataType>,\n breakpoint: Breakpoint,\n length: number,\n haveBottomContent: boolean,\n renderItem: RenderOptionType<DataType> = RenderItemDefault\n): JSX.Element[] => {\n if (section.type === 'cells') {\n const cellsSection = section as DataSectionOfType<'cells', DataType>;\n return cellsSection.items.map((item) => {\n return (\n <Card\n style=\"primary\"\n stretched\n hoverStyle=\"secondary\"\n onMouseDown={(event) => {\n event.preventDefault();\n }}\n onClick={(event) => {\n event.preventDefault();\n onValueSelect(item.value, item.data);\n }}\n padding={[Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12}\n paddingTop={12}\n paddingBottom={12}\n borderRadius={12}\n key={`cell_${sectionId}_${item.value}`}\n data-qa=\"suggest-item-cell\"\n >\n {renderItem({\n type: section.type,\n item,\n data: item.data,\n onValueSelect,\n breakpoint,\n 'data-qa': 'suggest-item-cell-text',\n })}\n </Card>\n );\n });\n }\n\n if (section.type === 'chips') {\n const chipsSection = section as DataSectionOfType<'chips', DataType>;\n return [\n <div\n className={classnames(styles.chipsSectionContainer, {\n // чипсы - не последний элемент или есть нижний контент\n [styles.chipsSectionContainerWithOtherItems]: sectionId !== length - 1 || haveBottomContent,\n })}\n key={`chips_section_${sectionId}`}\n >\n {chipsSection.items.map((item) => {\n return (\n <Fragment key={`chips_${sectionId}_${item.value}`}>\n {renderItem({\n type: section.type,\n item,\n data: item.data,\n onValueSelect,\n breakpoint,\n 'data-qa': 'suggest-item-chips',\n })}\n </Fragment>\n );\n })}\n </div>,\n ];\n }\n\n if (section.type === 'delimiter') {\n const delimiterSection = section as DataSectionOfType<'delimiter', DataType>;\n return [\n <Card\n style=\"primary\"\n stretched\n padding={[Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12}\n paddingTop={8}\n paddingBottom={8}\n key={`delimiter_${delimiterSection.text}`}\n data-qa=\"suggest-item-delimiter\"\n >\n <Text style=\"secondary\" typography=\"label-3-regular\">\n {delimiterSection.text}\n </Text>\n </Card>,\n ];\n }\n\n return [];\n};\n"],"names":["_jsx"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
+ import { ReactElement } from 'react';
2
+ import { DataSection, DataSectionOfType } from '@hh.ru/magritte-common-data-provider';
1
3
  import { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';
2
- import { DataSection, DataSectionOfType } from '@hh.ru/magritte-ui-suggest/types';
3
- interface ValueSelectHandler<K> {
4
- (value: string, data: K | undefined): void;
5
- }
6
- export declare const renderSection: <T, K extends DataSection["type"]>(section: DataSectionOfType<K>, sectionId: number, onValueSelect: ValueSelectHandler<T>, breakpoint: Breakpoint, length: number, haveBottomContent: boolean) => JSX.Element[];
7
- export {};
4
+ import { RenderOptionType, SuggestOptionProps, ValueSelectHandler } from '@hh.ru/magritte-ui-suggest/types';
5
+ export declare const RenderItemDefault: <DataType>({ type, data, item, onValueSelect, "data-qa": dataQa, }: SuggestOptionProps<DataType>) => ReactElement | null;
6
+ export declare const renderSection: <DataSectionType extends DataSection["type"], DataType>(section: DataSectionOfType<DataSectionType>, sectionId: number, onValueSelect: ValueSelectHandler<DataType>, breakpoint: Breakpoint, length: number, haveBottomContent: boolean, renderItem?: RenderOptionType<DataType>) => JSX.Element[];
@@ -1,11 +1,11 @@
1
1
  import './index.css';
2
- import 'react';
3
2
  import 'react/jsx-runtime';
3
+ import 'react';
4
4
  import 'classnames';
5
5
  import '@hh.ru/magritte-ui-breakpoint';
6
6
  import '@hh.ru/magritte-ui-card';
7
7
  import '@hh.ru/magritte-ui-cell';
8
8
  import '@hh.ru/magritte-ui-chips';
9
9
  import '@hh.ru/magritte-ui-typography';
10
- export { r as renderSection } from './sectionRenderers-DUmKzPLp.js';
10
+ export { R as RenderItemDefault, r as renderSection } from './sectionRenderers-DJgoxD4F.js';
11
11
  //# sourceMappingURL=sectionRenderers.js.map
package/types.d.ts CHANGED
@@ -1,47 +1,12 @@
1
1
  import { FocusEventHandler, ForwardRefExoticComponent, FunctionComponent, KeyboardEventHandler, Ref, ReactNode, ReactElement } from 'react';
2
+ import { DataProvider, CellItemProps, ChipItemProps, DataSection } from '@hh.ru/magritte-common-data-provider';
2
3
  import { type TokenBaseCoreSpace } from '@hh.ru/magritte-design-tokens/types';
3
- import { type CellProps } from '@hh.ru/magritte-ui-cell';
4
- import { type CustomChipProps } from '@hh.ru/magritte-ui-chips';
4
+ import { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';
5
5
  import { type NavigationBarProps } from '@hh.ru/magritte-ui-navigation-bar';
6
6
  import { BaseTrigger } from '@hh.ru/magritte-ui-trigger/BaseTrigger';
7
7
  export interface NativeFocusEventHandler {
8
8
  (event: FocusEvent): void;
9
9
  }
10
- type DataSectionTypes<T = never> = {
11
- cells: {
12
- items: Array<{
13
- componentProps: CellProps;
14
- value: string;
15
- data?: T;
16
- }>;
17
- };
18
- chips: {
19
- items: Array<{
20
- componentProps?: Omit<CustomChipProps, 'Element' | 'onDelete'>;
21
- value: string;
22
- data?: T;
23
- }>;
24
- };
25
- delimiter: {
26
- text: string;
27
- };
28
- };
29
- export type DataSectionOfType<T extends keyof DataSectionTypes, K = unknown> = DataSectionTypes<K>[T] & {
30
- type: T;
31
- } & {
32
- searchable?: boolean;
33
- };
34
- export type DataSection<K = unknown> = {
35
- [T in keyof DataSectionTypes]: DataSectionOfType<T, K>;
36
- }[keyof DataSectionTypes];
37
- export type DataProviderResult<T = unknown> = Array<DataSection<T>>;
38
- export type DataProviderRequest<T = unknown> = Promise<DataProviderResult<T>> & {
39
- cancel: VoidFunction;
40
- };
41
- export interface DataProvider<T = never> {
42
- (query: string): DataProviderRequest<T>;
43
- minCharsCount: number;
44
- }
45
10
  export interface RequiredInputProps {
46
11
  value: string;
47
12
  onChange: (value: string) => void;
@@ -67,18 +32,38 @@ type DataQa = {
67
32
  export interface OptionsCount {
68
33
  optionsCount: number;
69
34
  }
70
- export type InputProp<P extends SuggestInputComponent, T = Parameters<P>[0], K = Required<T>> = K extends RequiredInputProps ? {
71
- component: P;
72
- props: Omit<T, keyof RequiredInputProps> & Partial<RequiredInputProps> & DataQa;
35
+ export type InputProp<InputType extends SuggestInputComponent, InputParameters = Parameters<InputType>[0], RequiredPropsType = Required<InputParameters>> = RequiredPropsType extends RequiredInputProps ? {
36
+ component: InputType;
37
+ props: Omit<InputParameters, keyof RequiredInputProps> & Partial<RequiredInputProps> & DataQa;
73
38
  } : never;
74
- export interface SuggestProps<K, P extends SuggestInputComponent = SuggestInputComponent> {
39
+ export interface SuggestTrls {
40
+ resetButton: ReactNode;
41
+ }
42
+ export interface ValueSelectHandler<DataType> {
43
+ (value: string, data: DataType | undefined): void;
44
+ }
45
+ export interface SuggestOptionWithText {
46
+ text?: string;
47
+ }
48
+ export interface SuggestOptionProps<DataType> {
49
+ type: Omit<DataSection['type'], 'delimiter'>;
50
+ item: CellItemProps<DataType> | ChipItemProps<DataType>;
51
+ data?: DataType;
52
+ onValueSelect: ValueSelectHandler<DataType>;
53
+ breakpoint: Breakpoint;
54
+ 'data-qa'?: string;
55
+ }
56
+ export interface RenderOptionType<DataType> {
57
+ (props: SuggestOptionProps<DataType>): ReactElement | null;
58
+ }
59
+ export interface SuggestProps<DataType, InputType extends SuggestInputComponent = SuggestInputComponent> {
75
60
  /** Функция провайдер данных */
76
- dataProvider: DataProvider<K>;
61
+ dataProvider: DataProvider<DataType>;
77
62
  /** Значение в инпуте в саджесте, используется при работе в controlled режиме */
78
63
  inputValue?: string;
79
64
  /** Обработчик выбора значения в саджесте, с помощью возвращаемого значения
80
65
  * происходит управление применением выбора */
81
- onSelectValidator?: (value: string, data: K | undefined) => boolean;
66
+ onSelectValidator?: (value: string, data: DataType | undefined) => boolean;
82
67
  /**
83
68
  * Обработчик изменения значения саджеста.
84
69
  * Срабатывает как при вводе в инпут, так и при выборе значения из саджеста.
@@ -88,7 +73,7 @@ export interface SuggestProps<K, P extends SuggestInputComponent = SuggestInputC
88
73
  * Третий аргумент так же передается только в случае выбора значения из списка и равен значению из поля `data`
89
74
  * выбранного элемента.
90
75
  */
91
- onChange?: (value: string, isValueFromList: boolean, data?: K) => void;
76
+ onChange?: (value: string, isValueFromList: boolean, data?: DataType) => void;
92
77
  /** Отступ в пикселях между элементами саджеста */
93
78
  itemsGap?: TokenBaseCoreSpace;
94
79
  /**
@@ -96,9 +81,11 @@ export interface SuggestProps<K, P extends SuggestInputComponent = SuggestInputC
96
81
  * В качестве компонента могут использоваться только controlled инпуты.
97
82
  * В случае использования кастомного триггера, `component` используется только в `bottom-sheet`
98
83
  */
99
- input: InputProp<P>;
84
+ input: InputProp<InputType>;
100
85
  /** Render функция для Trigger */
101
- renderTrigger?: (props: InputProp<P> & OptionsCount) => ReactElement;
86
+ renderTrigger?: (props: InputProp<InputType> & OptionsCount) => ReactElement;
87
+ /** Render функция для option */
88
+ renderItem?: RenderOptionType<DataType>;
102
89
  /** Пропсы NavigationBar который отображается в BottomSheet саджеста на мобильных разрешениях */
103
90
  navigationBarProps?: NavigationBarProps;
104
91
  /** Обработчик события нажатия Enter в поиске */
@@ -116,9 +103,7 @@ export interface SuggestProps<K, P extends SuggestInputComponent = SuggestInputC
116
103
  /** placeholder при возникновении ошибки сети */
117
104
  errorPlaceholder: ReactNode;
118
105
  /** Перевод для кнопки в error состоянии */
119
- trls: {
120
- resetButton: ReactNode;
121
- };
106
+ trls: SuggestTrls;
122
107
  /** Обработчик события открытия дропа */
123
108
  onDropOpen?: VoidFunction;
124
109
  /** Обработчик события закрытия дропа */
package/dataProvider.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import { DataProvider, DataProviderResult } from '@hh.ru/magritte-ui-suggest/types';
2
- type CancelCallback = (callback: VoidFunction) => void;
3
- export interface FetcherResultProducer<R = never, I = undefined> {
4
- (data: I | null, query: string): DataProviderResult<R>;
5
- }
6
- export interface AsyncDataFetcher<R = never, T = DataProviderResult<R>> {
7
- (url: string, onCancel: CancelCallback): Promise<T | null>;
8
- }
9
- export declare const decorateWithQueryTransofrmer: <K, T>(fetcher: AsyncDataFetcher<K, T>, decorator: (query: string) => string) => AsyncDataFetcher<K, T>;
10
- export declare const decorateWithResponseFormatter: <T, F, K = never>(fetcher: AsyncDataFetcher<F, T>, formatter: FetcherResultProducer<K, T>) => AsyncDataFetcher<K>;
11
- export declare const combineProviders: <T>(providers: Array<DataProvider<T>>) => DataProvider<T>;
12
- export declare const defaultFetcher: <T>(url: string, onCancel: CancelCallback) => Promise<T | null>;
13
- export declare class DataProviderError extends Error {
14
- }
15
- export declare const createDataProvider: <K>({ fetcher, debounceTimeout, minCharsCount, }: {
16
- fetcher: AsyncDataFetcher<K>;
17
- debounceTimeout?: number;
18
- minCharsCount?: number;
19
- }) => DataProvider<K>;
20
- export declare const createStaticDataFetcher: <T extends {
21
- text: string;
22
- }>(data: Array<T>) => AsyncDataFetcher<never, T[]>;
23
- export {};
package/dataProvider.js DELETED
@@ -1,75 +0,0 @@
1
- import './index.css';
2
- import axios from 'axios';
3
- import { debounce } from '@hh.ru/magritte-common-func-utils';
4
- import { match } from '@hh.ru/magritte-common-fuzzy-search';
5
-
6
- const decorateWithQueryTransofrmer = (fetcher, decorator) => (query, onCancel) => fetcher(decorator(query), onCancel);
7
- const decorateWithResponseFormatter = (fetcher, formatter) => async (url, onCancel) => formatter(await fetcher(url, onCancel), url);
8
- const combineProviders = (providers) => {
9
- const provider = (query) => {
10
- const provider = providers.find((provider) => query.length >= provider.minCharsCount) || providers[0];
11
- return provider(query);
12
- };
13
- provider.minCharsCount = Math.min(...providers.map((provider) => provider.minCharsCount));
14
- return provider;
15
- };
16
- const createCancelablePromise = (callback) => {
17
- let isCanceled = false;
18
- let cancelHandler;
19
- const promise = new Promise((resolve, reject) => {
20
- cancelHandler = callback({
21
- resolve: (data) => {
22
- !isCanceled && resolve(data);
23
- },
24
- // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
25
- reject: (err) => !isCanceled && reject(err),
26
- });
27
- });
28
- promise.cancel = () => {
29
- isCanceled = true;
30
- cancelHandler?.();
31
- };
32
- return promise;
33
- };
34
- const defaultFetcher = (url, onCancel) => {
35
- const controller = new AbortController();
36
- onCancel(() => controller.abort());
37
- return axios
38
- .get(url, { signal: controller.signal })
39
- .then((response) => response.data)
40
- .catch((error) => {
41
- if (!axios.isCancel(error)) {
42
- throw error;
43
- }
44
- return null;
45
- });
46
- };
47
- class DataProviderError extends Error {
48
- }
49
- const createDataProvider = ({ fetcher, debounceTimeout = 300, minCharsCount = 3, }) => {
50
- const makeQuery = debounce(({ query, resolve, reject, cancelation, }) => {
51
- if (query.length < minCharsCount || cancelation.isCanceled) {
52
- reject(new DataProviderError());
53
- return;
54
- }
55
- fetcher(query, cancelation.onCancel).then(resolve, reject);
56
- }, debounceTimeout);
57
- const provider = (query) => createCancelablePromise(({ resolve, reject }) => {
58
- const cancelCallbacks = [];
59
- const cancelation = {
60
- isCanceled: false,
61
- onCancel: (callback) => cancelCallbacks.push(callback),
62
- };
63
- makeQuery({ query, resolve, reject, cancelation });
64
- return () => {
65
- cancelation.isCanceled = true;
66
- cancelCallbacks.forEach((callback) => callback());
67
- };
68
- });
69
- provider.minCharsCount = minCharsCount;
70
- return provider;
71
- };
72
- const createStaticDataFetcher = (data) => (query) => Promise.resolve(data.filter(({ text }) => match(query, text)));
73
-
74
- export { DataProviderError, combineProviders, createDataProvider, createStaticDataFetcher, decorateWithQueryTransofrmer, decorateWithResponseFormatter, defaultFetcher };
75
- //# sourceMappingURL=dataProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dataProvider.js","sources":["../src/dataProvider.ts"],"sourcesContent":["import axios from 'axios';\n\nimport { debounce } from '@hh.ru/magritte-common-func-utils';\nimport { match } from '@hh.ru/magritte-common-fuzzy-search';\nimport { DataProvider, DataProviderResult } from '@hh.ru/magritte-ui-suggest/types';\n\ntype CancelCallback = (callback: VoidFunction) => void;\n\nexport interface FetcherResultProducer<R = never, I = undefined> {\n (data: I | null, query: string): DataProviderResult<R>;\n}\nexport interface AsyncDataFetcher<R = never, T = DataProviderResult<R>> {\n (url: string, onCancel: CancelCallback): Promise<T | null>;\n}\n\nexport const decorateWithQueryTransofrmer =\n <K, T>(fetcher: AsyncDataFetcher<K, T>, decorator: (query: string) => string): AsyncDataFetcher<K, T> =>\n (query, onCancel) =>\n fetcher(decorator(query), onCancel);\n\nexport const decorateWithResponseFormatter =\n <T, F, K = never>(fetcher: AsyncDataFetcher<F, T>, formatter: FetcherResultProducer<K, T>): AsyncDataFetcher<K> =>\n async (url, onCancel) =>\n formatter(await fetcher(url, onCancel), url);\n\nexport const combineProviders = <T>(providers: Array<DataProvider<T>>): DataProvider<T> => {\n const provider = (query: string) => {\n const provider = providers.find((provider) => query.length >= provider.minCharsCount) || providers[0];\n return provider(query);\n };\n\n provider.minCharsCount = Math.min(...providers.map((provider) => provider.minCharsCount));\n return provider;\n};\n\ninterface ResolverCallback<T> {\n (arg: { resolve: (result: T | null) => void; reject: (err?: unknown) => void }): VoidFunction | void;\n}\n\nconst createCancelablePromise = <T>(callback: ResolverCallback<T>) => {\n let isCanceled = false;\n let cancelHandler: VoidFunction | void;\n\n const promise = new Promise<T | null>((resolve, reject) => {\n cancelHandler = callback({\n resolve: (data: T | null) => {\n !isCanceled && resolve(data);\n },\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject: (err: unknown) => !isCanceled && reject(err),\n });\n }) as Promise<T> & { cancel: VoidFunction };\n\n promise.cancel = () => {\n isCanceled = true;\n cancelHandler?.();\n };\n return promise;\n};\n\nexport const defaultFetcher = <T>(url: string, onCancel: CancelCallback): Promise<T | null> => {\n const controller = new AbortController();\n onCancel(() => controller.abort());\n\n return axios\n .get<T>(url, { signal: controller.signal })\n .then((response) => response.data)\n .catch((error) => {\n if (!axios.isCancel(error)) {\n throw error;\n }\n return null;\n });\n};\n\nexport class DataProviderError extends Error {}\n\nexport const createDataProvider = <K>({\n fetcher,\n debounceTimeout = 300,\n minCharsCount = 3,\n}: {\n fetcher: AsyncDataFetcher<K>;\n debounceTimeout?: number;\n minCharsCount?: number;\n}): DataProvider<K> => {\n const makeQuery = debounce(\n ({\n query,\n resolve,\n reject,\n cancelation,\n }: Parameters<ResolverCallback<DataProviderResult<K>>>[0] & {\n query: string;\n cancelation: { isCanceled: boolean; onCancel: CancelCallback };\n }) => {\n if (query.length < minCharsCount || cancelation.isCanceled) {\n reject(new DataProviderError());\n return;\n }\n fetcher(query, cancelation.onCancel).then(resolve, reject);\n },\n debounceTimeout\n );\n\n const provider = (query: string) =>\n createCancelablePromise<DataProviderResult<K>>(({ resolve, reject }) => {\n const cancelCallbacks: VoidFunction[] = [];\n const cancelation = {\n isCanceled: false,\n onCancel: (callback: VoidFunction) => cancelCallbacks.push(callback),\n };\n makeQuery({ query, resolve, reject, cancelation });\n return () => {\n cancelation.isCanceled = true;\n cancelCallbacks.forEach((callback) => callback());\n };\n });\n\n provider.minCharsCount = minCharsCount;\n return provider;\n};\n\nexport const createStaticDataFetcher =\n <T extends { text: string }>(data: Array<T>): AsyncDataFetcher<never, T[]> =>\n (query) =>\n Promise.resolve(data.filter(({ text }) => match(query, text)));\n"],"names":[],"mappings":"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"}
@@ -1,48 +0,0 @@
1
- import './index.css';
2
- import { createElement } from 'react';
3
- import { jsx } from 'react/jsx-runtime';
4
- import classnames from 'classnames';
5
- import { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';
6
- import { Card } from '@hh.ru/magritte-ui-card';
7
- import { Cell } from '@hh.ru/magritte-ui-cell';
8
- import { CustomChip } from '@hh.ru/magritte-ui-chips';
9
- import { Text } from '@hh.ru/magritte-ui-typography';
10
-
11
- var styles = {"chips-section-container":"magritte-chips-section-container___Z7N-E_7-0-9","chipsSectionContainer":"magritte-chips-section-container___Z7N-E_7-0-9","chips-section-container_with-other-items":"magritte-chips-section-container_with-other-items___eJZAr_7-0-9","chipsSectionContainerWithOtherItems":"magritte-chips-section-container_with-other-items___eJZAr_7-0-9","suggest-items-container":"magritte-suggest-items-container___SKj-g_7-0-9","suggestItemsContainer":"magritte-suggest-items-container___SKj-g_7-0-9","suggest-items-container-wrapper":"magritte-suggest-items-container-wrapper___T2L5U_7-0-9","suggestItemsContainerWrapper":"magritte-suggest-items-container-wrapper___T2L5U_7-0-9","suggest-input-container":"magritte-suggest-input-container___l3OkM_7-0-9","suggestInputContainer":"magritte-suggest-input-container___l3OkM_7-0-9","bottom-sheet-input-hide-caret":"magritte-bottom-sheet-input-hide-caret___ikoig_7-0-9","bottomSheetInputHideCaret":"magritte-bottom-sheet-input-hide-caret___ikoig_7-0-9","error-wrapper":"magritte-error-wrapper___Ui4xt_7-0-9","errorWrapper":"magritte-error-wrapper___Ui4xt_7-0-9"};
12
-
13
- const cellSectionRenderer = (section, sectionId, onValueSelect, breakpoint) => {
14
- return section.items.map((item) => {
15
- return (jsx(Card, { style: "primary", stretched: true, hoverStyle: "secondary", onMouseDown: (event) => {
16
- event.preventDefault();
17
- }, onClick: (event) => {
18
- event.preventDefault();
19
- onValueSelect(item.value, item.data);
20
- }, padding: [Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12, paddingTop: 12, paddingBottom: 12, borderRadius: 12, "data-qa": "suggest-item-cell", children: jsx(Cell, { ...item.componentProps, onClick: undefined }) }, `cell_${sectionId}_${item.value}`));
21
- });
22
- };
23
- const chipsSectionRenderer = (section, sectionId, onValueSelect, _, length, haveBottomContent) => {
24
- return (jsx("div", { className: classnames(styles.chipsSectionContainer, {
25
- // чипсы - не последний элемент или есть нижний контент
26
- [styles.chipsSectionContainerWithOtherItems]: sectionId !== length - 1 || haveBottomContent,
27
- }), children: section.items.map((item) => {
28
- return (createElement(CustomChip, { ...(item.componentProps || {}), key: `chips_${sectionId}_${item.value}`, onMouseDown: (event) => event.preventDefault(), onClick: () => onValueSelect(item.value, item.data), "data-qa": "suggest-item-chips" }, item.value));
29
- }) }, `chips_section_${sectionId}`));
30
- };
31
- const delimiterSectionRenderer = (section, _, __, breakpoint) => {
32
- return [
33
- jsx(Card, { style: "primary", stretched: true, padding: [Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12, paddingTop: 8, paddingBottom: 8, "data-qa": "suggest-item-delimiter", children: jsx(Text, { style: "secondary", typography: "label-3-regular", children: section.text }) }, `delimiter_${section.text}`),
34
- ];
35
- };
36
- const SECTION_TYPE_TO_RENDERER_MAP = {
37
- cells: cellSectionRenderer,
38
- chips: chipsSectionRenderer,
39
- delimiter: delimiterSectionRenderer,
40
- };
41
- const renderSection = (section, sectionId, onValueSelect, breakpoint, length, haveBottomContent) => {
42
- const renderer = SECTION_TYPE_TO_RENDERER_MAP[section.type];
43
- const result = renderer(section, sectionId, onValueSelect, breakpoint, length, haveBottomContent);
44
- return Array.isArray(result) ? result : [result];
45
- };
46
-
47
- export { renderSection as r, styles as s };
48
- //# sourceMappingURL=sectionRenderers-DUmKzPLp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sectionRenderers-DUmKzPLp.js","sources":["../src/sectionRenderers.tsx"],"sourcesContent":["import classnames from 'classnames';\n\nimport { Breakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { Card } from '@hh.ru/magritte-ui-card';\nimport { Cell } from '@hh.ru/magritte-ui-cell';\nimport { CustomChip } from '@hh.ru/magritte-ui-chips';\nimport { DataSection, DataSectionOfType } from '@hh.ru/magritte-ui-suggest/types';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './suggest.less';\n\ninterface ValueSelectHandler<K> {\n (value: string, data: K | undefined): void;\n}\n\ninterface SectionRenderer<T extends DataSection['type'], K = unknown> {\n (\n section: DataSectionOfType<T>,\n sectionId: number,\n onValueSelect: ValueSelectHandler<K>,\n breakpoint: Breakpoint,\n length: number,\n haveBottomContent: boolean\n ): JSX.Element[] | JSX.Element;\n}\n\nconst cellSectionRenderer: SectionRenderer<'cells'> = (section, sectionId, onValueSelect, breakpoint) => {\n return section.items.map((item) => {\n return (\n <Card\n style=\"primary\"\n stretched\n hoverStyle=\"secondary\"\n onMouseDown={(event) => {\n event.preventDefault();\n }}\n onClick={(event) => {\n event.preventDefault();\n onValueSelect(item.value, item.data);\n }}\n padding={[Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12}\n paddingTop={12}\n paddingBottom={12}\n borderRadius={12}\n key={`cell_${sectionId}_${item.value}`}\n data-qa=\"suggest-item-cell\"\n >\n <Cell {...item.componentProps} onClick={undefined} />\n </Card>\n );\n });\n};\n\nconst chipsSectionRenderer: SectionRenderer<'chips'> = (\n section,\n sectionId,\n onValueSelect,\n _,\n length,\n haveBottomContent\n) => {\n return (\n <div\n className={classnames(styles.chipsSectionContainer, {\n // чипсы - не последний элемент или есть нижний контент\n [styles.chipsSectionContainerWithOtherItems]: sectionId !== length - 1 || haveBottomContent,\n })}\n key={`chips_section_${sectionId}`}\n >\n {section.items.map((item) => {\n return (\n <CustomChip\n {...(item.componentProps || {})}\n key={`chips_${sectionId}_${item.value}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onValueSelect(item.value, item.data)}\n data-qa=\"suggest-item-chips\"\n >\n {item.value}\n </CustomChip>\n );\n })}\n </div>\n );\n};\n\nconst delimiterSectionRenderer: SectionRenderer<'delimiter'> = (section, _, __, breakpoint) => {\n return [\n <Card\n style=\"primary\"\n stretched\n padding={[Breakpoint.XS, Breakpoint.S].includes(breakpoint) ? 0 : 12}\n paddingTop={8}\n paddingBottom={8}\n key={`delimiter_${section.text}`}\n data-qa=\"suggest-item-delimiter\"\n >\n <Text style=\"secondary\" typography=\"label-3-regular\">\n {section.text}\n </Text>\n </Card>,\n ];\n};\n\nconst SECTION_TYPE_TO_RENDERER_MAP: { [K in DataSection['type']]: SectionRenderer<K> } = {\n cells: cellSectionRenderer,\n chips: chipsSectionRenderer,\n delimiter: delimiterSectionRenderer,\n};\n\nexport const renderSection = <T, K extends DataSection['type']>(\n section: DataSectionOfType<K>,\n sectionId: number,\n onValueSelect: ValueSelectHandler<T>,\n breakpoint: Breakpoint,\n length: number,\n haveBottomContent: boolean\n): JSX.Element[] => {\n const renderer = SECTION_TYPE_TO_RENDERER_MAP[section.type];\n const result = renderer(\n section,\n sectionId,\n onValueSelect as ValueSelectHandler<unknown>,\n breakpoint,\n length,\n haveBottomContent\n );\n return Array.isArray(result) ? result : [result];\n};\n"],"names":["_jsx","_createElement"],"mappings":"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"}