@vkontakte/vkui 7.3.8 → 7.3.9
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/dist/components/Search/Search.d.ts +5 -1
- package/dist/components/Search/Search.d.ts.map +1 -1
- package/dist/components/Search/Search.js +6 -4
- package/dist/components/Search/Search.js.map +1 -1
- package/dist/cssm/components/Search/Search.js +4 -3
- package/dist/cssm/components/Search/Search.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Search/Search.tsx +44 -31
|
@@ -51,9 +51,13 @@ export interface SearchProps extends React.InputHTMLAttributes<HTMLInputElement>
|
|
|
51
51
|
* Передает атрибут `data-testid` для кнопки поиска.
|
|
52
52
|
*/
|
|
53
53
|
findButtonTestId?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Скрывает кнопку очистки.
|
|
56
|
+
*/
|
|
57
|
+
hideClearButton?: boolean;
|
|
54
58
|
}
|
|
55
59
|
/**
|
|
56
60
|
* @see https://vkcom.github.io/VKUI/#/Search
|
|
57
61
|
*/
|
|
58
|
-
export declare const Search: ({ id: idProp, before, className, placeholder, after, getRef, icon: iconProp, onIconClick, style, autoComplete, onChange, iconLabel, clearLabel, clearButtonTestId, noPadding, getRootRef, findButtonText, findButtonTestId, onFindButtonClick, ...inputProps }: SearchProps) => React.ReactNode;
|
|
62
|
+
export declare const Search: ({ id: idProp, before, className, placeholder, after, getRef, icon: iconProp, onIconClick, style, autoComplete, onChange, iconLabel, clearLabel, clearButtonTestId, noPadding, getRootRef, findButtonText, findButtonTestId, onFindButtonClick, hideClearButton, ...inputProps }: SearchProps) => React.ReactNode;
|
|
59
63
|
//# sourceMappingURL=Search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../../src/components/Search/Search.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExE,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAK5E,MAAM,MAAM,kBAAkB,GAAG,CAC/B,IAAI,EAAE,KAAK,CAAC,SAAS,EACrB,KAAK,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,gBAAgB,KAChD,KAAK,CAAC,YAAY,CAAC;AAExB,MAAM,WAAW,WACf,SAAQ,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EACjD,UAAU,CAAC,cAAc,CAAC,EAC1B,MAAM,CAAC,gBAAgB,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,QAAQ,EAAE,kBAAkB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7E;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACrD;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACzD;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,GAAI,
|
|
1
|
+
{"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../../src/components/Search/Search.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExE,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAK5E,MAAM,MAAM,kBAAkB,GAAG,CAC/B,IAAI,EAAE,KAAK,CAAC,SAAS,EACrB,KAAK,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,gBAAgB,KAChD,KAAK,CAAC,YAAY,CAAC;AAExB,MAAM,WAAW,WACf,SAAQ,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EACjD,UAAU,CAAC,cAAc,CAAC,EAC1B,MAAM,CAAC,gBAAgB,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,QAAQ,EAAE,kBAAkB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7E;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACrD;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACzD;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,GAAI,iRAsBpB,WAAW,KAAG,KAAK,CAAC,SA0LtB,CAAC"}
|
|
@@ -23,7 +23,7 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
|
|
|
23
23
|
/**
|
|
24
24
|
* @see https://vkcom.github.io/VKUI/#/Search
|
|
25
25
|
*/ export const Search = (_param)=>{
|
|
26
|
-
var { id: idProp, before = /*#__PURE__*/ _jsx(Icon16SearchOutline, {}), className, placeholder = 'Поиск', after = 'Отмена', getRef, icon: iconProp, onIconClick, style, autoComplete = 'off', onChange, iconLabel, clearLabel = 'Очистить', clearButtonTestId, noPadding, getRootRef, findButtonText = 'Найти', findButtonTestId, onFindButtonClick } = _param, inputProps = _object_without_properties(_param, [
|
|
26
|
+
var { id: idProp, before = /*#__PURE__*/ _jsx(Icon16SearchOutline, {}), className, placeholder = 'Поиск', after = 'Отмена', getRef, icon: iconProp, onIconClick, style, autoComplete = 'off', onChange, iconLabel, clearLabel = 'Очистить', clearButtonTestId, noPadding, getRootRef, findButtonText = 'Найти', findButtonTestId, onFindButtonClick, hideClearButton } = _param, inputProps = _object_without_properties(_param, [
|
|
27
27
|
"id",
|
|
28
28
|
"before",
|
|
29
29
|
"className",
|
|
@@ -42,7 +42,8 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
|
|
|
42
42
|
"getRootRef",
|
|
43
43
|
"findButtonText",
|
|
44
44
|
"findButtonTestId",
|
|
45
|
-
"onFindButtonClick"
|
|
45
|
+
"onFindButtonClick",
|
|
46
|
+
"hideClearButton"
|
|
46
47
|
]);
|
|
47
48
|
const direction = useConfigDirection();
|
|
48
49
|
const isRtl = direction === 'rtl';
|
|
@@ -115,6 +116,7 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
|
|
|
115
116
|
icon
|
|
116
117
|
]
|
|
117
118
|
}));
|
|
119
|
+
const showControls = Boolean(iconProp || !hideClearButton || adaptiveSizeY.compact && onFindButtonClick);
|
|
118
120
|
return /*#__PURE__*/ _jsxs("div", {
|
|
119
121
|
className: classNames('vkuiInternalSearch', "vkuiSearch__host", sizeY === 'none' && "vkuiSearch__sizeYNone", sizeY === 'compact' && "vkuiSearch__sizeYCompact", isFocused && "vkuiSearch__focused", hasValue && "vkuiSearch__hasValue", hasAfter && "vkuiSearch__hasAfter", iconProp && "vkuiSearch__hasIcon", inputProps.disabled && "vkuiSearch__disabled", !noPadding && "vkuiSearch__withPadding", isRtl && "vkuiSearch__rtl", className),
|
|
120
122
|
ref: getRootRef,
|
|
@@ -149,11 +151,11 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
|
|
|
149
151
|
}))
|
|
150
152
|
]
|
|
151
153
|
}),
|
|
152
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
154
|
+
showControls && /*#__PURE__*/ _jsxs("div", {
|
|
153
155
|
className: "vkuiSearch__controls",
|
|
154
156
|
children: [
|
|
155
157
|
iconProp && (typeof iconProp === 'function' ? iconProp(renderIconButton) : renderIconButton(iconProp)),
|
|
156
|
-
/*#__PURE__*/ _jsxs(IconButton, {
|
|
158
|
+
!hideClearButton && /*#__PURE__*/ _jsxs(IconButton, {
|
|
157
159
|
hoverMode: "opacity",
|
|
158
160
|
onPointerDown: onIconCancelClickStart,
|
|
159
161
|
onClick: onCancel,
|
|
@@ -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 { 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 type { HasDataAttribute, HasRef, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: Partial<IconButtonProps> & HasDataAttribute,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLInputElement> {\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode);\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement>;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement>;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Search\n */\nexport const Search = ({\n id: idProp,\n before = <Icon16SearchOutline />,\n className,\n placeholder = 'Поиск',\n after = 'Отмена',\n getRef,\n icon: iconProp,\n onIconClick,\n style,\n autoComplete = 'off',\n onChange,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n getRootRef,\n findButtonText = 'Найти',\n findButtonTestId,\n onFindButtonClick,\n ...inputProps\n}: SearchProps): React.ReactNode => {\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n const inputRef = useExternRef(getRef);\n const {\n value: isFocused,\n setTrue: setFocusedTrue,\n setFalse: setFocusedFalse,\n } = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = idProp ? idProp : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputProps.value || inputProps.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { sizeY = 'none' } = useAdaptivity();\n const { sizeY: adaptiveSizeY } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n inputProps.onFocus && inputProps.onFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n inputProps.onBlur && inputProps.onBlur(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 (inputProps.value !== undefined) {\n setHasValue(Boolean(inputProps.value));\n }\n }, [inputProps.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputProps.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 return (\n <div\n className={classNames(\n 'vkuiInternalSearch',\n styles.host,\n sizeY === 'none' && styles.sizeYNone,\n sizeY === 'compact' && styles.sizeYCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputProps.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n className,\n )}\n ref={getRootRef}\n style={style}\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 {...inputProps}\n id={inputId}\n placeholder={placeholder}\n autoComplete={autoComplete}\n getRootRef={inputRef}\n className={styles.nativeInput}\n onFocus={onFocus}\n onBlur={onBlur}\n onChange={callMultiple(onChange, checkHasValue)}\n />\n </div>\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconCancelClickStart}\n onClick={onCancel}\n className={styles.icon}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputProps.disabled}\n data-testid={clearButtonTestId}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n {adaptiveSizeY.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveSizeY.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 </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 </div>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","Button","IconButton","Headline","VisuallyHidden","Search","id","idProp","before","className","placeholder","after","getRef","icon","iconProp","onIconClick","style","autoComplete","onChange","iconLabel","clearLabel","clearButtonTestId","noPadding","getRootRef","findButtonText","findButtonTestId","onFindButtonClick","inputProps","direction","isRtl","inputRef","value","isFocused","setTrue","setFocusedTrue","setFalse","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","defaultValue","checkHasValue","e","currentTarget","sizeY","adaptiveSizeY","platform","hasAfter","onFocus","onBlur","onCancel","useCallback","Object","nativeInputValueSetter","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","onPointerDown","onClick","div","disabled","ref","label","htmlFor","Component","type","level","weight","tabIndex","data-testid","compact","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 { 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 type { HasDataAttribute, HasRef, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: Partial<IconButtonProps> & HasDataAttribute,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLInputElement> {\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode);\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement>;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement>;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string;\n /**\n * Скрывает кнопку очистки.\n */\n hideClearButton?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Search\n */\nexport const Search = ({\n id: idProp,\n before = <Icon16SearchOutline />,\n className,\n placeholder = 'Поиск',\n after = 'Отмена',\n getRef,\n icon: iconProp,\n onIconClick,\n style,\n autoComplete = 'off',\n onChange,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n getRootRef,\n findButtonText = 'Найти',\n findButtonTestId,\n onFindButtonClick,\n hideClearButton,\n ...inputProps\n}: SearchProps): React.ReactNode => {\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n const inputRef = useExternRef(getRef);\n const {\n value: isFocused,\n setTrue: setFocusedTrue,\n setFalse: setFocusedFalse,\n } = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = idProp ? idProp : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputProps.value || inputProps.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { sizeY = 'none' } = useAdaptivity();\n const { sizeY: adaptiveSizeY } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n inputProps.onFocus && inputProps.onFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n inputProps.onBlur && inputProps.onBlur(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 (inputProps.value !== undefined) {\n setHasValue(Boolean(inputProps.value));\n }\n }, [inputProps.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputProps.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 || (adaptiveSizeY.compact && onFindButtonClick),\n );\n\n return (\n <div\n className={classNames(\n 'vkuiInternalSearch',\n styles.host,\n sizeY === 'none' && styles.sizeYNone,\n sizeY === 'compact' && styles.sizeYCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputProps.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n className,\n )}\n ref={getRootRef}\n style={style}\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 {...inputProps}\n id={inputId}\n placeholder={placeholder}\n autoComplete={autoComplete}\n getRootRef={inputRef}\n className={styles.nativeInput}\n onFocus={onFocus}\n onBlur={onBlur}\n onChange={callMultiple(onChange, checkHasValue)}\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={onIconCancelClickStart}\n onClick={onCancel}\n className={styles.icon}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputProps.disabled}\n data-testid={clearButtonTestId}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n )}\n {adaptiveSizeY.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveSizeY.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 </div>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","Button","IconButton","Headline","VisuallyHidden","Search","id","idProp","before","className","placeholder","after","getRef","icon","iconProp","onIconClick","style","autoComplete","onChange","iconLabel","clearLabel","clearButtonTestId","noPadding","getRootRef","findButtonText","findButtonTestId","onFindButtonClick","hideClearButton","inputProps","direction","isRtl","inputRef","value","isFocused","setTrue","setFocusedTrue","setFalse","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","defaultValue","checkHasValue","e","currentTarget","sizeY","adaptiveSizeY","platform","hasAfter","onFocus","onBlur","onCancel","useCallback","Object","nativeInputValueSetter","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","onPointerDown","onClick","showControls","compact","div","disabled","ref","label","htmlFor","Component","type","level","weight","tabIndex","data-testid","mode","size","focusVisibleMode","activeMode","span"],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
|
|
|
20
20
|
import styles from "./Search.module.css";
|
|
21
21
|
/**
|
|
22
22
|
* @see https://vkcom.github.io/VKUI/#/Search
|
|
23
|
-
*/ export const Search = ({ id: idProp, before = /*#__PURE__*/ _jsx(Icon16SearchOutline, {}), className, placeholder = 'Поиск', after = 'Отмена', getRef, icon: iconProp, onIconClick, style, autoComplete = 'off', onChange, iconLabel, clearLabel = 'Очистить', clearButtonTestId, noPadding, getRootRef, findButtonText = 'Найти', findButtonTestId, onFindButtonClick, ...inputProps })=>{
|
|
23
|
+
*/ export const Search = ({ id: idProp, before = /*#__PURE__*/ _jsx(Icon16SearchOutline, {}), className, placeholder = 'Поиск', after = 'Отмена', getRef, icon: iconProp, onIconClick, style, autoComplete = 'off', onChange, iconLabel, clearLabel = 'Очистить', clearButtonTestId, noPadding, getRootRef, findButtonText = 'Найти', findButtonTestId, onFindButtonClick, hideClearButton, ...inputProps })=>{
|
|
24
24
|
const direction = useConfigDirection();
|
|
25
25
|
const isRtl = direction === 'rtl';
|
|
26
26
|
const inputRef = useExternRef(getRef);
|
|
@@ -90,6 +90,7 @@ import styles from "./Search.module.css";
|
|
|
90
90
|
icon
|
|
91
91
|
]
|
|
92
92
|
});
|
|
93
|
+
const showControls = Boolean(iconProp || !hideClearButton || adaptiveSizeY.compact && onFindButtonClick);
|
|
93
94
|
return /*#__PURE__*/ _jsxs("div", {
|
|
94
95
|
className: classNames('vkuiInternalSearch', styles.host, sizeY === 'none' && styles.sizeYNone, sizeY === 'compact' && styles.sizeYCompact, isFocused && styles.focused, hasValue && styles.hasValue, hasAfter && styles.hasAfter, iconProp && styles.hasIcon, inputProps.disabled && styles.disabled, !noPadding && styles.withPadding, isRtl && styles.rtl, className),
|
|
95
96
|
ref: getRootRef,
|
|
@@ -124,11 +125,11 @@ import styles from "./Search.module.css";
|
|
|
124
125
|
})
|
|
125
126
|
]
|
|
126
127
|
}),
|
|
127
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
128
|
+
showControls && /*#__PURE__*/ _jsxs("div", {
|
|
128
129
|
className: styles.controls,
|
|
129
130
|
children: [
|
|
130
131
|
iconProp && (typeof iconProp === 'function' ? iconProp(renderIconButton) : renderIconButton(iconProp)),
|
|
131
|
-
/*#__PURE__*/ _jsxs(IconButton, {
|
|
132
|
+
!hideClearButton && /*#__PURE__*/ _jsxs(IconButton, {
|
|
132
133
|
hoverMode: "opacity",
|
|
133
134
|
onPointerDown: onIconCancelClickStart,
|
|
134
135
|
onClick: onCancel,
|
|
@@ -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 { 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 type { HasDataAttribute, HasRef, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: Partial<IconButtonProps> & HasDataAttribute,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLInputElement> {\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode);\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement>;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement>;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Search\n */\nexport const Search = ({\n id: idProp,\n before = <Icon16SearchOutline />,\n className,\n placeholder = 'Поиск',\n after = 'Отмена',\n getRef,\n icon: iconProp,\n onIconClick,\n style,\n autoComplete = 'off',\n onChange,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n getRootRef,\n findButtonText = 'Найти',\n findButtonTestId,\n onFindButtonClick,\n ...inputProps\n}: SearchProps): React.ReactNode => {\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n const inputRef = useExternRef(getRef);\n const {\n value: isFocused,\n setTrue: setFocusedTrue,\n setFalse: setFocusedFalse,\n } = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = idProp ? idProp : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputProps.value || inputProps.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { sizeY = 'none' } = useAdaptivity();\n const { sizeY: adaptiveSizeY } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n inputProps.onFocus && inputProps.onFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n inputProps.onBlur && inputProps.onBlur(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 (inputProps.value !== undefined) {\n setHasValue(Boolean(inputProps.value));\n }\n }, [inputProps.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputProps.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 return (\n <div\n className={classNames(\n 'vkuiInternalSearch',\n styles.host,\n sizeY === 'none' && styles.sizeYNone,\n sizeY === 'compact' && styles.sizeYCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputProps.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n className,\n )}\n ref={getRootRef}\n style={style}\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 {...inputProps}\n id={inputId}\n placeholder={placeholder}\n autoComplete={autoComplete}\n getRootRef={inputRef}\n className={styles.nativeInput}\n onFocus={onFocus}\n onBlur={onBlur}\n onChange={callMultiple(onChange, checkHasValue)}\n />\n </div>\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconCancelClickStart}\n onClick={onCancel}\n className={styles.icon}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputProps.disabled}\n data-testid={clearButtonTestId}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n {adaptiveSizeY.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveSizeY.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 </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 </div>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","Button","IconButton","Headline","VisuallyHidden","styles","Search","id","idProp","before","className","placeholder","after","getRef","icon","iconProp","onIconClick","style","autoComplete","onChange","iconLabel","clearLabel","clearButtonTestId","noPadding","getRootRef","findButtonText","findButtonTestId","onFindButtonClick","inputProps","direction","isRtl","inputRef","value","isFocused","setTrue","setFocusedTrue","setFalse","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","defaultValue","checkHasValue","e","currentTarget","sizeY","adaptiveSizeY","platform","hasAfter","onFocus","onBlur","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","onPointerDown","onClick","div","host","sizeYNone","sizeYCompact","focused","hasIcon","disabled","withPadding","rtl","ref","field","label","htmlFor","input","Component","type","level","weight","nativeInput","controls","tabIndex","data-testid","compact","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 { 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 type { HasDataAttribute, HasRef, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: Partial<IconButtonProps> & HasDataAttribute,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLInputElement> {\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode);\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement>;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement>;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string;\n /**\n * Скрывает кнопку очистки.\n */\n hideClearButton?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Search\n */\nexport const Search = ({\n id: idProp,\n before = <Icon16SearchOutline />,\n className,\n placeholder = 'Поиск',\n after = 'Отмена',\n getRef,\n icon: iconProp,\n onIconClick,\n style,\n autoComplete = 'off',\n onChange,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n getRootRef,\n findButtonText = 'Найти',\n findButtonTestId,\n onFindButtonClick,\n hideClearButton,\n ...inputProps\n}: SearchProps): React.ReactNode => {\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n const inputRef = useExternRef(getRef);\n const {\n value: isFocused,\n setTrue: setFocusedTrue,\n setFalse: setFocusedFalse,\n } = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = idProp ? idProp : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputProps.value || inputProps.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { sizeY = 'none' } = useAdaptivity();\n const { sizeY: adaptiveSizeY } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n inputProps.onFocus && inputProps.onFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n inputProps.onBlur && inputProps.onBlur(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 (inputProps.value !== undefined) {\n setHasValue(Boolean(inputProps.value));\n }\n }, [inputProps.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputProps.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 || (adaptiveSizeY.compact && onFindButtonClick),\n );\n\n return (\n <div\n className={classNames(\n 'vkuiInternalSearch',\n styles.host,\n sizeY === 'none' && styles.sizeYNone,\n sizeY === 'compact' && styles.sizeYCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputProps.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n className,\n )}\n ref={getRootRef}\n style={style}\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 {...inputProps}\n id={inputId}\n placeholder={placeholder}\n autoComplete={autoComplete}\n getRootRef={inputRef}\n className={styles.nativeInput}\n onFocus={onFocus}\n onBlur={onBlur}\n onChange={callMultiple(onChange, checkHasValue)}\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={onIconCancelClickStart}\n onClick={onCancel}\n className={styles.icon}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputProps.disabled}\n data-testid={clearButtonTestId}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n )}\n {adaptiveSizeY.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveSizeY.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 </div>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","Button","IconButton","Headline","VisuallyHidden","styles","Search","id","idProp","before","className","placeholder","after","getRef","icon","iconProp","onIconClick","style","autoComplete","onChange","iconLabel","clearLabel","clearButtonTestId","noPadding","getRootRef","findButtonText","findButtonTestId","onFindButtonClick","hideClearButton","inputProps","direction","isRtl","inputRef","value","isFocused","setTrue","setFocusedTrue","setFalse","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","defaultValue","checkHasValue","e","currentTarget","sizeY","adaptiveSizeY","platform","hasAfter","onFocus","onBlur","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","onPointerDown","onClick","showControls","compact","div","host","sizeYNone","sizeYCompact","focused","hasIcon","disabled","withPadding","rtl","ref","field","label","htmlFor","input","Component","type","level","weight","nativeInput","controls","tabIndex","data-testid","mode","size","findButton","focusVisibleMode","activeMode","span","afterTextClip"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -77,6 +77,10 @@ export interface SearchProps
|
|
|
77
77
|
* Передает атрибут `data-testid` для кнопки поиска.
|
|
78
78
|
*/
|
|
79
79
|
findButtonTestId?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Скрывает кнопку очистки.
|
|
82
|
+
*/
|
|
83
|
+
hideClearButton?: boolean;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
/**
|
|
@@ -102,6 +106,7 @@ export const Search = ({
|
|
|
102
106
|
findButtonText = 'Найти',
|
|
103
107
|
findButtonTestId,
|
|
104
108
|
onFindButtonClick,
|
|
109
|
+
hideClearButton,
|
|
105
110
|
...inputProps
|
|
106
111
|
}: SearchProps): React.ReactNode => {
|
|
107
112
|
const direction = useConfigDirection();
|
|
@@ -190,6 +195,10 @@ export const Search = ({
|
|
|
190
195
|
</IconButton>
|
|
191
196
|
);
|
|
192
197
|
|
|
198
|
+
const showControls = Boolean(
|
|
199
|
+
iconProp || !hideClearButton || (adaptiveSizeY.compact && onFindButtonClick),
|
|
200
|
+
);
|
|
201
|
+
|
|
193
202
|
return (
|
|
194
203
|
<div
|
|
195
204
|
className={classNames(
|
|
@@ -231,37 +240,41 @@ export const Search = ({
|
|
|
231
240
|
onChange={callMultiple(onChange, checkHasValue)}
|
|
232
241
|
/>
|
|
233
242
|
</div>
|
|
234
|
-
|
|
235
|
-
{
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
243
|
+
{showControls && (
|
|
244
|
+
<div className={styles.controls}>
|
|
245
|
+
{iconProp &&
|
|
246
|
+
(typeof iconProp === 'function'
|
|
247
|
+
? iconProp(renderIconButton)
|
|
248
|
+
: renderIconButton(iconProp))}
|
|
249
|
+
{!hideClearButton && (
|
|
250
|
+
<IconButton
|
|
251
|
+
hoverMode="opacity"
|
|
252
|
+
onPointerDown={onIconCancelClickStart}
|
|
253
|
+
onClick={onCancel}
|
|
254
|
+
className={styles.icon}
|
|
255
|
+
tabIndex={hasValue ? undefined : -1}
|
|
256
|
+
disabled={inputProps.disabled}
|
|
257
|
+
data-testid={clearButtonTestId}
|
|
258
|
+
>
|
|
259
|
+
<VisuallyHidden>{clearLabel}</VisuallyHidden>
|
|
260
|
+
{platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}
|
|
261
|
+
</IconButton>
|
|
262
|
+
)}
|
|
263
|
+
{adaptiveSizeY.compact && onFindButtonClick && (
|
|
264
|
+
<Button
|
|
265
|
+
mode="primary"
|
|
266
|
+
size="m"
|
|
267
|
+
className={classNames(styles.findButton, adaptiveSizeY.compact.className)}
|
|
268
|
+
focusVisibleMode="inside"
|
|
269
|
+
onClick={onFindButtonClick}
|
|
270
|
+
tabIndex={hasValue ? undefined : -1}
|
|
271
|
+
data-testid={findButtonTestId}
|
|
272
|
+
>
|
|
273
|
+
{findButtonText}
|
|
274
|
+
</Button>
|
|
275
|
+
)}
|
|
276
|
+
</div>
|
|
277
|
+
)}
|
|
265
278
|
</div>
|
|
266
279
|
{hasAfter && (
|
|
267
280
|
<div className={styles.after}>
|