@vkontakte/vkui 8.1.0 → 8.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../../src/components/Search/Search.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../../src/components/Search/Search.tsx"],"names":[],"mappings":"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"}
@@ -100,16 +100,6 @@ autoComplete = 'off', autoCapitalize, autoCorrect, disabled, list, maxLength, mi
100
100
  const onIconClickStart = React.useCallback((e)=>onIconClick?.(e), [
101
101
  onIconClick
102
102
  ]);
103
- const onIconCancelClickStart = React.useCallback((e)=>{
104
- e.preventDefault();
105
- inputRef.current?.focus();
106
- if (touchEnabled()) {
107
- onCancel();
108
- }
109
- }, [
110
- inputRef,
111
- onCancel
112
- ]);
113
103
  useIsomorphicLayoutEffect(()=>{
114
104
  if (inputRest.value !== undefined) {
115
105
  setHasValue(Boolean(inputRest.value));
@@ -136,6 +126,25 @@ autoComplete = 'off', autoCapitalize, autoCorrect, disabled, list, maxLength, mi
136
126
  ]
137
127
  });
138
128
  const showControls = Boolean(iconProp || !hideClearButton || adaptiveDensity.compact && onFindButtonClick);
129
+ const onClearPointerDown = (e)=>{
130
+ // Сначала вызываем внешний обработчик, затем локальную логику, чтобы можно было предотвратить обработку фокуса на поле ввода.
131
+ onClearButtonPointerDown?.(e);
132
+ e.preventDefault();
133
+ inputRef.current?.focus();
134
+ if (touchEnabled()) {
135
+ onCancel();
136
+ }
137
+ };
138
+ const onClearClick = (e)=>{
139
+ // eslint-disable-next-line @typescript-eslint/unbound-method
140
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;
141
+ nativeInputValueSetter?.call(inputRef.current, '');
142
+ const ev2 = new Event('input', {
143
+ bubbles: true
144
+ });
145
+ inputRef.current?.dispatchEvent(ev2);
146
+ onClearButtonClick?.(e);
147
+ };
139
148
  return /*#__PURE__*/ _jsxs(RootComponent, {
140
149
  baseClassName: classNames('vkuiInternalSearch', "vkuiSearch__host", density === 'none' && "vkuiSearch__densityNone", density === 'compact' && "vkuiSearch__densityCompact", isFocused && "vkuiSearch__focused", hasValue && "vkuiSearch__hasValue", hasAfter && "vkuiSearch__hasAfter", iconProp && "vkuiSearch__hasIcon", inputRest.disabled && "vkuiSearch__disabled", !noPadding && "vkuiSearch__withPadding", isRtl && "vkuiSearch__rtl"),
141
150
  ...rootRest,
@@ -173,8 +182,8 @@ autoComplete = 'off', autoCapitalize, autoCorrect, disabled, list, maxLength, mi
173
182
  iconProp && (typeof iconProp === 'function' ? iconProp(renderIconButton) : renderIconButton(iconProp)),
174
183
  !hideClearButton && /*#__PURE__*/ _jsxs(IconButton, {
175
184
  hoverMode: "opacity",
176
- onPointerDown: callMultiple(onIconCancelClickStart, onClearButtonPointerDown),
177
- onClick: callMultiple(onCancel, onClearButtonClick),
185
+ onPointerDown: onClearPointerDown,
186
+ onClick: onClearClick,
178
187
  tabIndex: hasValue ? undefined : -1,
179
188
  disabled: inputRest.disabled,
180
189
  "data-testid": clearButtonTestId,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Search/Search.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon16SearchOutline, Icon24Cancel } from '@vkontakte/icons';\nimport { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityConditionalRender } from '../../hooks/useAdaptivityConditionalRender';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useMergeProps } from '../../hooks/useMergeProps';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { touchEnabled } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { HasDataAttribute, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nconst warn = warnOnce('Search');\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: (Partial<IconButtonProps> & HasDataAttribute) | undefined,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'autoComplete'\n | 'autoCapitalize'\n | 'autoCorrect'\n | 'disabled'\n | 'list'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'pattern'\n | 'enterKeyHint'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'value'\n | 'form'\n | 'onChange'\n | 'onFocus'\n | 'onBlur'\n >,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onFocus' | 'onBlur'>,\n HasRootRef<HTMLDivElement> {\n /**\n * @deprecated Since 7.9.0. Вместо этого используйте `slotProps={ input: { getRootRef: ... } }`.\n */\n getRef?: React.Ref<HTMLInputElement> | undefined;\n /**\n * Свойства, которые можно прокинуть внутрь компонента:\n * - `root`: свойства для прокидывания в корень компонента;\n * - `input`: свойства для прокидывания в поле ввода;\n * - `clearButton`: свойства для прокидывания в кнопку очистки.\n */\n slotProps?:\n | {\n root?:\n | (React.HTMLAttributes<HTMLDivElement> & HasRootRef<HTMLDivElement> & HasDataAttribute)\n | undefined;\n input?: React.InputHTMLAttributes<HTMLInputElement> &\n HasRootRef<HTMLInputElement> &\n HasDataAttribute;\n clearButton?: React.HTMLAttributes<HTMLElement> &\n HasRootRef<HTMLElement> &\n HasDataAttribute;\n }\n | undefined;\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode | undefined;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode | undefined;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode) | undefined;\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement> | undefined;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string | undefined;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string | undefined;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string | undefined;\n /**\n * @deprecated Since 8.1.0. Будет удалено в **VKUI v10**. Вместо этого используйте `slotProps={ clearButton: { 'data-testid': ... } }`.\n *\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string | undefined;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean | undefined;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string | undefined;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement> | undefined;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string | undefined;\n /**\n * Скрывает кнопку очистки.\n */\n hideClearButton?: boolean | undefined;\n}\n\n/**\n * @see https://vkui.io/components/search\n */\nexport const Search = ({\n // SearchProps\n after = 'Отмена',\n before = <Icon16SearchOutline />,\n icon: iconProp,\n onIconClick,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n findButtonText = 'Найти',\n onFindButtonClick,\n findButtonTestId,\n hideClearButton,\n getRef,\n\n // input props\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n placeholder: placeholderProp = 'Поиск',\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n\n slotProps,\n ...restProps\n}: SearchProps): React.ReactNode => {\n /* istanbul ignore if: не проверяем в тестах */\n if (process.env.NODE_ENV === 'development') {\n if (getRef) {\n warn('Свойство `getRef` устаревшее, используйте `slotProps={ input: { getRootRef: ... } }`');\n }\n if (clearButtonTestId) {\n warn(\n \"Свойство `clearButtonTestId` устаревшее, используйте `slotProps={ clearButton: { 'data-testid': ... } }`\",\n );\n }\n }\n\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const rootRest = useMergeProps(restProps, slotProps?.root);\n\n const {\n id,\n placeholder,\n getRootRef: getInputRef,\n onChange,\n onFocus: onInputFocus,\n onBlur: onInputBlur,\n ...inputRest\n } = useMergeProps(\n {\n getRootRef: getRef,\n className: styles.nativeInput,\n placeholder: placeholderProp,\n autoComplete,\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n },\n slotProps?.input,\n );\n\n const {\n onClick: onClearButtonClick,\n onPointerDown: onClearButtonPointerDown,\n ...clearButtonRest\n } = useMergeProps({ className: styles.icon }, slotProps?.clearButton);\n\n const inputRef = useExternRef(getInputRef);\n const [isFocused, setFocusedTrue, setFocusedFalse] = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = id ? id : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputRest.value || inputRest.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { density = 'none' } = useAdaptivity();\n const { density: adaptiveDensity } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n onInputFocus && onInputFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n onInputBlur && onInputBlur(e);\n };\n\n const onCancel = React.useCallback(() => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n }, [inputRef]);\n\n const onIconClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => onIconClick?.(e),\n [onIconClick],\n );\n\n const onIconCancelClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n e.preventDefault();\n inputRef.current?.focus();\n if (touchEnabled()) {\n onCancel();\n }\n },\n [inputRef, onCancel],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (inputRest.value !== undefined) {\n setHasValue(Boolean(inputRest.value));\n }\n }, [inputRest.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputRest.defaultValue));\n });\n\n const renderIconButton: RenderIconButtonFn = (icon, props = {}) => (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconClickStart}\n className={styles.icon}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n onClick={noop}\n {...props}\n >\n <VisuallyHidden>{iconLabel}</VisuallyHidden>\n {icon}\n </IconButton>\n );\n\n const showControls = Boolean(\n iconProp || !hideClearButton || (adaptiveDensity.compact && onFindButtonClick),\n );\n\n return (\n <RootComponent\n baseClassName={classNames(\n 'vkuiInternalSearch',\n styles.host,\n density === 'none' && styles.densityNone,\n density === 'compact' && styles.densityCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputRest.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n )}\n {...rootRest}\n >\n <div className={styles.field}>\n <label htmlFor={inputId} className={styles.label}>\n {placeholder}\n </label>\n <div className={styles.input}>\n {before}\n <Headline\n Component=\"input\"\n type=\"search\"\n level=\"1\"\n weight=\"3\"\n id={inputId}\n placeholder={placeholder}\n getRootRef={inputRef}\n onChange={callMultiple(onChange, checkHasValue)}\n onFocus={onFocus}\n onBlur={onBlur}\n {...inputRest}\n />\n </div>\n {showControls && (\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n {!hideClearButton && (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={callMultiple(onIconCancelClickStart, onClearButtonPointerDown)}\n onClick={callMultiple(onCancel, onClearButtonClick)}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputRest.disabled}\n data-testid={clearButtonTestId}\n {...clearButtonRest}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n )}\n {adaptiveDensity.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveDensity.compact.className)}\n focusVisibleMode=\"inside\"\n onClick={onFindButtonClick}\n tabIndex={hasValue ? undefined : -1}\n data-testid={findButtonTestId}\n >\n {findButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n {hasAfter && (\n <div className={styles.after}>\n <Button\n mode=\"tertiary\"\n size=\"m\"\n focusVisibleMode=\"inside\"\n hoverMode=\"opacity\"\n activeMode=\"opacity\"\n onClick={onCancel}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n >\n <span className={styles.afterTextClip}>{after}</span>\n </Button>\n </div>\n )}\n </RootComponent>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useMergeProps","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","warnOnce","Button","IconButton","RootComponent","Headline","VisuallyHidden","warn","Search","after","before","icon","iconProp","onIconClick","iconLabel","clearLabel","clearButtonTestId","noPadding","findButtonText","onFindButtonClick","findButtonTestId","hideClearButton","getRef","autoComplete","autoCapitalize","autoCorrect","disabled","list","maxLength","minLength","name","pattern","placeholder","placeholderProp","enterKeyHint","readOnly","required","value","form","id","idProp","inputMode","defaultValue","autoFocus","tabIndex","spellCheck","onChange","onChangeProp","onFocus","onFocusProp","onBlur","onBlurProp","slotProps","restProps","process","env","NODE_ENV","direction","isRtl","rootRest","root","getRootRef","getInputRef","onInputFocus","onInputBlur","inputRest","className","input","onClick","onClearButtonClick","onPointerDown","onClearButtonPointerDown","clearButtonRest","clearButton","inputRef","isFocused","setFocusedTrue","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","checkHasValue","e","currentTarget","density","adaptiveDensity","platform","hasAfter","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","showControls","compact","baseClassName","div","label","htmlFor","Component","type","level","weight","data-testid","mode","size","focusVisibleMode","activeMode","span"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Search/Search.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon16SearchOutline, Icon24Cancel } from '@vkontakte/icons';\nimport { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityConditionalRender } from '../../hooks/useAdaptivityConditionalRender';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useMergeProps } from '../../hooks/useMergeProps';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { touchEnabled } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { HasDataAttribute, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nconst warn = warnOnce('Search');\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: (Partial<IconButtonProps> & HasDataAttribute) | undefined,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'autoComplete'\n | 'autoCapitalize'\n | 'autoCorrect'\n | 'disabled'\n | 'list'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'pattern'\n | 'enterKeyHint'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'value'\n | 'form'\n | 'onChange'\n | 'onFocus'\n | 'onBlur'\n >,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onFocus' | 'onBlur'>,\n HasRootRef<HTMLDivElement> {\n /**\n * @deprecated Since 7.9.0. Вместо этого используйте `slotProps={ input: { getRootRef: ... } }`.\n */\n getRef?: React.Ref<HTMLInputElement> | undefined;\n /**\n * Свойства, которые можно прокинуть внутрь компонента:\n * - `root`: свойства для прокидывания в корень компонента;\n * - `input`: свойства для прокидывания в поле ввода;\n * - `clearButton`: свойства для прокидывания в кнопку очистки.\n */\n slotProps?:\n | {\n root?:\n | (React.HTMLAttributes<HTMLDivElement> & HasRootRef<HTMLDivElement> & HasDataAttribute)\n | undefined;\n input?: React.InputHTMLAttributes<HTMLInputElement> &\n HasRootRef<HTMLInputElement> &\n HasDataAttribute;\n clearButton?: React.HTMLAttributes<HTMLElement> &\n HasRootRef<HTMLElement> &\n HasDataAttribute;\n }\n | undefined;\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode | undefined;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode | undefined;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode) | undefined;\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement> | undefined;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string | undefined;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string | undefined;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string | undefined;\n /**\n * @deprecated Since 8.1.0. Будет удалено в **VKUI v10**. Вместо этого используйте `slotProps={ clearButton: { 'data-testid': ... } }`.\n *\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string | undefined;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean | undefined;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string | undefined;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement> | undefined;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string | undefined;\n /**\n * Скрывает кнопку очистки.\n */\n hideClearButton?: boolean | undefined;\n}\n\n/**\n * @see https://vkui.io/components/search\n */\nexport const Search = ({\n // SearchProps\n after = 'Отмена',\n before = <Icon16SearchOutline />,\n icon: iconProp,\n onIconClick,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n findButtonText = 'Найти',\n onFindButtonClick,\n findButtonTestId,\n hideClearButton,\n getRef,\n\n // input props\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n placeholder: placeholderProp = 'Поиск',\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n\n slotProps,\n ...restProps\n}: SearchProps): React.ReactNode => {\n /* istanbul ignore if: не проверяем в тестах */\n if (process.env.NODE_ENV === 'development') {\n if (getRef) {\n warn('Свойство `getRef` устаревшее, используйте `slotProps={ input: { getRootRef: ... } }`');\n }\n if (clearButtonTestId) {\n warn(\n \"Свойство `clearButtonTestId` устаревшее, используйте `slotProps={ clearButton: { 'data-testid': ... } }`\",\n );\n }\n }\n\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const rootRest = useMergeProps(restProps, slotProps?.root);\n\n const {\n id,\n placeholder,\n getRootRef: getInputRef,\n onChange,\n onFocus: onInputFocus,\n onBlur: onInputBlur,\n ...inputRest\n } = useMergeProps(\n {\n getRootRef: getRef,\n className: styles.nativeInput,\n placeholder: placeholderProp,\n autoComplete,\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n },\n slotProps?.input,\n );\n\n const {\n onClick: onClearButtonClick,\n onPointerDown: onClearButtonPointerDown,\n ...clearButtonRest\n } = useMergeProps({ className: styles.icon }, slotProps?.clearButton);\n\n const inputRef = useExternRef(getInputRef);\n const [isFocused, setFocusedTrue, setFocusedFalse] = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = id ? id : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputRest.value || inputRest.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { density = 'none' } = useAdaptivity();\n const { density: adaptiveDensity } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n onInputFocus && onInputFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n onInputBlur && onInputBlur(e);\n };\n\n const onCancel = React.useCallback(() => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n }, [inputRef]);\n\n const onIconClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => onIconClick?.(e),\n [onIconClick],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (inputRest.value !== undefined) {\n setHasValue(Boolean(inputRest.value));\n }\n }, [inputRest.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputRest.defaultValue));\n });\n\n const renderIconButton: RenderIconButtonFn = (icon, props = {}) => (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconClickStart}\n className={styles.icon}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n onClick={noop}\n {...props}\n >\n <VisuallyHidden>{iconLabel}</VisuallyHidden>\n {icon}\n </IconButton>\n );\n\n const showControls = Boolean(\n iconProp || !hideClearButton || (adaptiveDensity.compact && onFindButtonClick),\n );\n\n const onClearPointerDown: React.PointerEventHandler<HTMLElement> = (e) => {\n // Сначала вызываем внешний обработчик, затем локальную логику, чтобы можно было предотвратить обработку фокуса на поле ввода.\n onClearButtonPointerDown?.(e);\n\n e.preventDefault();\n inputRef.current?.focus();\n if (touchEnabled()) {\n onCancel();\n }\n };\n\n const onClearClick: React.MouseEventHandler<HTMLElement> = (e) => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n\n onClearButtonClick?.(e);\n };\n\n return (\n <RootComponent\n baseClassName={classNames(\n 'vkuiInternalSearch',\n styles.host,\n density === 'none' && styles.densityNone,\n density === 'compact' && styles.densityCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputRest.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n )}\n {...rootRest}\n >\n <div className={styles.field}>\n <label htmlFor={inputId} className={styles.label}>\n {placeholder}\n </label>\n <div className={styles.input}>\n {before}\n <Headline\n Component=\"input\"\n type=\"search\"\n level=\"1\"\n weight=\"3\"\n id={inputId}\n placeholder={placeholder}\n getRootRef={inputRef}\n onChange={callMultiple(onChange, checkHasValue)}\n onFocus={onFocus}\n onBlur={onBlur}\n {...inputRest}\n />\n </div>\n {showControls && (\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n {!hideClearButton && (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onClearPointerDown}\n onClick={onClearClick}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputRest.disabled}\n data-testid={clearButtonTestId}\n {...clearButtonRest}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n )}\n {adaptiveDensity.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveDensity.compact.className)}\n focusVisibleMode=\"inside\"\n onClick={onFindButtonClick}\n tabIndex={hasValue ? undefined : -1}\n data-testid={findButtonTestId}\n >\n {findButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n {hasAfter && (\n <div className={styles.after}>\n <Button\n mode=\"tertiary\"\n size=\"m\"\n focusVisibleMode=\"inside\"\n hoverMode=\"opacity\"\n activeMode=\"opacity\"\n onClick={onCancel}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n >\n <span className={styles.afterTextClip}>{after}</span>\n </Button>\n </div>\n )}\n </RootComponent>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useMergeProps","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","warnOnce","Button","IconButton","RootComponent","Headline","VisuallyHidden","warn","Search","after","before","icon","iconProp","onIconClick","iconLabel","clearLabel","clearButtonTestId","noPadding","findButtonText","onFindButtonClick","findButtonTestId","hideClearButton","getRef","autoComplete","autoCapitalize","autoCorrect","disabled","list","maxLength","minLength","name","pattern","placeholder","placeholderProp","enterKeyHint","readOnly","required","value","form","id","idProp","inputMode","defaultValue","autoFocus","tabIndex","spellCheck","onChange","onChangeProp","onFocus","onFocusProp","onBlur","onBlurProp","slotProps","restProps","process","env","NODE_ENV","direction","isRtl","rootRest","root","getRootRef","getInputRef","onInputFocus","onInputBlur","inputRest","className","input","onClick","onClearButtonClick","onPointerDown","onClearButtonPointerDown","clearButtonRest","clearButton","inputRef","isFocused","setFocusedTrue","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","checkHasValue","e","currentTarget","density","adaptiveDensity","platform","hasAfter","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","undefined","renderIconButton","props","hoverMode","showControls","compact","onClearPointerDown","preventDefault","focus","onClearClick","baseClassName","div","label","htmlFor","Component","type","level","weight","data-testid","mode","size","focusVisibleMode","activeMode","span"],"mappings":"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"}
@@ -101,16 +101,6 @@ autoComplete = 'off', autoCapitalize, autoCorrect, disabled, list, maxLength, mi
101
101
  const onIconClickStart = React.useCallback((e)=>onIconClick?.(e), [
102
102
  onIconClick
103
103
  ]);
104
- const onIconCancelClickStart = React.useCallback((e)=>{
105
- e.preventDefault();
106
- inputRef.current?.focus();
107
- if (touchEnabled()) {
108
- onCancel();
109
- }
110
- }, [
111
- inputRef,
112
- onCancel
113
- ]);
114
104
  useIsomorphicLayoutEffect(()=>{
115
105
  if (inputRest.value !== undefined) {
116
106
  setHasValue(Boolean(inputRest.value));
@@ -137,6 +127,25 @@ autoComplete = 'off', autoCapitalize, autoCorrect, disabled, list, maxLength, mi
137
127
  ]
138
128
  });
139
129
  const showControls = Boolean(iconProp || !hideClearButton || adaptiveDensity.compact && onFindButtonClick);
130
+ const onClearPointerDown = (e)=>{
131
+ // Сначала вызываем внешний обработчик, затем локальную логику, чтобы можно было предотвратить обработку фокуса на поле ввода.
132
+ onClearButtonPointerDown?.(e);
133
+ e.preventDefault();
134
+ inputRef.current?.focus();
135
+ if (touchEnabled()) {
136
+ onCancel();
137
+ }
138
+ };
139
+ const onClearClick = (e)=>{
140
+ // eslint-disable-next-line @typescript-eslint/unbound-method
141
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;
142
+ nativeInputValueSetter?.call(inputRef.current, '');
143
+ const ev2 = new Event('input', {
144
+ bubbles: true
145
+ });
146
+ inputRef.current?.dispatchEvent(ev2);
147
+ onClearButtonClick?.(e);
148
+ };
140
149
  return /*#__PURE__*/ _jsxs(RootComponent, {
141
150
  baseClassName: classNames('vkuiInternalSearch', styles.host, density === 'none' && styles.densityNone, density === 'compact' && styles.densityCompact, isFocused && styles.focused, hasValue && styles.hasValue, hasAfter && styles.hasAfter, iconProp && styles.hasIcon, inputRest.disabled && styles.disabled, !noPadding && styles.withPadding, isRtl && styles.rtl),
142
151
  ...rootRest,
@@ -174,8 +183,8 @@ autoComplete = 'off', autoCapitalize, autoCorrect, disabled, list, maxLength, mi
174
183
  iconProp && (typeof iconProp === 'function' ? iconProp(renderIconButton) : renderIconButton(iconProp)),
175
184
  !hideClearButton && /*#__PURE__*/ _jsxs(IconButton, {
176
185
  hoverMode: "opacity",
177
- onPointerDown: callMultiple(onIconCancelClickStart, onClearButtonPointerDown),
178
- onClick: callMultiple(onCancel, onClearButtonClick),
186
+ onPointerDown: onClearPointerDown,
187
+ onClick: onClearClick,
179
188
  tabIndex: hasValue ? undefined : -1,
180
189
  disabled: inputRest.disabled,
181
190
  "data-testid": clearButtonTestId,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Search/Search.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon16SearchOutline, Icon24Cancel } from '@vkontakte/icons';\nimport { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityConditionalRender } from '../../hooks/useAdaptivityConditionalRender';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useMergeProps } from '../../hooks/useMergeProps';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { touchEnabled } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { HasDataAttribute, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nconst warn = warnOnce('Search');\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: (Partial<IconButtonProps> & HasDataAttribute) | undefined,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'autoComplete'\n | 'autoCapitalize'\n | 'autoCorrect'\n | 'disabled'\n | 'list'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'pattern'\n | 'enterKeyHint'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'value'\n | 'form'\n | 'onChange'\n | 'onFocus'\n | 'onBlur'\n >,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onFocus' | 'onBlur'>,\n HasRootRef<HTMLDivElement> {\n /**\n * @deprecated Since 7.9.0. Вместо этого используйте `slotProps={ input: { getRootRef: ... } }`.\n */\n getRef?: React.Ref<HTMLInputElement> | undefined;\n /**\n * Свойства, которые можно прокинуть внутрь компонента:\n * - `root`: свойства для прокидывания в корень компонента;\n * - `input`: свойства для прокидывания в поле ввода;\n * - `clearButton`: свойства для прокидывания в кнопку очистки.\n */\n slotProps?:\n | {\n root?:\n | (React.HTMLAttributes<HTMLDivElement> & HasRootRef<HTMLDivElement> & HasDataAttribute)\n | undefined;\n input?: React.InputHTMLAttributes<HTMLInputElement> &\n HasRootRef<HTMLInputElement> &\n HasDataAttribute;\n clearButton?: React.HTMLAttributes<HTMLElement> &\n HasRootRef<HTMLElement> &\n HasDataAttribute;\n }\n | undefined;\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode | undefined;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode | undefined;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode) | undefined;\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement> | undefined;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string | undefined;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string | undefined;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string | undefined;\n /**\n * @deprecated Since 8.1.0. Будет удалено в **VKUI v10**. Вместо этого используйте `slotProps={ clearButton: { 'data-testid': ... } }`.\n *\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string | undefined;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean | undefined;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string | undefined;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement> | undefined;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string | undefined;\n /**\n * Скрывает кнопку очистки.\n */\n hideClearButton?: boolean | undefined;\n}\n\n/**\n * @see https://vkui.io/components/search\n */\nexport const Search = ({\n // SearchProps\n after = 'Отмена',\n before = <Icon16SearchOutline />,\n icon: iconProp,\n onIconClick,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n findButtonText = 'Найти',\n onFindButtonClick,\n findButtonTestId,\n hideClearButton,\n getRef,\n\n // input props\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n placeholder: placeholderProp = 'Поиск',\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n\n slotProps,\n ...restProps\n}: SearchProps): React.ReactNode => {\n /* istanbul ignore if: не проверяем в тестах */\n if (process.env.NODE_ENV === 'development') {\n if (getRef) {\n warn('Свойство `getRef` устаревшее, используйте `slotProps={ input: { getRootRef: ... } }`');\n }\n if (clearButtonTestId) {\n warn(\n \"Свойство `clearButtonTestId` устаревшее, используйте `slotProps={ clearButton: { 'data-testid': ... } }`\",\n );\n }\n }\n\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const rootRest = useMergeProps(restProps, slotProps?.root);\n\n const {\n id,\n placeholder,\n getRootRef: getInputRef,\n onChange,\n onFocus: onInputFocus,\n onBlur: onInputBlur,\n ...inputRest\n } = useMergeProps(\n {\n getRootRef: getRef,\n className: styles.nativeInput,\n placeholder: placeholderProp,\n autoComplete,\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n },\n slotProps?.input,\n );\n\n const {\n onClick: onClearButtonClick,\n onPointerDown: onClearButtonPointerDown,\n ...clearButtonRest\n } = useMergeProps({ className: styles.icon }, slotProps?.clearButton);\n\n const inputRef = useExternRef(getInputRef);\n const [isFocused, setFocusedTrue, setFocusedFalse] = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = id ? id : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputRest.value || inputRest.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { density = 'none' } = useAdaptivity();\n const { density: adaptiveDensity } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n onInputFocus && onInputFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n onInputBlur && onInputBlur(e);\n };\n\n const onCancel = React.useCallback(() => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n }, [inputRef]);\n\n const onIconClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => onIconClick?.(e),\n [onIconClick],\n );\n\n const onIconCancelClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n e.preventDefault();\n inputRef.current?.focus();\n if (touchEnabled()) {\n onCancel();\n }\n },\n [inputRef, onCancel],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (inputRest.value !== undefined) {\n setHasValue(Boolean(inputRest.value));\n }\n }, [inputRest.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputRest.defaultValue));\n });\n\n const renderIconButton: RenderIconButtonFn = (icon, props = {}) => (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconClickStart}\n className={styles.icon}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n onClick={noop}\n {...props}\n >\n <VisuallyHidden>{iconLabel}</VisuallyHidden>\n {icon}\n </IconButton>\n );\n\n const showControls = Boolean(\n iconProp || !hideClearButton || (adaptiveDensity.compact && onFindButtonClick),\n );\n\n return (\n <RootComponent\n baseClassName={classNames(\n 'vkuiInternalSearch',\n styles.host,\n density === 'none' && styles.densityNone,\n density === 'compact' && styles.densityCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputRest.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n )}\n {...rootRest}\n >\n <div className={styles.field}>\n <label htmlFor={inputId} className={styles.label}>\n {placeholder}\n </label>\n <div className={styles.input}>\n {before}\n <Headline\n Component=\"input\"\n type=\"search\"\n level=\"1\"\n weight=\"3\"\n id={inputId}\n placeholder={placeholder}\n getRootRef={inputRef}\n onChange={callMultiple(onChange, checkHasValue)}\n onFocus={onFocus}\n onBlur={onBlur}\n {...inputRest}\n />\n </div>\n {showControls && (\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n {!hideClearButton && (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={callMultiple(onIconCancelClickStart, onClearButtonPointerDown)}\n onClick={callMultiple(onCancel, onClearButtonClick)}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputRest.disabled}\n data-testid={clearButtonTestId}\n {...clearButtonRest}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n )}\n {adaptiveDensity.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveDensity.compact.className)}\n focusVisibleMode=\"inside\"\n onClick={onFindButtonClick}\n tabIndex={hasValue ? undefined : -1}\n data-testid={findButtonTestId}\n >\n {findButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n {hasAfter && (\n <div className={styles.after}>\n <Button\n mode=\"tertiary\"\n size=\"m\"\n focusVisibleMode=\"inside\"\n hoverMode=\"opacity\"\n activeMode=\"opacity\"\n onClick={onCancel}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n >\n <span className={styles.afterTextClip}>{after}</span>\n </Button>\n </div>\n )}\n </RootComponent>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useMergeProps","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","warnOnce","Button","IconButton","RootComponent","Headline","VisuallyHidden","styles","warn","Search","after","before","icon","iconProp","onIconClick","iconLabel","clearLabel","clearButtonTestId","noPadding","findButtonText","onFindButtonClick","findButtonTestId","hideClearButton","getRef","autoComplete","autoCapitalize","autoCorrect","disabled","list","maxLength","minLength","name","pattern","placeholder","placeholderProp","enterKeyHint","readOnly","required","value","form","id","idProp","inputMode","defaultValue","autoFocus","tabIndex","spellCheck","onChange","onChangeProp","onFocus","onFocusProp","onBlur","onBlurProp","slotProps","restProps","process","env","NODE_ENV","direction","isRtl","rootRest","root","getRootRef","getInputRef","onInputFocus","onInputBlur","inputRest","className","nativeInput","input","onClick","onClearButtonClick","onPointerDown","onClearButtonPointerDown","clearButtonRest","clearButton","inputRef","isFocused","setFocusedTrue","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","checkHasValue","e","currentTarget","density","adaptiveDensity","platform","hasAfter","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","showControls","compact","baseClassName","host","densityNone","densityCompact","focused","hasIcon","withPadding","rtl","div","field","label","htmlFor","Component","type","level","weight","controls","data-testid","mode","size","findButton","focusVisibleMode","activeMode","span","afterTextClip"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/Search/Search.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon16SearchOutline, Icon24Cancel } from '@vkontakte/icons';\nimport { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityConditionalRender } from '../../hooks/useAdaptivityConditionalRender';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useMergeProps } from '../../hooks/useMergeProps';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { touchEnabled } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { HasDataAttribute, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nconst warn = warnOnce('Search');\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: (Partial<IconButtonProps> & HasDataAttribute) | undefined,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'autoComplete'\n | 'autoCapitalize'\n | 'autoCorrect'\n | 'disabled'\n | 'list'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'pattern'\n | 'enterKeyHint'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'value'\n | 'form'\n | 'onChange'\n | 'onFocus'\n | 'onBlur'\n >,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onFocus' | 'onBlur'>,\n HasRootRef<HTMLDivElement> {\n /**\n * @deprecated Since 7.9.0. Вместо этого используйте `slotProps={ input: { getRootRef: ... } }`.\n */\n getRef?: React.Ref<HTMLInputElement> | undefined;\n /**\n * Свойства, которые можно прокинуть внутрь компонента:\n * - `root`: свойства для прокидывания в корень компонента;\n * - `input`: свойства для прокидывания в поле ввода;\n * - `clearButton`: свойства для прокидывания в кнопку очистки.\n */\n slotProps?:\n | {\n root?:\n | (React.HTMLAttributes<HTMLDivElement> & HasRootRef<HTMLDivElement> & HasDataAttribute)\n | undefined;\n input?: React.InputHTMLAttributes<HTMLInputElement> &\n HasRootRef<HTMLInputElement> &\n HasDataAttribute;\n clearButton?: React.HTMLAttributes<HTMLElement> &\n HasRootRef<HTMLElement> &\n HasDataAttribute;\n }\n | undefined;\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode | undefined;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode | undefined;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode) | undefined;\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement> | undefined;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string | undefined;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string | undefined;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string | undefined;\n /**\n * @deprecated Since 8.1.0. Будет удалено в **VKUI v10**. Вместо этого используйте `slotProps={ clearButton: { 'data-testid': ... } }`.\n *\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string | undefined;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean | undefined;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string | undefined;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement> | undefined;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string | undefined;\n /**\n * Скрывает кнопку очистки.\n */\n hideClearButton?: boolean | undefined;\n}\n\n/**\n * @see https://vkui.io/components/search\n */\nexport const Search = ({\n // SearchProps\n after = 'Отмена',\n before = <Icon16SearchOutline />,\n icon: iconProp,\n onIconClick,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n findButtonText = 'Найти',\n onFindButtonClick,\n findButtonTestId,\n hideClearButton,\n getRef,\n\n // input props\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n placeholder: placeholderProp = 'Поиск',\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n\n slotProps,\n ...restProps\n}: SearchProps): React.ReactNode => {\n /* istanbul ignore if: не проверяем в тестах */\n if (process.env.NODE_ENV === 'development') {\n if (getRef) {\n warn('Свойство `getRef` устаревшее, используйте `slotProps={ input: { getRootRef: ... } }`');\n }\n if (clearButtonTestId) {\n warn(\n \"Свойство `clearButtonTestId` устаревшее, используйте `slotProps={ clearButton: { 'data-testid': ... } }`\",\n );\n }\n }\n\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const rootRest = useMergeProps(restProps, slotProps?.root);\n\n const {\n id,\n placeholder,\n getRootRef: getInputRef,\n onChange,\n onFocus: onInputFocus,\n onBlur: onInputBlur,\n ...inputRest\n } = useMergeProps(\n {\n getRootRef: getRef,\n className: styles.nativeInput,\n placeholder: placeholderProp,\n autoComplete,\n autoCapitalize,\n autoCorrect,\n disabled,\n list,\n maxLength,\n minLength,\n name,\n pattern,\n enterKeyHint,\n readOnly,\n required,\n value,\n form,\n id: idProp,\n inputMode,\n defaultValue,\n autoFocus,\n tabIndex,\n spellCheck,\n onChange: onChangeProp,\n onFocus: onFocusProp,\n onBlur: onBlurProp,\n },\n slotProps?.input,\n );\n\n const {\n onClick: onClearButtonClick,\n onPointerDown: onClearButtonPointerDown,\n ...clearButtonRest\n } = useMergeProps({ className: styles.icon }, slotProps?.clearButton);\n\n const inputRef = useExternRef(getInputRef);\n const [isFocused, setFocusedTrue, setFocusedFalse] = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = id ? id : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputRest.value || inputRest.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { density = 'none' } = useAdaptivity();\n const { density: adaptiveDensity } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n onInputFocus && onInputFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n onInputBlur && onInputBlur(e);\n };\n\n const onCancel = React.useCallback(() => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n }, [inputRef]);\n\n const onIconClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => onIconClick?.(e),\n [onIconClick],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (inputRest.value !== undefined) {\n setHasValue(Boolean(inputRest.value));\n }\n }, [inputRest.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputRest.defaultValue));\n });\n\n const renderIconButton: RenderIconButtonFn = (icon, props = {}) => (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconClickStart}\n className={styles.icon}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n onClick={noop}\n {...props}\n >\n <VisuallyHidden>{iconLabel}</VisuallyHidden>\n {icon}\n </IconButton>\n );\n\n const showControls = Boolean(\n iconProp || !hideClearButton || (adaptiveDensity.compact && onFindButtonClick),\n );\n\n const onClearPointerDown: React.PointerEventHandler<HTMLElement> = (e) => {\n // Сначала вызываем внешний обработчик, затем локальную логику, чтобы можно было предотвратить обработку фокуса на поле ввода.\n onClearButtonPointerDown?.(e);\n\n e.preventDefault();\n inputRef.current?.focus();\n if (touchEnabled()) {\n onCancel();\n }\n };\n\n const onClearClick: React.MouseEventHandler<HTMLElement> = (e) => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n\n onClearButtonClick?.(e);\n };\n\n return (\n <RootComponent\n baseClassName={classNames(\n 'vkuiInternalSearch',\n styles.host,\n density === 'none' && styles.densityNone,\n density === 'compact' && styles.densityCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputRest.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n )}\n {...rootRest}\n >\n <div className={styles.field}>\n <label htmlFor={inputId} className={styles.label}>\n {placeholder}\n </label>\n <div className={styles.input}>\n {before}\n <Headline\n Component=\"input\"\n type=\"search\"\n level=\"1\"\n weight=\"3\"\n id={inputId}\n placeholder={placeholder}\n getRootRef={inputRef}\n onChange={callMultiple(onChange, checkHasValue)}\n onFocus={onFocus}\n onBlur={onBlur}\n {...inputRest}\n />\n </div>\n {showControls && (\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n {!hideClearButton && (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onClearPointerDown}\n onClick={onClearClick}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputRest.disabled}\n data-testid={clearButtonTestId}\n {...clearButtonRest}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n )}\n {adaptiveDensity.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveDensity.compact.className)}\n focusVisibleMode=\"inside\"\n onClick={onFindButtonClick}\n tabIndex={hasValue ? undefined : -1}\n data-testid={findButtonTestId}\n >\n {findButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n {hasAfter && (\n <div className={styles.after}>\n <Button\n mode=\"tertiary\"\n size=\"m\"\n focusVisibleMode=\"inside\"\n hoverMode=\"opacity\"\n activeMode=\"opacity\"\n onClick={onCancel}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n >\n <span className={styles.afterTextClip}>{after}</span>\n </Button>\n </div>\n )}\n </RootComponent>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useMergeProps","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","warnOnce","Button","IconButton","RootComponent","Headline","VisuallyHidden","styles","warn","Search","after","before","icon","iconProp","onIconClick","iconLabel","clearLabel","clearButtonTestId","noPadding","findButtonText","onFindButtonClick","findButtonTestId","hideClearButton","getRef","autoComplete","autoCapitalize","autoCorrect","disabled","list","maxLength","minLength","name","pattern","placeholder","placeholderProp","enterKeyHint","readOnly","required","value","form","id","idProp","inputMode","defaultValue","autoFocus","tabIndex","spellCheck","onChange","onChangeProp","onFocus","onFocusProp","onBlur","onBlurProp","slotProps","restProps","process","env","NODE_ENV","direction","isRtl","rootRest","root","getRootRef","getInputRef","onInputFocus","onInputBlur","inputRest","className","nativeInput","input","onClick","onClearButtonClick","onPointerDown","onClearButtonPointerDown","clearButtonRest","clearButton","inputRef","isFocused","setFocusedTrue","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","checkHasValue","e","currentTarget","density","adaptiveDensity","platform","hasAfter","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","undefined","renderIconButton","props","hoverMode","showControls","compact","onClearPointerDown","preventDefault","focus","onClearClick","baseClassName","host","densityNone","densityCompact","focused","hasIcon","withPadding","rtl","div","field","label","htmlFor","Component","type","level","weight","controls","data-testid","mode","size","findButton","focusVisibleMode","activeMode","span","afterTextClip"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "version": "8.1.0",
3
+ "version": "8.1.1",
4
4
  "name": "@vkontakte/vkui",
5
5
  "description": "VKUI library",
6
6
  "module": "./dist/index.js",
@@ -288,17 +288,6 @@ export const Search = ({
288
288
  [onIconClick],
289
289
  );
290
290
 
291
- const onIconCancelClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(
292
- (e) => {
293
- e.preventDefault();
294
- inputRef.current?.focus();
295
- if (touchEnabled()) {
296
- onCancel();
297
- }
298
- },
299
- [inputRef, onCancel],
300
- );
301
-
302
291
  useIsomorphicLayoutEffect(() => {
303
292
  if (inputRest.value !== undefined) {
304
293
  setHasValue(Boolean(inputRest.value));
@@ -328,6 +317,31 @@ export const Search = ({
328
317
  iconProp || !hideClearButton || (adaptiveDensity.compact && onFindButtonClick),
329
318
  );
330
319
 
320
+ const onClearPointerDown: React.PointerEventHandler<HTMLElement> = (e) => {
321
+ // Сначала вызываем внешний обработчик, затем локальную логику, чтобы можно было предотвратить обработку фокуса на поле ввода.
322
+ onClearButtonPointerDown?.(e);
323
+
324
+ e.preventDefault();
325
+ inputRef.current?.focus();
326
+ if (touchEnabled()) {
327
+ onCancel();
328
+ }
329
+ };
330
+
331
+ const onClearClick: React.MouseEventHandler<HTMLElement> = (e) => {
332
+ // eslint-disable-next-line @typescript-eslint/unbound-method
333
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
334
+ HTMLInputElement.prototype,
335
+ 'value',
336
+ )?.set;
337
+ nativeInputValueSetter?.call(inputRef.current, '');
338
+
339
+ const ev2 = new Event('input', { bubbles: true });
340
+ inputRef.current?.dispatchEvent(ev2);
341
+
342
+ onClearButtonClick?.(e);
343
+ };
344
+
331
345
  return (
332
346
  <RootComponent
333
347
  baseClassName={classNames(
@@ -374,8 +388,8 @@ export const Search = ({
374
388
  {!hideClearButton && (
375
389
  <IconButton
376
390
  hoverMode="opacity"
377
- onPointerDown={callMultiple(onIconCancelClickStart, onClearButtonPointerDown)}
378
- onClick={callMultiple(onCancel, onClearButtonClick)}
391
+ onPointerDown={onClearPointerDown}
392
+ onClick={onClearClick}
379
393
  tabIndex={hasValue ? undefined : -1}
380
394
  disabled={inputRest.disabled}
381
395
  data-testid={clearButtonTestId}