@vkontakte/vkui 7.5.2 → 7.5.4
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/ChipsInputBase/ChipsInputBase.d.ts.map +1 -1
- package/dist/components/ChipsInputBase/ChipsInputBase.js +21 -1
- package/dist/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
- package/dist/components/ChipsSelect/ChipsSelect.d.ts.map +1 -1
- package/dist/components/ChipsSelect/ChipsSelect.js +2 -4
- package/dist/components/ChipsSelect/ChipsSelect.js.map +1 -1
- package/dist/components/HorizontalScroll/HorizontalScroll.d.ts.map +1 -1
- package/dist/components/HorizontalScroll/HorizontalScroll.js +13 -3
- package/dist/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/dist/components.css +1 -1
- package/dist/components.css.map +1 -1
- package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js +21 -1
- package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
- package/dist/cssm/components/ChipsSelect/ChipsSelect.js +2 -4
- package/dist/cssm/components/ChipsSelect/ChipsSelect.js.map +1 -1
- package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js +9 -1
- package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/dist/cssm/components/ModalPage/ModalPage.module.css +9 -15
- package/dist/vkui.css +1 -1
- package/dist/vkui.css.map +1 -1
- package/package.json +1 -1
- package/src/components/ChipsInputBase/ChipsInputBase.tsx +26 -4
- package/src/components/ChipsSelect/ChipsSelect.tsx +2 -4
- package/src/components/HorizontalScroll/HorizontalScroll.tsx +13 -1
- package/src/components/ModalPage/ModalPage.module.css +9 -14
- package/src/components/ModalPage/ModalPage.module.css.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChipsInputBase.d.ts","sourceRoot":"","sources":["../../../src/components/ChipsInputBase/ChipsInputBase.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsB/B,OAAO,KAAK,EAAE,UAAU,EAAmB,0BAA0B,EAAc,MAAM,SAAS,CAAC;AAQnG,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,UAAU,EAAE,mXAsClD,0BAA0B,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"ChipsInputBase.d.ts","sourceRoot":"","sources":["../../../src/components/ChipsInputBase/ChipsInputBase.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsB/B,OAAO,KAAK,EAAE,UAAU,EAAmB,0BAA0B,EAAc,MAAM,SAAS,CAAC;AAQnG,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,UAAU,EAAE,mXAsClD,0BAA0B,CAAC,CAAC,CAAC,KAAG,KAAK,CAAC,SAsRxC,CAAC"}
|
|
@@ -147,7 +147,8 @@ export const ChipsInputBase = (_param)=>{
|
|
|
147
147
|
removeChipOption(v, getChipOptionIndexByValueProp(v, value));
|
|
148
148
|
};
|
|
149
149
|
const handleRootClick = (event)=>{
|
|
150
|
-
|
|
150
|
+
const activeElement = getActiveElementByAnotherElement(event.currentTarget);
|
|
151
|
+
if (event.defaultPrevented || contains(event.currentTarget, activeElement)) {
|
|
151
152
|
return;
|
|
152
153
|
}
|
|
153
154
|
if (inputRef.current) {
|
|
@@ -194,6 +195,24 @@ export const ChipsInputBase = (_param)=>{
|
|
|
194
195
|
clearButton
|
|
195
196
|
]);
|
|
196
197
|
const inputId = idProp || `chips-input-base-generated-id-${idGenerated}`;
|
|
198
|
+
const handleRootMouseDown = (e)=>{
|
|
199
|
+
// Если клик был в один из чипов, то preventDefault делать не нужно, так как не будет срабатывать выделение текста
|
|
200
|
+
if (isHTMLElement(e.target) && contains(listboxRef.current, e.target) && listboxRef.current !== e.target) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const activeElement = getActiveElementByAnotherElement(e.currentTarget);
|
|
204
|
+
// Когда выделен текст чипа не нужно делать preventDefault, чтобы сбросить выделение
|
|
205
|
+
if (contains(listboxRef.current, activeElement)) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
// Когда клик в сам инпут, не нужно делать preventDefault, так как не будет работать выделение текста
|
|
209
|
+
if (e.target === inputRef.current) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// Делаем preventDefault, чтобы при клике в поле, вне инпута, высота поля не скакала от того,
|
|
213
|
+
// что фокус сначала пропадает из инпута, а потом возвращается
|
|
214
|
+
e.preventDefault();
|
|
215
|
+
};
|
|
197
216
|
return /*#__PURE__*/ _jsx(FormField, {
|
|
198
217
|
Component: "div",
|
|
199
218
|
getRootRef: getRootRef,
|
|
@@ -210,6 +229,7 @@ export const ChipsInputBase = (_param)=>{
|
|
|
210
229
|
className: className,
|
|
211
230
|
maxHeight: maxHeight,
|
|
212
231
|
onClick: disabled ? undefined : handleRootClick,
|
|
232
|
+
onMouseDown: handleRootMouseDown,
|
|
213
233
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
214
234
|
className: classNames("vkuiChipsInputBase__host", sizeY !== 'regular' && sizeYClassNames[sizeY], withPlaceholder && "vkuiChipsInputBase__hasPlaceholder", inputValue && "vkuiChipsInputBase__hasInputValue"),
|
|
215
235
|
ref: containerRef,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ChipsInputBase/ChipsInputBase.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { isHTMLElement } from '@vkontakte/vkui-floating-ui/utils/dom';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { getHorizontalFocusGoTo, Keys } from '../../lib/accessibility';\nimport {\n contains as checkTargetIsInputEl,\n contains,\n getActiveElementByAnotherElement,\n} from '../../lib/dom';\nimport { FormField } from '../FormField/FormField';\nimport { FormFieldClearButton } from '../FormFieldClearButton/FormFieldClearButton';\nimport { Text } from '../Typography/Text/Text';\nimport { DEFAULT_INPUT_VALUE, DEFAULT_VALUE, renderChipDefault } from './constants';\nimport {\n getChipOptionIndexByHTMLElement,\n getChipOptionIndexByValueProp,\n getChipOptionValueByHTMLElement,\n getNextChipOptionIndexByNavigateToProp,\n isInputValueEmpty,\n} from './helpers';\nimport type { ChipOption, ChipOptionValue, ChipsInputBasePrivateProps, NavigateTo } from './types';\nimport styles from './ChipsInputBase.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n} as const;\n\nexport const ChipsInputBase = <O extends ChipOption>({\n // FormFieldProps\n getRootRef,\n style,\n className,\n before,\n after,\n status,\n mode,\n maxHeight,\n\n // option\n value = DEFAULT_VALUE,\n onAddChipOption,\n 'onRemoveChipOption': onRemoveChipOptionProp,\n renderChip = renderChipDefault,\n\n // input\n getRef,\n 'id': idProp,\n inputValue = DEFAULT_INPUT_VALUE,\n placeholder,\n disabled,\n readOnly,\n addOnBlur,\n onBlur,\n onInputChange,\n\n // clear\n ClearButton = FormFieldClearButton,\n clearButtonShown,\n clearButtonTestId,\n onClear,\n\n // a11y\n chipsListLabel = 'Выбранные элементы',\n 'aria-label': ariaLabel = '',\n ...restProps\n}: ChipsInputBasePrivateProps<O>): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n const idGenerated = React.useId();\n const inputRef = useExternRef(getRef);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const listboxRef = React.useRef<HTMLDivElement>(null);\n\n const valueLength = value.length;\n const withPlaceholder = valueLength === 0;\n const [lastFocusedChipOptionIndex, setLastFocusedChipOptionIndex] = React.useState(0);\n\n const resetChipOptionFocusToInputEl = (inputEl: HTMLInputElement) => {\n setLastFocusedChipOptionIndex(0);\n inputEl.focus();\n };\n\n const moveFocusToChipOption = (\n currentIndex: number,\n navigateTo: NavigateTo,\n listboxEl: HTMLElement,\n ) => {\n const index = getNextChipOptionIndexByNavigateToProp(currentIndex, navigateTo, valueLength);\n // eslint-disable-next-line no-restricted-properties\n const foundEl = listboxEl.querySelector<HTMLElement>(`[data-index=\"${index}\"]`);\n\n if (foundEl) {\n setLastFocusedChipOptionIndex(index);\n foundEl.focus();\n }\n };\n\n const removeChipOption = (o: O | ChipOptionValue, index: number) => {\n /* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */\n if (!inputRef.current || !listboxRef.current) {\n return;\n }\n\n if (valueLength > 1) {\n if (index === valueLength - 1) {\n moveFocusToChipOption(index, 'prev', listboxRef.current);\n } else {\n moveFocusToChipOption(index, 'next', listboxRef.current);\n }\n } else {\n resetChipOptionFocusToInputEl(inputRef.current);\n }\n\n onRemoveChipOptionProp(o);\n };\n\n const handleListboxKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const targetEl = event.target;\n /* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */\n if (event.defaultPrevented || !listboxRef.current || !isHTMLElement(targetEl)) {\n return;\n }\n\n switch (event.key) {\n case Keys.ENTER: {\n if (\n !readOnly &&\n checkTargetIsInputEl(targetEl, inputRef.current) &&\n inputRef.current &&\n !isInputValueEmpty(inputRef.current)\n ) {\n event.preventDefault();\n onAddChipOption(inputRef.current.value);\n }\n break;\n }\n case Keys.DELETE:\n case Keys.BACKSPACE: {\n if (!readOnly && valueLength > 0) {\n if (!checkTargetIsInputEl(targetEl, inputRef.current)) {\n event.preventDefault();\n removeChipOption(\n getChipOptionValueByHTMLElement(targetEl),\n getChipOptionIndexByHTMLElement(targetEl),\n );\n } else if (event.key === Keys.BACKSPACE && isInputValueEmpty(inputRef.current)) {\n event.preventDefault();\n moveFocusToChipOption(\n getChipOptionIndexByHTMLElement(targetEl),\n 'last',\n listboxRef.current,\n );\n }\n }\n break;\n }\n case Keys.HOME:\n case Keys.END:\n case Keys.ARROW_UP:\n case Keys.ARROW_LEFT:\n case Keys.ARROW_DOWN:\n case Keys.ARROW_RIGHT: {\n if (valueLength !== 0 && !checkTargetIsInputEl(targetEl, inputRef.current)) {\n event.preventDefault();\n moveFocusToChipOption(\n getChipOptionIndexByHTMLElement(targetEl),\n getHorizontalFocusGoTo(event.key),\n listboxRef.current,\n );\n }\n break;\n }\n }\n };\n\n const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(event);\n }\n\n if (addOnBlur && !event.defaultPrevented && inputRef.current) {\n onAddChipOption(inputRef.current.value);\n }\n };\n\n const handleChipRemove = (event: React.MouseEvent, v: ChipOptionValue) => {\n event.preventDefault();\n event.stopPropagation();\n removeChipOption(v, getChipOptionIndexByValueProp(v, value));\n };\n\n const handleRootClick = (event: React.MouseEvent<HTMLDivElement>) => {\n if (\n event.defaultPrevented ||\n contains(event.currentTarget, getActiveElementByAnotherElement(event.currentTarget))\n ) {\n return;\n }\n\n if (inputRef.current) {\n inputRef.current.focus();\n }\n };\n\n const handleClear = React.useCallback(() => {\n if (inputRef.current) {\n resetChipOptionFocusToInputEl(inputRef.current);\n }\n onClear();\n }, [inputRef, onClear]);\n\n const clearButton = React.useMemo(() => {\n if (clearButtonShown) {\n return (\n <ClearButton onClick={handleClear} disabled={disabled} data-testid={clearButtonTestId} />\n );\n }\n return undefined;\n }, [ClearButton, clearButtonShown, clearButtonTestId, disabled, handleClear]);\n\n const afterItems = React.useMemo(() => {\n if (clearButton || after) {\n return (\n <>\n {clearButton}\n {after}\n </>\n );\n }\n return undefined;\n }, [after, clearButton]);\n\n const inputId = idProp || `chips-input-base-generated-id-${idGenerated}`;\n\n return (\n <FormField\n Component=\"div\"\n getRootRef={getRootRef}\n // role=\"group\" добавлена, чтобы этот блок можно было найти с помощью стрелочек при использовании NVDA\n // Если убрать, то aria-label не будет читаться\n role=\"group\"\n aria-label={ariaLabel}\n style={style}\n disabled={disabled}\n before={before}\n after={afterItems}\n status={status}\n mode={mode}\n className={className}\n maxHeight={maxHeight}\n onClick={disabled ? undefined : handleRootClick}\n >\n <div\n className={classNames(\n styles.host,\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n withPlaceholder && styles.hasPlaceholder,\n inputValue && styles.hasInputValue,\n )}\n ref={containerRef}\n onKeyDown={disabled ? undefined : handleListboxKeyDown}\n >\n <div\n className={styles.listBox}\n // для a11y\n ref={listboxRef}\n role=\"listbox\"\n aria-orientation=\"horizontal\"\n aria-disabled={disabled}\n aria-readonly={readOnly}\n aria-label={chipsListLabel}\n >\n {value.map((option, index) => (\n <React.Fragment key={`${typeof option.value}-${option.value}`}>\n {renderChip(\n {\n 'Component': 'div',\n 'value': option.value,\n 'label': option.label,\n 'disabled': option.disabled || disabled,\n 'readOnly': option.readOnly || readOnly,\n 'className': styles.chip,\n 'onRemove': handleChipRemove,\n // чтобы можно было легче найти этот чип в DOM\n 'data-index': index,\n 'data-value': option.value,\n 'data-value-type': typeof option.value,\n // для a11y\n 'tabIndex': lastFocusedChipOptionIndex === index ? 0 : -1,\n 'role': 'option',\n 'aria-selected': true,\n 'aria-posinset': index + 1,\n 'aria-setsize': valueLength,\n 'aria-description': 'Для удаления используйте Backspace или Delete',\n },\n option,\n )}\n </React.Fragment>\n ))}\n </div>\n <Text\n autoCapitalize=\"none\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n {...restProps}\n aria-label={ariaLabel}\n Component=\"input\"\n type=\"text\"\n id={inputId}\n getRootRef={inputRef}\n className={styles.el}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={withPlaceholder ? placeholder : undefined}\n value={inputValue}\n onChange={onInputChange}\n onBlur={handleInputBlur}\n />\n </div>\n </FormField>\n );\n};\n"],"names":["React","classNames","isHTMLElement","useAdaptivity","useExternRef","getHorizontalFocusGoTo","Keys","contains","checkTargetIsInputEl","getActiveElementByAnotherElement","FormField","FormFieldClearButton","Text","DEFAULT_INPUT_VALUE","DEFAULT_VALUE","renderChipDefault","getChipOptionIndexByHTMLElement","getChipOptionIndexByValueProp","getChipOptionValueByHTMLElement","getNextChipOptionIndexByNavigateToProp","isInputValueEmpty","sizeYClassNames","none","compact","ChipsInputBase","getRootRef","style","className","before","after","status","mode","maxHeight","value","onAddChipOption","onRemoveChipOptionProp","renderChip","getRef","idProp","inputValue","placeholder","disabled","readOnly","addOnBlur","onBlur","onInputChange","ClearButton","clearButtonShown","clearButtonTestId","onClear","chipsListLabel","ariaLabel","restProps","sizeY","idGenerated","useId","inputRef","containerRef","useRef","listboxRef","valueLength","length","withPlaceholder","lastFocusedChipOptionIndex","setLastFocusedChipOptionIndex","useState","resetChipOptionFocusToInputEl","inputEl","focus","moveFocusToChipOption","currentIndex","navigateTo","listboxEl","index","foundEl","querySelector","removeChipOption","o","current","handleListboxKeyDown","event","targetEl","target","defaultPrevented","key","ENTER","preventDefault","DELETE","BACKSPACE","HOME","END","ARROW_UP","ARROW_LEFT","ARROW_DOWN","ARROW_RIGHT","handleInputBlur","handleChipRemove","v","stopPropagation","handleRootClick","currentTarget","handleClear","useCallback","clearButton","useMemo","onClick","data-testid","undefined","afterItems","inputId","Component","role","aria-label","div","ref","onKeyDown","aria-orientation","aria-disabled","aria-readonly","map","option","Fragment","label","autoCapitalize","autoComplete","autoCorrect","spellCheck","type","id","onChange"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ChipsInputBase/ChipsInputBase.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { isHTMLElement } from '@vkontakte/vkui-floating-ui/utils/dom';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { getHorizontalFocusGoTo, Keys } from '../../lib/accessibility';\nimport {\n contains as checkTargetIsInputEl,\n contains,\n getActiveElementByAnotherElement,\n} from '../../lib/dom';\nimport { FormField } from '../FormField/FormField';\nimport { FormFieldClearButton } from '../FormFieldClearButton/FormFieldClearButton';\nimport { Text } from '../Typography/Text/Text';\nimport { DEFAULT_INPUT_VALUE, DEFAULT_VALUE, renderChipDefault } from './constants';\nimport {\n getChipOptionIndexByHTMLElement,\n getChipOptionIndexByValueProp,\n getChipOptionValueByHTMLElement,\n getNextChipOptionIndexByNavigateToProp,\n isInputValueEmpty,\n} from './helpers';\nimport type { ChipOption, ChipOptionValue, ChipsInputBasePrivateProps, NavigateTo } from './types';\nimport styles from './ChipsInputBase.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n} as const;\n\nexport const ChipsInputBase = <O extends ChipOption>({\n // FormFieldProps\n getRootRef,\n style,\n className,\n before,\n after,\n status,\n mode,\n maxHeight,\n\n // option\n value = DEFAULT_VALUE,\n onAddChipOption,\n 'onRemoveChipOption': onRemoveChipOptionProp,\n renderChip = renderChipDefault,\n\n // input\n getRef,\n 'id': idProp,\n inputValue = DEFAULT_INPUT_VALUE,\n placeholder,\n disabled,\n readOnly,\n addOnBlur,\n onBlur,\n onInputChange,\n\n // clear\n ClearButton = FormFieldClearButton,\n clearButtonShown,\n clearButtonTestId,\n onClear,\n\n // a11y\n chipsListLabel = 'Выбранные элементы',\n 'aria-label': ariaLabel = '',\n ...restProps\n}: ChipsInputBasePrivateProps<O>): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n const idGenerated = React.useId();\n const inputRef = useExternRef(getRef);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const listboxRef = React.useRef<HTMLDivElement>(null);\n\n const valueLength = value.length;\n const withPlaceholder = valueLength === 0;\n const [lastFocusedChipOptionIndex, setLastFocusedChipOptionIndex] = React.useState(0);\n\n const resetChipOptionFocusToInputEl = (inputEl: HTMLInputElement) => {\n setLastFocusedChipOptionIndex(0);\n inputEl.focus();\n };\n\n const moveFocusToChipOption = (\n currentIndex: number,\n navigateTo: NavigateTo,\n listboxEl: HTMLElement,\n ) => {\n const index = getNextChipOptionIndexByNavigateToProp(currentIndex, navigateTo, valueLength);\n // eslint-disable-next-line no-restricted-properties\n const foundEl = listboxEl.querySelector<HTMLElement>(`[data-index=\"${index}\"]`);\n\n if (foundEl) {\n setLastFocusedChipOptionIndex(index);\n foundEl.focus();\n }\n };\n\n const removeChipOption = (o: O | ChipOptionValue, index: number) => {\n /* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */\n if (!inputRef.current || !listboxRef.current) {\n return;\n }\n\n if (valueLength > 1) {\n if (index === valueLength - 1) {\n moveFocusToChipOption(index, 'prev', listboxRef.current);\n } else {\n moveFocusToChipOption(index, 'next', listboxRef.current);\n }\n } else {\n resetChipOptionFocusToInputEl(inputRef.current);\n }\n\n onRemoveChipOptionProp(o);\n };\n\n const handleListboxKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const targetEl = event.target;\n /* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */\n if (event.defaultPrevented || !listboxRef.current || !isHTMLElement(targetEl)) {\n return;\n }\n\n switch (event.key) {\n case Keys.ENTER: {\n if (\n !readOnly &&\n checkTargetIsInputEl(targetEl, inputRef.current) &&\n inputRef.current &&\n !isInputValueEmpty(inputRef.current)\n ) {\n event.preventDefault();\n onAddChipOption(inputRef.current.value);\n }\n break;\n }\n case Keys.DELETE:\n case Keys.BACKSPACE: {\n if (!readOnly && valueLength > 0) {\n if (!checkTargetIsInputEl(targetEl, inputRef.current)) {\n event.preventDefault();\n removeChipOption(\n getChipOptionValueByHTMLElement(targetEl),\n getChipOptionIndexByHTMLElement(targetEl),\n );\n } else if (event.key === Keys.BACKSPACE && isInputValueEmpty(inputRef.current)) {\n event.preventDefault();\n moveFocusToChipOption(\n getChipOptionIndexByHTMLElement(targetEl),\n 'last',\n listboxRef.current,\n );\n }\n }\n break;\n }\n case Keys.HOME:\n case Keys.END:\n case Keys.ARROW_UP:\n case Keys.ARROW_LEFT:\n case Keys.ARROW_DOWN:\n case Keys.ARROW_RIGHT: {\n if (valueLength !== 0 && !checkTargetIsInputEl(targetEl, inputRef.current)) {\n event.preventDefault();\n moveFocusToChipOption(\n getChipOptionIndexByHTMLElement(targetEl),\n getHorizontalFocusGoTo(event.key),\n listboxRef.current,\n );\n }\n break;\n }\n }\n };\n\n const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(event);\n }\n\n if (addOnBlur && !event.defaultPrevented && inputRef.current) {\n onAddChipOption(inputRef.current.value);\n }\n };\n\n const handleChipRemove = (event: React.MouseEvent, v: ChipOptionValue) => {\n event.preventDefault();\n event.stopPropagation();\n removeChipOption(v, getChipOptionIndexByValueProp(v, value));\n };\n\n const handleRootClick = (event: React.MouseEvent<HTMLDivElement>) => {\n const activeElement = getActiveElementByAnotherElement(event.currentTarget);\n if (event.defaultPrevented || contains(event.currentTarget, activeElement)) {\n return;\n }\n\n if (inputRef.current) {\n inputRef.current.focus();\n }\n };\n\n const handleClear = React.useCallback(() => {\n if (inputRef.current) {\n resetChipOptionFocusToInputEl(inputRef.current);\n }\n onClear();\n }, [inputRef, onClear]);\n\n const clearButton = React.useMemo(() => {\n if (clearButtonShown) {\n return (\n <ClearButton onClick={handleClear} disabled={disabled} data-testid={clearButtonTestId} />\n );\n }\n return undefined;\n }, [ClearButton, clearButtonShown, clearButtonTestId, disabled, handleClear]);\n\n const afterItems = React.useMemo(() => {\n if (clearButton || after) {\n return (\n <>\n {clearButton}\n {after}\n </>\n );\n }\n return undefined;\n }, [after, clearButton]);\n\n const inputId = idProp || `chips-input-base-generated-id-${idGenerated}`;\n\n const handleRootMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {\n // Если клик был в один из чипов, то preventDefault делать не нужно, так как не будет срабатывать выделение текста\n if (\n isHTMLElement(e.target) &&\n contains(listboxRef.current, e.target) &&\n listboxRef.current !== e.target\n ) {\n return;\n }\n const activeElement = getActiveElementByAnotherElement(e.currentTarget);\n // Когда выделен текст чипа не нужно делать preventDefault, чтобы сбросить выделение\n if (contains(listboxRef.current, activeElement)) {\n return;\n }\n // Когда клик в сам инпут, не нужно делать preventDefault, так как не будет работать выделение текста\n if (e.target === inputRef.current) {\n return;\n }\n // Делаем preventDefault, чтобы при клике в поле, вне инпута, высота поля не скакала от того,\n // что фокус сначала пропадает из инпута, а потом возвращается\n e.preventDefault();\n };\n\n return (\n <FormField\n Component=\"div\"\n getRootRef={getRootRef}\n // role=\"group\" добавлена, чтобы этот блок можно было найти с помощью стрелочек при использовании NVDA\n // Если убрать, то aria-label не будет читаться\n role=\"group\"\n aria-label={ariaLabel}\n style={style}\n disabled={disabled}\n before={before}\n after={afterItems}\n status={status}\n mode={mode}\n className={className}\n maxHeight={maxHeight}\n onClick={disabled ? undefined : handleRootClick}\n onMouseDown={handleRootMouseDown}\n >\n <div\n className={classNames(\n styles.host,\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n withPlaceholder && styles.hasPlaceholder,\n inputValue && styles.hasInputValue,\n )}\n ref={containerRef}\n onKeyDown={disabled ? undefined : handleListboxKeyDown}\n >\n <div\n className={styles.listBox}\n // для a11y\n ref={listboxRef}\n role=\"listbox\"\n aria-orientation=\"horizontal\"\n aria-disabled={disabled}\n aria-readonly={readOnly}\n aria-label={chipsListLabel}\n >\n {value.map((option, index) => (\n <React.Fragment key={`${typeof option.value}-${option.value}`}>\n {renderChip(\n {\n 'Component': 'div',\n 'value': option.value,\n 'label': option.label,\n 'disabled': option.disabled || disabled,\n 'readOnly': option.readOnly || readOnly,\n 'className': styles.chip,\n 'onRemove': handleChipRemove,\n // чтобы можно было легче найти этот чип в DOM\n 'data-index': index,\n 'data-value': option.value,\n 'data-value-type': typeof option.value,\n // для a11y\n 'tabIndex': lastFocusedChipOptionIndex === index ? 0 : -1,\n 'role': 'option',\n 'aria-selected': true,\n 'aria-posinset': index + 1,\n 'aria-setsize': valueLength,\n 'aria-description': 'Для удаления используйте Backspace или Delete',\n },\n option,\n )}\n </React.Fragment>\n ))}\n </div>\n <Text\n autoCapitalize=\"none\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n {...restProps}\n aria-label={ariaLabel}\n Component=\"input\"\n type=\"text\"\n id={inputId}\n getRootRef={inputRef}\n className={styles.el}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={withPlaceholder ? placeholder : undefined}\n value={inputValue}\n onChange={onInputChange}\n onBlur={handleInputBlur}\n />\n </div>\n </FormField>\n );\n};\n"],"names":["React","classNames","isHTMLElement","useAdaptivity","useExternRef","getHorizontalFocusGoTo","Keys","contains","checkTargetIsInputEl","getActiveElementByAnotherElement","FormField","FormFieldClearButton","Text","DEFAULT_INPUT_VALUE","DEFAULT_VALUE","renderChipDefault","getChipOptionIndexByHTMLElement","getChipOptionIndexByValueProp","getChipOptionValueByHTMLElement","getNextChipOptionIndexByNavigateToProp","isInputValueEmpty","sizeYClassNames","none","compact","ChipsInputBase","getRootRef","style","className","before","after","status","mode","maxHeight","value","onAddChipOption","onRemoveChipOptionProp","renderChip","getRef","idProp","inputValue","placeholder","disabled","readOnly","addOnBlur","onBlur","onInputChange","ClearButton","clearButtonShown","clearButtonTestId","onClear","chipsListLabel","ariaLabel","restProps","sizeY","idGenerated","useId","inputRef","containerRef","useRef","listboxRef","valueLength","length","withPlaceholder","lastFocusedChipOptionIndex","setLastFocusedChipOptionIndex","useState","resetChipOptionFocusToInputEl","inputEl","focus","moveFocusToChipOption","currentIndex","navigateTo","listboxEl","index","foundEl","querySelector","removeChipOption","o","current","handleListboxKeyDown","event","targetEl","target","defaultPrevented","key","ENTER","preventDefault","DELETE","BACKSPACE","HOME","END","ARROW_UP","ARROW_LEFT","ARROW_DOWN","ARROW_RIGHT","handleInputBlur","handleChipRemove","v","stopPropagation","handleRootClick","activeElement","currentTarget","handleClear","useCallback","clearButton","useMemo","onClick","data-testid","undefined","afterItems","inputId","handleRootMouseDown","e","Component","role","aria-label","onMouseDown","div","ref","onKeyDown","aria-orientation","aria-disabled","aria-readonly","map","option","Fragment","label","autoCapitalize","autoComplete","autoCorrect","spellCheck","type","id","onChange"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChipsSelect.d.ts","sourceRoot":"","sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAa7D,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAkC5E,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,UAAU,CACpD,SAAQ,mBAAmB,CAAC,CAAC,CAAC,EAC5B,mBAAmB,CAAC,CAAC,CAAC,EACtB,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC,EAClD,IAAI,CAAC,yBAAyB,EAAE,oBAAoB,CAAC;IACvD;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC9E;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,EAChB,sBAAsB,GACvB,EAAE;QACD,sBAAsB,EAAE,KAAK,CAAC,SAAS,CAAC;KACzC,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAEnF;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,UAAU,EAAE,yuBAsDpD,gBAAgB,CAAC,MAAM,CAAC,KAAG,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"ChipsSelect.d.ts","sourceRoot":"","sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAa7D,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAkC5E,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,UAAU,CACpD,SAAQ,mBAAmB,CAAC,CAAC,CAAC,EAC5B,mBAAmB,CAAC,CAAC,CAAC,EACtB,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC,EAClD,IAAI,CAAC,yBAAyB,EAAE,oBAAoB,CAAC;IACvD;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC9E;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,EAChB,sBAAsB,GACvB,EAAE;QACD,sBAAsB,EAAE,KAAK,CAAC,SAAS,CAAC;KACzC,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAEnF;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,UAAU,EAAE,yuBAsDpD,gBAAgB,CAAC,MAAM,CAAC,KAAG,KAAK,CAAC,SAsanC,CAAC"}
|
|
@@ -271,10 +271,8 @@ const findIndexBefore = (options = [], endIndex = options.length)=>{
|
|
|
271
271
|
]);
|
|
272
272
|
useGlobalOnEventOutside('mousedown', handleClickOutside, opened ? rootRef : null, opened ? dropdownScrollBoxRef : null);
|
|
273
273
|
const onDropdownIconClick = React.useCallback((e)=>{
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
setOpened(false);
|
|
277
|
-
}
|
|
274
|
+
e.preventDefault();
|
|
275
|
+
setOpened(!opened);
|
|
278
276
|
}, [
|
|
279
277
|
opened,
|
|
280
278
|
setOpened
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { type MouseEventHandler } from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useGlobalOnEventOutside } from '../../hooks/useGlobalOnClickOutside';\nimport { Keys } from '../../lib/accessibility';\nimport type { Placement } from '../../lib/floating';\nimport { defaultFilterFn } from '../../lib/select';\nimport { ChipsInputBase } from '../ChipsInputBase/ChipsInputBase';\nimport {\n getNewOptionDataDefault,\n getOptionLabelDefault,\n getOptionValueDefault,\n renderChipDefault,\n} from '../ChipsInputBase/constants';\nimport type { ChipOption, ChipsInputBaseProps } from '../ChipsInputBase/types';\nimport {\n CustomSelectDropdown,\n type CustomSelectDropdownProps,\n} from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n type CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport type { FormFieldProps } from '../FormField/FormField';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport {\n DEFAULT_EMPTY_TEXT,\n DEFAULT_SELECTED_BEHAVIOR,\n FOCUS_ACTION_NEXT,\n FOCUS_ACTION_PREV,\n isCreateNewOptionPreset,\n isEmptyOptionPreset,\n isNotServicePreset,\n renderOptionDefault,\n} from './constants';\nimport type { FocusActionType, OptionPreset } from './types';\nimport { useChipsSelect, type UseChipsSelectProps } from './useChipsSelect';\nimport styles from './ChipsSelect.module.css';\n\nconst findIndexAfter = <O extends ChipOption>(\n options: Array<OptionPreset<O>> = [],\n startIndex = -1,\n) => {\n if (startIndex >= options.length - 1) {\n return -1;\n }\n return options.findIndex(\n (option, i) => i > startIndex && (!isNotServicePreset(option) || !option.disabled),\n );\n};\n\nconst findIndexBefore = <O extends ChipOption>(\n options: Array<OptionPreset<O>> = [],\n endIndex: number = options.length,\n) => {\n let result = -1;\n if (endIndex <= 0) {\n return result;\n }\n for (let i = endIndex - 1; i >= 0; i--) {\n let option = options[i];\n\n if (!isNotServicePreset(option) || !option.disabled) {\n result = i;\n break;\n }\n }\n return result;\n};\n\nexport interface ChipsSelectProps<O extends ChipOption>\n extends ChipsInputBaseProps<O>,\n UseChipsSelectProps<O>,\n Pick<FormFieldProps, 'status' | 'mode' | 'before'>,\n Pick<CustomSelectDropdownProps, 'overscrollBehavior'> {\n /**\n * Расположение выпадающего списка.\n */\n placement?: 'top' | 'bottom';\n /**\n * Отрисовка Spinner вместо списка опций в выпадающем списке.\n */\n fetching?: boolean;\n /**\n * Закрытие выпадающего списка после выбора элемента.\n */\n closeAfterSelect?: boolean;\n /**\n * Ширина раскрывающегося списка зависит от контента.\n */\n dropdownAutoWidth?: boolean;\n /**\n * Принудительно использовать портал.\n */\n forceDropdownPortal?: boolean;\n /**\n * Передает атрибут `data-testid` для дропдауна.\n */\n dropdownTestId?: string;\n /**\n * Иконка раскрывающегося списка.\n */\n icon?: React.ReactNode;\n /**\n * Добавляет значение в список на событие `onBlur` (использовать вместе с `creatable`).\n */\n addOnBlur?: boolean;\n /**\n * Отключает максимальную высоту по умолчанию.\n */\n noMaxHeight?: boolean;\n /**\n * Функция для отрисовки кастомной опции в выпадающем списке.\n */\n renderOption?: (props: CustomSelectOptionProps, option: O) => React.ReactNode;\n /**\n * Рендер-проп для кастомного рендера содержимого дропдауна.\n * В `defaultDropdownContent` содержится список опций.\n */\n renderDropdown?: ({\n defaultDropdownContent,\n }: {\n defaultDropdownContent: React.ReactNode;\n }) => React.ReactNode;\n /**\n * Событие срабатывающее перед `onChange`.\n */\n onChangeStart?: (event: React.MouseEvent | React.KeyboardEvent, option: O) => void;\n\n /**\n * Отступ от выпадающего списка.\n */\n dropdownOffsetDistance?: number;\n\n /**\n * Если `true`, то справа будет отображаться кнопка для очистки значения.\n */\n allowClearButton?: boolean;\n}\n\n/**\n * @see https://vkui.io/components/chips-select\n */\nexport const ChipsSelect = <Option extends ChipOption>({\n // FormFieldProps\n id: labelledbyId,\n getRootRef,\n className,\n status = 'default',\n icon: dropdownIconProp,\n onChangeStart,\n\n // CustomSelectDropdownProps\n options: optionsProp,\n placement: placementProp = 'bottom',\n closeAfterSelect = true,\n selectedBehavior = DEFAULT_SELECTED_BEHAVIOR,\n emptyText = DEFAULT_EMPTY_TEXT,\n creatable = false,\n fetching = false,\n dropdownAutoWidth,\n forceDropdownPortal,\n noMaxHeight = false,\n filterFn = defaultFilterFn,\n sortFn = false,\n dropdownTestId,\n onClose,\n onOpen,\n overscrollBehavior,\n renderDropdown,\n\n // ChipsInputProps\n getRef,\n value: valueProp,\n defaultValue,\n inputValue: inputValueProp,\n defaultInputValue,\n disabled,\n readOnly,\n getOptionValue = getOptionValueDefault,\n getOptionLabel = getOptionLabelDefault,\n getNewOptionData = getNewOptionDataDefault,\n renderChip = renderChipDefault,\n renderOption = renderOptionDefault,\n onChange,\n onFocus: onFocusProp,\n onInputChange: onInputChangeProp,\n onBlur: onBlurProp,\n onKeyDown: onKeyDownProp,\n dropdownOffsetDistance = 0,\n allowClearButton,\n clearButtonTestId,\n delimiter,\n\n // a11y\n chipsListLabel,\n ...restProps\n}: ChipsSelectProps<Option>): React.ReactNode => {\n const {\n // Связано с ChipsInputProps\n // option\n value,\n addOptionFromInput,\n addOption,\n removeOption,\n clearOptions,\n // input\n inputRef: inputRefHook,\n inputValue,\n clearInput,\n onInputChange,\n\n // Связано с CustomSelectDropdownProps\n options,\n opened,\n setOpened,\n focusedOption,\n focusedOptionIndex,\n setFocusedOption,\n setFocusedOptionIndex,\n } = useChipsSelect({\n // option\n value: valueProp,\n defaultValue,\n onChange,\n getOptionValue,\n getOptionLabel,\n getNewOptionData,\n\n // input\n inputValue: inputValueProp,\n defaultInputValue,\n onInputChange: onInputChangeProp,\n\n // dropdown\n options: optionsProp,\n emptyText,\n creatable,\n filterFn,\n sortFn,\n selectedBehavior,\n onClose,\n onOpen,\n\n // other\n disabled,\n delimiter,\n });\n\n // Связано с ChipsInputProps\n const rootRef = useExternRef(getRootRef);\n const inputRef = useExternRef(getRef, inputRefHook);\n\n // Связано с CustomSelectDropdownProps\n const [dropdownVerticalPlacement, setDropdownVerticalPlacement] = React.useState<\n 'top' | 'bottom'\n >(placementProp);\n\n const onDropdownPlacementChange = React.useCallback((placement: Placement) => {\n if (placement.startsWith('top')) {\n setDropdownVerticalPlacement('top');\n } else if (placement.startsWith('bottom')) {\n setDropdownVerticalPlacement('bottom');\n }\n }, []);\n\n const dropdownId = React.useId();\n const dropdownCurrentItemId =\n focusedOptionIndex !== null ? `${dropdownId}-${focusedOptionIndex}` : undefined;\n const dropdownScrollBoxRef = React.useRef<HTMLDivElement>(null);\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n if (onFocusProp) {\n onFocusProp(event);\n }\n\n if (!readOnly) {\n setOpened(true);\n setFocusedOptionIndex(null);\n }\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n if (onBlurProp) {\n onBlurProp(event);\n }\n\n // Не добавляем значение, если его нужно выбрать строго из списка\n if (!readOnly && !event.defaultPrevented && !creatable) {\n event.preventDefault();\n }\n };\n\n const chipsSelectOptions = React.useRef<HTMLElement[]>([]).current;\n\n const scrollToElement = (index: number, center = false) => {\n const dropdown = dropdownScrollBoxRef.current;\n const item = chipsSelectOptions[index];\n\n /* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */\n if (!item || !dropdown) {\n return;\n }\n\n const dropdownHeight = dropdown.offsetHeight;\n const scrollTop = dropdown.scrollTop;\n const itemTop = item.offsetTop;\n const itemHeight = item.offsetHeight;\n\n /* istanbul ignore next: нет представления как воспроизвести */\n if (center) {\n dropdown.scrollTop = itemTop - dropdownHeight / 2 + itemHeight / 2;\n } else if (itemTop + itemHeight > dropdownHeight + scrollTop) {\n dropdown.scrollTop = itemTop - dropdownHeight + itemHeight;\n } else if (itemTop < scrollTop) {\n dropdown.scrollTop = itemTop;\n }\n };\n\n const focusOptionByIndex = (index: number, oldIndex: number | null) => {\n if (index === oldIndex) {\n /* istanbul ignore next: нет представления как воспроизвести */\n return;\n }\n\n const option = options[index];\n\n if (isNotServicePreset(option) && option.disabled) {\n return;\n }\n\n scrollToElement(index);\n setFocusedOptionIndex(index);\n };\n\n const focusOption = (nextIndex: number | null, type: FocusActionType) => {\n let index = nextIndex === null ? -1 : nextIndex;\n\n if (type === FOCUS_ACTION_NEXT) {\n const nextIndex = findIndexAfter(options, index);\n index = nextIndex === -1 ? findIndexAfter(options) : nextIndex; // Следующий за index или первый валидный до index\n } else if (type === FOCUS_ACTION_PREV) {\n const beforeIndex = findIndexBefore(options, index);\n index = beforeIndex === -1 ? findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index\n }\n\n focusOptionByIndex(index, focusedOptionIndex);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (onKeyDownProp) {\n onKeyDownProp(event);\n }\n\n if (event.defaultPrevented || readOnly) {\n return;\n }\n\n switch (event.key) {\n case Keys.ARROW_UP:\n case Keys.ARROW_DOWN:\n event.preventDefault();\n\n if (!opened) {\n setOpened(true);\n focusOption(null, FOCUS_ACTION_NEXT);\n } else {\n focusOption(\n focusedOptionIndex,\n event.key === Keys.ARROW_UP ? FOCUS_ACTION_PREV : FOCUS_ACTION_NEXT,\n );\n }\n break;\n case Keys.ENTER: {\n if (!opened) {\n break;\n }\n if (focusedOptionIndex != null) {\n const foundOption = options[focusedOptionIndex];\n if (foundOption && isNotServicePreset(foundOption)) {\n event.preventDefault();\n\n if (onChangeStart) {\n onChangeStart(event, foundOption);\n }\n\n addOption(foundOption);\n setFocusedOptionIndex(null);\n clearInput();\n if (closeAfterSelect) {\n setOpened(false);\n }\n\n break;\n }\n }\n\n if (!creatable) {\n event.preventDefault();\n }\n break;\n }\n case Keys.ESCAPE:\n case Keys.TAB:\n if (opened) {\n setOpened(false);\n }\n }\n };\n\n React.useEffect(() => {\n if (focusedOptionIndex === null) {\n setFocusedOption(null);\n } else {\n const foundFocusedOptionIndex = options[focusedOptionIndex];\n\n if (foundFocusedOptionIndex && isNotServicePreset(foundFocusedOptionIndex)) {\n setFocusedOption(foundFocusedOptionIndex);\n }\n }\n }, [options, focusedOptionIndex, setFocusedOption]);\n\n const onDropdownMouseLeave = React.useCallback(() => {\n setFocusedOptionIndex(null);\n }, [setFocusedOptionIndex]);\n\n const handleClickOutside = React.useCallback(() => {\n setOpened(false);\n }, [setOpened]);\n\n useGlobalOnEventOutside(\n 'mousedown', // см. https://github.com/VKCOM/VKUI/pull/8582\n handleClickOutside,\n opened ? rootRef : null,\n opened ? dropdownScrollBoxRef : null,\n );\n\n const onDropdownIconClick: MouseEventHandler<SVGSVGElement> = React.useCallback(\n (e) => {\n if (opened) {\n e.preventDefault();\n setOpened(false);\n }\n },\n [opened, setOpened],\n );\n\n const dropdownContent = React.useMemo(() => {\n const defaultDropdownContent = options.map((option, index) => {\n const dropdownItemId = `${dropdownId}-${index}`;\n\n if (isEmptyOptionPreset(option)) {\n return (\n <Footnote key=\"empty-text\" className={styles.empty}>\n {option.placeholder}\n </Footnote>\n );\n }\n if (isCreateNewOptionPreset(option)) {\n return (\n <CustomSelectOption\n key=\"create-new-option\"\n id={dropdownItemId}\n hovered={focusedOptionIndex === index}\n onMouseDown={() => addOptionFromInput(inputValue)}\n onMouseEnter={() => setFocusedOptionIndex(index)}\n >\n {option.actionText}\n </CustomSelectOption>\n );\n }\n return (\n <React.Fragment key={`${typeof option.value}-${option.value}`}>\n {renderOption(\n {\n id: dropdownItemId,\n disabled: option.disabled,\n hovered: focusedOption\n ? getOptionValue(option) === getOptionValue(focusedOption)\n : false,\n children: option.label,\n selected: !!value.find(\n (selectedOption: Option) =>\n getOptionValue(selectedOption) === getOptionValue(option),\n ),\n getRootRef(node) {\n if (node) {\n chipsSelectOptions[index] = node;\n }\n },\n onMouseDown(event: React.MouseEvent<HTMLDivElement>) {\n if (option.disabled) {\n return;\n }\n if (onChangeStart) {\n onChangeStart(event, option);\n }\n\n if (!event.defaultPrevented) {\n closeAfterSelect && setOpened(false);\n addOption(option);\n clearInput();\n }\n },\n onMouseEnter() {\n setFocusedOptionIndex(index);\n },\n },\n option,\n )}\n </React.Fragment>\n );\n });\n\n if (renderDropdown) {\n return renderDropdown({\n defaultDropdownContent,\n });\n }\n return defaultDropdownContent;\n }, [\n addOption,\n addOptionFromInput,\n chipsSelectOptions,\n clearInput,\n closeAfterSelect,\n dropdownId,\n focusedOption,\n focusedOptionIndex,\n getOptionValue,\n inputValue,\n onChangeStart,\n options,\n renderDropdown,\n renderOption,\n setFocusedOptionIndex,\n setOpened,\n value,\n ]);\n\n const openedClassNames = React.useMemo(\n () =>\n (opened &&\n dropdownOffsetDistance === 0 &&\n (dropdownVerticalPlacement.includes('top') ? styles.popUp : styles.popDown)) ||\n undefined,\n [dropdownOffsetDistance, opened, dropdownVerticalPlacement],\n );\n\n const clearButtonShown = allowClearButton && (!!value.length || !!inputValue.length);\n\n return (\n <>\n <ChipsInputBase\n {...restProps}\n disabled={disabled}\n readOnly={readOnly}\n clearButtonShown={clearButtonShown}\n clearButtonTestId={clearButtonTestId}\n // FormFieldProps\n id={labelledbyId}\n getRootRef={rootRef}\n className={classNames(styles.host, openedClassNames, className)}\n status={status}\n after={\n dropdownIconProp || (\n <DropdownIcon\n opened={opened}\n onClick={onDropdownIconClick}\n className={classNames(\n styles.dropdownIcon,\n clearButtonShown && styles.dropdownIconWithOffset,\n )}\n />\n )\n }\n // option\n value={value}\n onAddChipOption={addOptionFromInput}\n onRemoveChipOption={removeOption}\n renderChip={renderChip}\n onClear={clearOptions}\n // input\n getRef={inputRef}\n inputValue={inputValue}\n onInputChange={onInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n // a11y\n role=\"combobox\"\n aria-expanded={opened}\n aria-autocomplete=\"list\"\n aria-activedescendant={opened ? dropdownCurrentItemId : undefined}\n aria-haspopup=\"listbox\"\n chipsListLabel={chipsListLabel}\n />\n {opened && (\n <CustomSelectDropdown\n data-testid={dropdownTestId}\n targetRef={rootRef}\n placement={dropdownVerticalPlacement}\n scrollBoxRef={dropdownScrollBoxRef}\n onPlacementChange={onDropdownPlacementChange}\n onMouseLeave={onDropdownMouseLeave}\n fetching={fetching}\n autoWidth={dropdownAutoWidth}\n forcePortal={forceDropdownPortal}\n noMaxHeight={noMaxHeight}\n offsetDistance={dropdownOffsetDistance}\n overscrollBehavior={overscrollBehavior}\n // a11y\n id={dropdownId}\n role=\"listbox\"\n aria-labelledby={labelledbyId}\n >\n {dropdownContent}\n </CustomSelectDropdown>\n )}\n </>\n );\n};\n"],"names":["React","classNames","useExternRef","useGlobalOnEventOutside","Keys","defaultFilterFn","ChipsInputBase","getNewOptionDataDefault","getOptionLabelDefault","getOptionValueDefault","renderChipDefault","CustomSelectDropdown","CustomSelectOption","DropdownIcon","Footnote","DEFAULT_EMPTY_TEXT","DEFAULT_SELECTED_BEHAVIOR","FOCUS_ACTION_NEXT","FOCUS_ACTION_PREV","isCreateNewOptionPreset","isEmptyOptionPreset","isNotServicePreset","renderOptionDefault","useChipsSelect","findIndexAfter","options","startIndex","length","findIndex","option","i","disabled","findIndexBefore","endIndex","result","ChipsSelect","id","labelledbyId","getRootRef","className","status","icon","dropdownIconProp","onChangeStart","optionsProp","placement","placementProp","closeAfterSelect","selectedBehavior","emptyText","creatable","fetching","dropdownAutoWidth","forceDropdownPortal","noMaxHeight","filterFn","sortFn","dropdownTestId","onClose","onOpen","overscrollBehavior","renderDropdown","getRef","value","valueProp","defaultValue","inputValue","inputValueProp","defaultInputValue","readOnly","getOptionValue","getOptionLabel","getNewOptionData","renderChip","renderOption","onChange","onFocus","onFocusProp","onInputChange","onInputChangeProp","onBlur","onBlurProp","onKeyDown","onKeyDownProp","dropdownOffsetDistance","allowClearButton","clearButtonTestId","delimiter","chipsListLabel","restProps","addOptionFromInput","addOption","removeOption","clearOptions","inputRef","inputRefHook","clearInput","opened","setOpened","focusedOption","focusedOptionIndex","setFocusedOption","setFocusedOptionIndex","rootRef","dropdownVerticalPlacement","setDropdownVerticalPlacement","useState","onDropdownPlacementChange","useCallback","startsWith","dropdownId","useId","dropdownCurrentItemId","undefined","dropdownScrollBoxRef","useRef","handleFocus","event","handleBlur","defaultPrevented","preventDefault","chipsSelectOptions","current","scrollToElement","index","center","dropdown","item","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","oldIndex","focusOption","nextIndex","type","beforeIndex","handleKeyDown","key","ARROW_UP","ARROW_DOWN","ENTER","foundOption","ESCAPE","TAB","useEffect","foundFocusedOptionIndex","onDropdownMouseLeave","handleClickOutside","onDropdownIconClick","e","dropdownContent","useMemo","defaultDropdownContent","map","dropdownItemId","placeholder","hovered","onMouseDown","onMouseEnter","actionText","Fragment","children","label","selected","find","selectedOption","node","openedClassNames","includes","clearButtonShown","after","onClick","onAddChipOption","onRemoveChipOption","onClear","role","aria-expanded","aria-autocomplete","aria-activedescendant","aria-haspopup","data-testid","targetRef","scrollBoxRef","onPlacementChange","onMouseLeave","autoWidth","forcePortal","offsetDistance","aria-labelledby"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { type MouseEventHandler } from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useGlobalOnEventOutside } from '../../hooks/useGlobalOnClickOutside';\nimport { Keys } from '../../lib/accessibility';\nimport type { Placement } from '../../lib/floating';\nimport { defaultFilterFn } from '../../lib/select';\nimport { ChipsInputBase } from '../ChipsInputBase/ChipsInputBase';\nimport {\n getNewOptionDataDefault,\n getOptionLabelDefault,\n getOptionValueDefault,\n renderChipDefault,\n} from '../ChipsInputBase/constants';\nimport type { ChipOption, ChipsInputBaseProps } from '../ChipsInputBase/types';\nimport {\n CustomSelectDropdown,\n type CustomSelectDropdownProps,\n} from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n type CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport type { FormFieldProps } from '../FormField/FormField';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport {\n DEFAULT_EMPTY_TEXT,\n DEFAULT_SELECTED_BEHAVIOR,\n FOCUS_ACTION_NEXT,\n FOCUS_ACTION_PREV,\n isCreateNewOptionPreset,\n isEmptyOptionPreset,\n isNotServicePreset,\n renderOptionDefault,\n} from './constants';\nimport type { FocusActionType, OptionPreset } from './types';\nimport { useChipsSelect, type UseChipsSelectProps } from './useChipsSelect';\nimport styles from './ChipsSelect.module.css';\n\nconst findIndexAfter = <O extends ChipOption>(\n options: Array<OptionPreset<O>> = [],\n startIndex = -1,\n) => {\n if (startIndex >= options.length - 1) {\n return -1;\n }\n return options.findIndex(\n (option, i) => i > startIndex && (!isNotServicePreset(option) || !option.disabled),\n );\n};\n\nconst findIndexBefore = <O extends ChipOption>(\n options: Array<OptionPreset<O>> = [],\n endIndex: number = options.length,\n) => {\n let result = -1;\n if (endIndex <= 0) {\n return result;\n }\n for (let i = endIndex - 1; i >= 0; i--) {\n let option = options[i];\n\n if (!isNotServicePreset(option) || !option.disabled) {\n result = i;\n break;\n }\n }\n return result;\n};\n\nexport interface ChipsSelectProps<O extends ChipOption>\n extends ChipsInputBaseProps<O>,\n UseChipsSelectProps<O>,\n Pick<FormFieldProps, 'status' | 'mode' | 'before'>,\n Pick<CustomSelectDropdownProps, 'overscrollBehavior'> {\n /**\n * Расположение выпадающего списка.\n */\n placement?: 'top' | 'bottom';\n /**\n * Отрисовка Spinner вместо списка опций в выпадающем списке.\n */\n fetching?: boolean;\n /**\n * Закрытие выпадающего списка после выбора элемента.\n */\n closeAfterSelect?: boolean;\n /**\n * Ширина раскрывающегося списка зависит от контента.\n */\n dropdownAutoWidth?: boolean;\n /**\n * Принудительно использовать портал.\n */\n forceDropdownPortal?: boolean;\n /**\n * Передает атрибут `data-testid` для дропдауна.\n */\n dropdownTestId?: string;\n /**\n * Иконка раскрывающегося списка.\n */\n icon?: React.ReactNode;\n /**\n * Добавляет значение в список на событие `onBlur` (использовать вместе с `creatable`).\n */\n addOnBlur?: boolean;\n /**\n * Отключает максимальную высоту по умолчанию.\n */\n noMaxHeight?: boolean;\n /**\n * Функция для отрисовки кастомной опции в выпадающем списке.\n */\n renderOption?: (props: CustomSelectOptionProps, option: O) => React.ReactNode;\n /**\n * Рендер-проп для кастомного рендера содержимого дропдауна.\n * В `defaultDropdownContent` содержится список опций.\n */\n renderDropdown?: ({\n defaultDropdownContent,\n }: {\n defaultDropdownContent: React.ReactNode;\n }) => React.ReactNode;\n /**\n * Событие срабатывающее перед `onChange`.\n */\n onChangeStart?: (event: React.MouseEvent | React.KeyboardEvent, option: O) => void;\n\n /**\n * Отступ от выпадающего списка.\n */\n dropdownOffsetDistance?: number;\n\n /**\n * Если `true`, то справа будет отображаться кнопка для очистки значения.\n */\n allowClearButton?: boolean;\n}\n\n/**\n * @see https://vkui.io/components/chips-select\n */\nexport const ChipsSelect = <Option extends ChipOption>({\n // FormFieldProps\n id: labelledbyId,\n getRootRef,\n className,\n status = 'default',\n icon: dropdownIconProp,\n onChangeStart,\n\n // CustomSelectDropdownProps\n options: optionsProp,\n placement: placementProp = 'bottom',\n closeAfterSelect = true,\n selectedBehavior = DEFAULT_SELECTED_BEHAVIOR,\n emptyText = DEFAULT_EMPTY_TEXT,\n creatable = false,\n fetching = false,\n dropdownAutoWidth,\n forceDropdownPortal,\n noMaxHeight = false,\n filterFn = defaultFilterFn,\n sortFn = false,\n dropdownTestId,\n onClose,\n onOpen,\n overscrollBehavior,\n renderDropdown,\n\n // ChipsInputProps\n getRef,\n value: valueProp,\n defaultValue,\n inputValue: inputValueProp,\n defaultInputValue,\n disabled,\n readOnly,\n getOptionValue = getOptionValueDefault,\n getOptionLabel = getOptionLabelDefault,\n getNewOptionData = getNewOptionDataDefault,\n renderChip = renderChipDefault,\n renderOption = renderOptionDefault,\n onChange,\n onFocus: onFocusProp,\n onInputChange: onInputChangeProp,\n onBlur: onBlurProp,\n onKeyDown: onKeyDownProp,\n dropdownOffsetDistance = 0,\n allowClearButton,\n clearButtonTestId,\n delimiter,\n\n // a11y\n chipsListLabel,\n ...restProps\n}: ChipsSelectProps<Option>): React.ReactNode => {\n const {\n // Связано с ChipsInputProps\n // option\n value,\n addOptionFromInput,\n addOption,\n removeOption,\n clearOptions,\n // input\n inputRef: inputRefHook,\n inputValue,\n clearInput,\n onInputChange,\n\n // Связано с CustomSelectDropdownProps\n options,\n opened,\n setOpened,\n focusedOption,\n focusedOptionIndex,\n setFocusedOption,\n setFocusedOptionIndex,\n } = useChipsSelect({\n // option\n value: valueProp,\n defaultValue,\n onChange,\n getOptionValue,\n getOptionLabel,\n getNewOptionData,\n\n // input\n inputValue: inputValueProp,\n defaultInputValue,\n onInputChange: onInputChangeProp,\n\n // dropdown\n options: optionsProp,\n emptyText,\n creatable,\n filterFn,\n sortFn,\n selectedBehavior,\n onClose,\n onOpen,\n\n // other\n disabled,\n delimiter,\n });\n\n // Связано с ChipsInputProps\n const rootRef = useExternRef(getRootRef);\n const inputRef = useExternRef(getRef, inputRefHook);\n\n // Связано с CustomSelectDropdownProps\n const [dropdownVerticalPlacement, setDropdownVerticalPlacement] = React.useState<\n 'top' | 'bottom'\n >(placementProp);\n\n const onDropdownPlacementChange = React.useCallback((placement: Placement) => {\n if (placement.startsWith('top')) {\n setDropdownVerticalPlacement('top');\n } else if (placement.startsWith('bottom')) {\n setDropdownVerticalPlacement('bottom');\n }\n }, []);\n\n const dropdownId = React.useId();\n const dropdownCurrentItemId =\n focusedOptionIndex !== null ? `${dropdownId}-${focusedOptionIndex}` : undefined;\n const dropdownScrollBoxRef = React.useRef<HTMLDivElement>(null);\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n if (onFocusProp) {\n onFocusProp(event);\n }\n\n if (!readOnly) {\n setOpened(true);\n setFocusedOptionIndex(null);\n }\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n if (onBlurProp) {\n onBlurProp(event);\n }\n\n // Не добавляем значение, если его нужно выбрать строго из списка\n if (!readOnly && !event.defaultPrevented && !creatable) {\n event.preventDefault();\n }\n };\n\n const chipsSelectOptions = React.useRef<HTMLElement[]>([]).current;\n\n const scrollToElement = (index: number, center = false) => {\n const dropdown = dropdownScrollBoxRef.current;\n const item = chipsSelectOptions[index];\n\n /* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */\n if (!item || !dropdown) {\n return;\n }\n\n const dropdownHeight = dropdown.offsetHeight;\n const scrollTop = dropdown.scrollTop;\n const itemTop = item.offsetTop;\n const itemHeight = item.offsetHeight;\n\n /* istanbul ignore next: нет представления как воспроизвести */\n if (center) {\n dropdown.scrollTop = itemTop - dropdownHeight / 2 + itemHeight / 2;\n } else if (itemTop + itemHeight > dropdownHeight + scrollTop) {\n dropdown.scrollTop = itemTop - dropdownHeight + itemHeight;\n } else if (itemTop < scrollTop) {\n dropdown.scrollTop = itemTop;\n }\n };\n\n const focusOptionByIndex = (index: number, oldIndex: number | null) => {\n if (index === oldIndex) {\n /* istanbul ignore next: нет представления как воспроизвести */\n return;\n }\n\n const option = options[index];\n\n if (isNotServicePreset(option) && option.disabled) {\n return;\n }\n\n scrollToElement(index);\n setFocusedOptionIndex(index);\n };\n\n const focusOption = (nextIndex: number | null, type: FocusActionType) => {\n let index = nextIndex === null ? -1 : nextIndex;\n\n if (type === FOCUS_ACTION_NEXT) {\n const nextIndex = findIndexAfter(options, index);\n index = nextIndex === -1 ? findIndexAfter(options) : nextIndex; // Следующий за index или первый валидный до index\n } else if (type === FOCUS_ACTION_PREV) {\n const beforeIndex = findIndexBefore(options, index);\n index = beforeIndex === -1 ? findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index\n }\n\n focusOptionByIndex(index, focusedOptionIndex);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (onKeyDownProp) {\n onKeyDownProp(event);\n }\n\n if (event.defaultPrevented || readOnly) {\n return;\n }\n\n switch (event.key) {\n case Keys.ARROW_UP:\n case Keys.ARROW_DOWN:\n event.preventDefault();\n\n if (!opened) {\n setOpened(true);\n focusOption(null, FOCUS_ACTION_NEXT);\n } else {\n focusOption(\n focusedOptionIndex,\n event.key === Keys.ARROW_UP ? FOCUS_ACTION_PREV : FOCUS_ACTION_NEXT,\n );\n }\n break;\n case Keys.ENTER: {\n if (!opened) {\n break;\n }\n if (focusedOptionIndex != null) {\n const foundOption = options[focusedOptionIndex];\n if (foundOption && isNotServicePreset(foundOption)) {\n event.preventDefault();\n\n if (onChangeStart) {\n onChangeStart(event, foundOption);\n }\n\n addOption(foundOption);\n setFocusedOptionIndex(null);\n clearInput();\n if (closeAfterSelect) {\n setOpened(false);\n }\n\n break;\n }\n }\n\n if (!creatable) {\n event.preventDefault();\n }\n break;\n }\n case Keys.ESCAPE:\n case Keys.TAB:\n if (opened) {\n setOpened(false);\n }\n }\n };\n\n React.useEffect(() => {\n if (focusedOptionIndex === null) {\n setFocusedOption(null);\n } else {\n const foundFocusedOptionIndex = options[focusedOptionIndex];\n\n if (foundFocusedOptionIndex && isNotServicePreset(foundFocusedOptionIndex)) {\n setFocusedOption(foundFocusedOptionIndex);\n }\n }\n }, [options, focusedOptionIndex, setFocusedOption]);\n\n const onDropdownMouseLeave = React.useCallback(() => {\n setFocusedOptionIndex(null);\n }, [setFocusedOptionIndex]);\n\n const handleClickOutside = React.useCallback(() => {\n setOpened(false);\n }, [setOpened]);\n\n useGlobalOnEventOutside(\n 'mousedown', // см. https://github.com/VKCOM/VKUI/pull/8582\n handleClickOutside,\n opened ? rootRef : null,\n opened ? dropdownScrollBoxRef : null,\n );\n\n const onDropdownIconClick: MouseEventHandler<SVGSVGElement> = React.useCallback(\n (e) => {\n e.preventDefault();\n setOpened(!opened);\n },\n [opened, setOpened],\n );\n\n const dropdownContent = React.useMemo(() => {\n const defaultDropdownContent = options.map((option, index) => {\n const dropdownItemId = `${dropdownId}-${index}`;\n\n if (isEmptyOptionPreset(option)) {\n return (\n <Footnote key=\"empty-text\" className={styles.empty}>\n {option.placeholder}\n </Footnote>\n );\n }\n if (isCreateNewOptionPreset(option)) {\n return (\n <CustomSelectOption\n key=\"create-new-option\"\n id={dropdownItemId}\n hovered={focusedOptionIndex === index}\n onMouseDown={() => addOptionFromInput(inputValue)}\n onMouseEnter={() => setFocusedOptionIndex(index)}\n >\n {option.actionText}\n </CustomSelectOption>\n );\n }\n return (\n <React.Fragment key={`${typeof option.value}-${option.value}`}>\n {renderOption(\n {\n id: dropdownItemId,\n disabled: option.disabled,\n hovered: focusedOption\n ? getOptionValue(option) === getOptionValue(focusedOption)\n : false,\n children: option.label,\n selected: !!value.find(\n (selectedOption: Option) =>\n getOptionValue(selectedOption) === getOptionValue(option),\n ),\n getRootRef(node) {\n if (node) {\n chipsSelectOptions[index] = node;\n }\n },\n onMouseDown(event: React.MouseEvent<HTMLDivElement>) {\n if (option.disabled) {\n return;\n }\n if (onChangeStart) {\n onChangeStart(event, option);\n }\n\n if (!event.defaultPrevented) {\n closeAfterSelect && setOpened(false);\n addOption(option);\n clearInput();\n }\n },\n onMouseEnter() {\n setFocusedOptionIndex(index);\n },\n },\n option,\n )}\n </React.Fragment>\n );\n });\n\n if (renderDropdown) {\n return renderDropdown({\n defaultDropdownContent,\n });\n }\n return defaultDropdownContent;\n }, [\n addOption,\n addOptionFromInput,\n chipsSelectOptions,\n clearInput,\n closeAfterSelect,\n dropdownId,\n focusedOption,\n focusedOptionIndex,\n getOptionValue,\n inputValue,\n onChangeStart,\n options,\n renderDropdown,\n renderOption,\n setFocusedOptionIndex,\n setOpened,\n value,\n ]);\n\n const openedClassNames = React.useMemo(\n () =>\n (opened &&\n dropdownOffsetDistance === 0 &&\n (dropdownVerticalPlacement.includes('top') ? styles.popUp : styles.popDown)) ||\n undefined,\n [dropdownOffsetDistance, opened, dropdownVerticalPlacement],\n );\n\n const clearButtonShown = allowClearButton && (!!value.length || !!inputValue.length);\n\n return (\n <>\n <ChipsInputBase\n {...restProps}\n disabled={disabled}\n readOnly={readOnly}\n clearButtonShown={clearButtonShown}\n clearButtonTestId={clearButtonTestId}\n // FormFieldProps\n id={labelledbyId}\n getRootRef={rootRef}\n className={classNames(styles.host, openedClassNames, className)}\n status={status}\n after={\n dropdownIconProp || (\n <DropdownIcon\n opened={opened}\n onClick={onDropdownIconClick}\n className={classNames(\n styles.dropdownIcon,\n clearButtonShown && styles.dropdownIconWithOffset,\n )}\n />\n )\n }\n // option\n value={value}\n onAddChipOption={addOptionFromInput}\n onRemoveChipOption={removeOption}\n renderChip={renderChip}\n onClear={clearOptions}\n // input\n getRef={inputRef}\n inputValue={inputValue}\n onInputChange={onInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n // a11y\n role=\"combobox\"\n aria-expanded={opened}\n aria-autocomplete=\"list\"\n aria-activedescendant={opened ? dropdownCurrentItemId : undefined}\n aria-haspopup=\"listbox\"\n chipsListLabel={chipsListLabel}\n />\n {opened && (\n <CustomSelectDropdown\n data-testid={dropdownTestId}\n targetRef={rootRef}\n placement={dropdownVerticalPlacement}\n scrollBoxRef={dropdownScrollBoxRef}\n onPlacementChange={onDropdownPlacementChange}\n onMouseLeave={onDropdownMouseLeave}\n fetching={fetching}\n autoWidth={dropdownAutoWidth}\n forcePortal={forceDropdownPortal}\n noMaxHeight={noMaxHeight}\n offsetDistance={dropdownOffsetDistance}\n overscrollBehavior={overscrollBehavior}\n // a11y\n id={dropdownId}\n role=\"listbox\"\n aria-labelledby={labelledbyId}\n >\n {dropdownContent}\n </CustomSelectDropdown>\n )}\n </>\n );\n};\n"],"names":["React","classNames","useExternRef","useGlobalOnEventOutside","Keys","defaultFilterFn","ChipsInputBase","getNewOptionDataDefault","getOptionLabelDefault","getOptionValueDefault","renderChipDefault","CustomSelectDropdown","CustomSelectOption","DropdownIcon","Footnote","DEFAULT_EMPTY_TEXT","DEFAULT_SELECTED_BEHAVIOR","FOCUS_ACTION_NEXT","FOCUS_ACTION_PREV","isCreateNewOptionPreset","isEmptyOptionPreset","isNotServicePreset","renderOptionDefault","useChipsSelect","findIndexAfter","options","startIndex","length","findIndex","option","i","disabled","findIndexBefore","endIndex","result","ChipsSelect","id","labelledbyId","getRootRef","className","status","icon","dropdownIconProp","onChangeStart","optionsProp","placement","placementProp","closeAfterSelect","selectedBehavior","emptyText","creatable","fetching","dropdownAutoWidth","forceDropdownPortal","noMaxHeight","filterFn","sortFn","dropdownTestId","onClose","onOpen","overscrollBehavior","renderDropdown","getRef","value","valueProp","defaultValue","inputValue","inputValueProp","defaultInputValue","readOnly","getOptionValue","getOptionLabel","getNewOptionData","renderChip","renderOption","onChange","onFocus","onFocusProp","onInputChange","onInputChangeProp","onBlur","onBlurProp","onKeyDown","onKeyDownProp","dropdownOffsetDistance","allowClearButton","clearButtonTestId","delimiter","chipsListLabel","restProps","addOptionFromInput","addOption","removeOption","clearOptions","inputRef","inputRefHook","clearInput","opened","setOpened","focusedOption","focusedOptionIndex","setFocusedOption","setFocusedOptionIndex","rootRef","dropdownVerticalPlacement","setDropdownVerticalPlacement","useState","onDropdownPlacementChange","useCallback","startsWith","dropdownId","useId","dropdownCurrentItemId","undefined","dropdownScrollBoxRef","useRef","handleFocus","event","handleBlur","defaultPrevented","preventDefault","chipsSelectOptions","current","scrollToElement","index","center","dropdown","item","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","oldIndex","focusOption","nextIndex","type","beforeIndex","handleKeyDown","key","ARROW_UP","ARROW_DOWN","ENTER","foundOption","ESCAPE","TAB","useEffect","foundFocusedOptionIndex","onDropdownMouseLeave","handleClickOutside","onDropdownIconClick","e","dropdownContent","useMemo","defaultDropdownContent","map","dropdownItemId","placeholder","hovered","onMouseDown","onMouseEnter","actionText","Fragment","children","label","selected","find","selectedOption","node","openedClassNames","includes","clearButtonShown","after","onClick","onAddChipOption","onRemoveChipOption","onClear","role","aria-expanded","aria-autocomplete","aria-activedescendant","aria-haspopup","data-testid","targetRef","scrollBoxRef","onPlacementChange","onMouseLeave","autoWidth","forcePortal","offsetDistance","aria-labelledby"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HorizontalScroll.d.ts","sourceRoot":"","sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"HorizontalScroll.d.ts","sourceRoot":"","sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAqBhF,MAAM,MAAM,qBAAqB,GAAG,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;AAExE,MAAM,WAAW,qBACf,SAAQ,yBAAyB,CAAC,cAAc,CAAC,EAC/C,MAAM,CAAC,cAAc,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC;;OAEG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACrC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAChC;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,uBAAuB,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IAC5C;;OAEG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3C;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AA6GD;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,gQAiB9B,qBAAqB,KAAG,KAAK,CAAC,SAyJhC,CAAC"}
|
|
@@ -8,6 +8,8 @@ import { classNames, noop } from "@vkontakte/vkjs";
|
|
|
8
8
|
import { useAdaptivityHasPointer } from "../../hooks/useAdaptivityHasPointer.js";
|
|
9
9
|
import { useConfigDirection } from "../../hooks/useConfigDirection.js";
|
|
10
10
|
import { useExternRef } from "../../hooks/useExternRef.js";
|
|
11
|
+
import { useFocusVisible } from "../../hooks/useFocusVisible.js";
|
|
12
|
+
import { useFocusVisibleClassName } from "../../hooks/useFocusVisibleClassName.js";
|
|
11
13
|
import { easeInOutSine } from "../../lib/fx.js";
|
|
12
14
|
import { useIsomorphicLayoutEffect } from "../../lib/useIsomorphicLayoutEffect.js";
|
|
13
15
|
import { RootComponent } from "../RootComponent/RootComponent.js";
|
|
@@ -105,6 +107,12 @@ function doScroll({ scrollElement, getScrollPosition, animationQueue, onScrollTo
|
|
|
105
107
|
]);
|
|
106
108
|
const [canScrollStart, setCanScrollStart] = React.useState(false);
|
|
107
109
|
const [canScrollEnd, setCanScrollEnd] = React.useState(false);
|
|
110
|
+
const _useFocusVisible = useFocusVisible(), { focusVisible } = _useFocusVisible, focusEvents = _object_without_properties(_useFocusVisible, [
|
|
111
|
+
"focusVisible"
|
|
112
|
+
]);
|
|
113
|
+
const focusVisibleClassNames = useFocusVisibleClassName({
|
|
114
|
+
focusVisible
|
|
115
|
+
});
|
|
108
116
|
const direction = useConfigDirection();
|
|
109
117
|
const isRtl = direction === 'rtl';
|
|
110
118
|
const isCustomScrollingRef = React.useRef(false);
|
|
@@ -227,15 +235,17 @@ function doScroll({ scrollElement, getScrollPosition, animationQueue, onScrollTo
|
|
|
227
235
|
className: classNames("vkuiHorizontalScroll__arrow", "vkuiHorizontalScroll__arrowRight"),
|
|
228
236
|
onClick: scrollToEnd
|
|
229
237
|
}),
|
|
230
|
-
/*#__PURE__*/ _jsx("div", {
|
|
231
|
-
className: "vkuiHorizontalScroll__in",
|
|
238
|
+
/*#__PURE__*/ _jsx("div", _object_spread_props(_object_spread({
|
|
239
|
+
className: classNames("vkuiHorizontalScroll__in", focusVisibleClassNames),
|
|
232
240
|
ref: scrollerRef,
|
|
241
|
+
tabIndex: 0
|
|
242
|
+
}, focusEvents), {
|
|
233
243
|
children: /*#__PURE__*/ _jsx(ContentWrapperComponent, {
|
|
234
244
|
className: classNames("vkuiHorizontalScroll__inWrapper", contentWrapperClassName),
|
|
235
245
|
ref: contentWrapperRef,
|
|
236
246
|
children: children
|
|
237
247
|
})
|
|
238
|
-
})
|
|
248
|
+
}))
|
|
239
249
|
]
|
|
240
250
|
}));
|
|
241
251
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { easeInOutSine } from '../../lib/fx';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasRef, HTMLAttributesWithRootRef } from '../../types';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { ScrollArrow, type ScrollArrowProps } from '../ScrollArrow/ScrollArrow';\nimport styles from './HorizontalScroll.module.css';\n\n/* eslint-disable jsdoc/require-jsdoc */\ninterface ScrollContext {\n scrollElement: HTMLElement | null;\n scrollAnimationDuration: number;\n animationQueue: VoidFunction[];\n getScrollPosition: (currentPosition: number) => number;\n onScrollToEndBorder: VoidFunction;\n onScrollEnd: VoidFunction;\n onScrollStart: VoidFunction;\n /**\n * Начальная ширина прокрутки.\n * В некоторых случаях может отличаться от текущей ширины прокрутки из-за transforms: translate.\n */\n initialScrollWidth: number;\n textDirection: 'ltr' | 'rtl';\n}\n/* eslint-enable jsdoc/require-jsdoc */\n\nexport type ScrollPositionHandler = (currentPosition: number) => number;\n\nexport interface HorizontalScrollProps\n extends HTMLAttributesWithRootRef<HTMLDivElement>,\n HasRef<HTMLDivElement> {\n /**\n * Функция для расчета величины прокрутки при нажатии на левую стрелку.\n */\n getScrollToLeft?: ScrollPositionHandler;\n /**\n * Функция для расчета величины прокрутки при нажатии на правую стрелку.\n */\n getScrollToRight?: ScrollPositionHandler;\n /**\n * Размер стрелок.\n */\n arrowSize?: ScrollArrowProps['size'];\n /**\n * Смещает иконки кнопок навигации по вертикали.\n */\n arrowOffsetY?: number | string;\n /**\n * Показывать ли стрелки.\n */\n showArrows?: boolean | 'always';\n /**\n * Длительность анимации скролла.\n */\n scrollAnimationDuration?: number;\n /**\n * Добавляет возможность прокручивать контент на любое колесо мыши.\n * По умолчанию прокручивается как любой горизонтальный контент через shift.\n */\n scrollOnAnyWheel?: boolean;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении предыдущего элемента.\n */\n prevButtonTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении следующего элемента.\n */\n nextButtonTestId?: string;\n /**\n * Позволяет поменять тег используемый для обертки над контентом, прокинутым в `children`.\n */\n ContentWrapperComponent?: React.ElementType;\n /**\n * `ref` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperRef?: React.Ref<HTMLElement>;\n /**\n * Специфичный `className` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperClassName?: string;\n}\n\n/**\n * Timing method.\n */\nfunction now() {\n return performance && performance.now ? performance.now() : Date.now();\n}\n\n/**\n * Округление к большему по модулю.\n *\n * ## Пример\n *\n * ```ts\n * import { strict as assert } from 'node:assert';\n *\n * assert.equal(roundingAwayFromZero(5.1), 6)\n * assert.equal(roundingAwayFromZero(-5.1), -6)\n * ```\n */\nfunction roundingAwayFromZero(value: number): number {\n return value > 0 ? Math.ceil(value) : Math.floor(value);\n}\n\n/**\n * Округляем el.scrollLeft\n * https://github.com/VKCOM/VKUI/pull/2445.\n */\nconst roundUpElementScrollLeft = (el: HTMLElement) => roundingAwayFromZero(el.scrollLeft);\n\n/**\n * Код анимации скрола, на основе полифила: https://github.com/iamdustan/smoothscroll\n * Константа взята из полифила (468), на дизайн-ревью уточнили до 250.\n * @var {number} SCROLL_ONE_FRAME_TIME время анимации скролла\n */\nconst SCROLL_ONE_FRAME_TIME = 250;\n\nfunction doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue,\n onScrollToEndBorder,\n onScrollEnd,\n onScrollStart,\n initialScrollWidth,\n scrollAnimationDuration,\n textDirection,\n}: ScrollContext) {\n if (!scrollElement || !getScrollPosition) {\n return;\n }\n\n /**\n * Крайнее значение сдвига.\n */\n const extremeScrollLeft =\n (textDirection === 'ltr' ? 1 : -1) * (initialScrollWidth - scrollElement.offsetWidth);\n\n const startScrollLeft = roundUpElementScrollLeft(scrollElement);\n const remappedStartScrollLeft = startScrollLeft * (textDirection === 'rtl' ? -1 : 1);\n\n let endScrollLeft = getScrollPosition(remappedStartScrollLeft);\n\n const diff = endScrollLeft - remappedStartScrollLeft;\n if (textDirection === 'rtl') {\n endScrollLeft = startScrollLeft - diff;\n }\n\n onScrollStart();\n\n /**\n * Если окончание прокрутки вышло за ноль.\n */\n if (startScrollLeft * endScrollLeft < 0) {\n endScrollLeft = 0;\n }\n\n if (Math.abs(endScrollLeft) >= Math.abs(extremeScrollLeft)) {\n onScrollToEndBorder();\n endScrollLeft = extremeScrollLeft;\n }\n\n const startTime = now();\n\n (function scroll() {\n const time = now();\n const elapsed = Math.min((time - startTime) / scrollAnimationDuration, 1);\n\n const value = easeInOutSine(elapsed);\n\n const currentScrollLeft = startScrollLeft + (endScrollLeft - startScrollLeft) * value;\n scrollElement.scrollLeft = roundingAwayFromZero(currentScrollLeft);\n\n const scrollEnd =\n textDirection === 'ltr' ? Math.max(0, endScrollLeft) : Math.min(0, endScrollLeft);\n if (roundUpElementScrollLeft(scrollElement) !== scrollEnd && elapsed !== 1) {\n requestAnimationFrame(scroll);\n return;\n }\n\n onScrollEnd();\n animationQueue.shift();\n if (animationQueue.length > 0) {\n animationQueue[0]();\n }\n })();\n}\n\n/**\n * @see https://vkui.io/components/horizontal-scroll\n */\nexport const HorizontalScroll = ({\n children,\n getScrollToLeft,\n getScrollToRight,\n showArrows = true,\n arrowSize = 'm',\n arrowOffsetY,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n getRef,\n scrollOnAnyWheel = false,\n prevButtonTestId,\n nextButtonTestId,\n // ContentWrapper\n ContentWrapperComponent = 'div',\n contentWrapperRef,\n contentWrapperClassName,\n ...restProps\n}: HorizontalScrollProps): React.ReactNode => {\n const [canScrollStart, setCanScrollStart] = React.useState(false);\n const [canScrollEnd, setCanScrollEnd] = React.useState(false);\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const isCustomScrollingRef = React.useRef(false);\n\n const scrollerRef = useExternRef(getRef);\n\n const animationQueue = React.useRef<VoidFunction[]>([]);\n\n const hasPointer = useAdaptivityHasPointer();\n\n const scrollTo = React.useCallback(\n (getScrollPosition: ScrollPositionHandler) => {\n const scrollElement = scrollerRef.current;\n\n animationQueue.current.push(() =>\n doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue: animationQueue.current,\n onScrollToEndBorder: () => setCanScrollEnd(false),\n onScrollEnd: () => (isCustomScrollingRef.current = false),\n onScrollStart: () => (isCustomScrollingRef.current = true),\n initialScrollWidth: scrollElement?.firstElementChild?.scrollWidth || 0,\n scrollAnimationDuration,\n textDirection: direction,\n }),\n );\n if (animationQueue.current.length === 1) {\n animationQueue.current[0]();\n }\n },\n [scrollerRef, scrollAnimationDuration, direction, setCanScrollEnd],\n );\n\n const scrollToStart = React.useCallback(() => {\n const getScrollPosition =\n getScrollToLeft ?? ((i: number) => i - scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToLeft, scrollTo, scrollerRef]);\n\n const scrollToEnd = React.useCallback(() => {\n const getScrollPosition =\n getScrollToRight ?? ((i: number) => i + scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToRight, scrollTo, scrollerRef]);\n\n const calculateArrowsVisibility = React.useCallback(() => {\n if (showArrows && hasPointer && scrollerRef.current && !isCustomScrollingRef.current) {\n const scrollElement = scrollerRef.current;\n const scrollLeft = scrollElement.scrollLeft;\n\n setCanScrollStart(isRtl ? scrollLeft < 0 : scrollLeft > 0);\n setCanScrollEnd(\n Math.abs(roundUpElementScrollLeft(scrollElement)) + scrollElement.offsetWidth <\n scrollElement.scrollWidth,\n );\n }\n }, [showArrows, hasPointer, scrollerRef, isRtl]);\n\n React.useEffect(calculateArrowsVisibility, [calculateArrowsVisibility, children]);\n\n useIsomorphicLayoutEffect(\n function addWheelEventHandler() {\n const scrollEl = scrollerRef.current;\n if (!scrollEl) {\n return noop;\n }\n /**\n * Прокрутка с помощью любого колеса мыши.\n */\n const onWheel = (e: WheelEvent) => {\n scrollerRef.current!.scrollBy({ left: e.deltaX + e.deltaY, behavior: 'auto' });\n e.preventDefault();\n };\n\n const listenerOptions = { passive: false };\n\n if (scrollOnAnyWheel) {\n scrollEl.addEventListener('wheel', onWheel, listenerOptions);\n }\n scrollEl.addEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n\n return () => {\n if (scrollOnAnyWheel) {\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для wheel нет passive свойства\n scrollEl.removeEventListener('wheel', onWheel, listenerOptions);\n }\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для scroll нет passive свойства\n scrollEl.removeEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n };\n },\n [scrollOnAnyWheel, calculateArrowsVisibility, scrollerRef],\n );\n\n return (\n <RootComponent\n {...restProps}\n baseClassName={classNames(\n styles.host,\n 'vkuiInternalHorizontalScroll',\n showArrows === 'always' && styles.withConstArrows,\n isRtl && styles.rtl,\n )}\n onMouseEnter={calculateArrowsVisibility}\n >\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollStart && (\n <ScrollArrow\n data-testid={prevButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"left\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowLeft)}\n onClick={scrollToStart}\n />\n )}\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollEnd && (\n <ScrollArrow\n data-testid={nextButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"right\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowRight)}\n onClick={scrollToEnd}\n />\n )}\n <div className={styles.in} ref={scrollerRef}>\n <ContentWrapperComponent\n className={classNames(styles.inWrapper, contentWrapperClassName)}\n ref={contentWrapperRef}\n >\n {children}\n </ContentWrapperComponent>\n </div>\n </RootComponent>\n );\n};\n"],"names":["React","classNames","noop","useAdaptivityHasPointer","useConfigDirection","useExternRef","easeInOutSine","useIsomorphicLayoutEffect","RootComponent","ScrollArrow","now","performance","Date","roundingAwayFromZero","value","Math","ceil","floor","roundUpElementScrollLeft","el","scrollLeft","SCROLL_ONE_FRAME_TIME","doScroll","scrollElement","getScrollPosition","animationQueue","onScrollToEndBorder","onScrollEnd","onScrollStart","initialScrollWidth","scrollAnimationDuration","textDirection","extremeScrollLeft","offsetWidth","startScrollLeft","remappedStartScrollLeft","endScrollLeft","diff","abs","startTime","scroll","time","elapsed","min","currentScrollLeft","scrollEnd","max","requestAnimationFrame","shift","length","HorizontalScroll","children","getScrollToLeft","getScrollToRight","showArrows","arrowSize","arrowOffsetY","getRef","scrollOnAnyWheel","prevButtonTestId","nextButtonTestId","ContentWrapperComponent","contentWrapperRef","contentWrapperClassName","restProps","canScrollStart","setCanScrollStart","useState","canScrollEnd","setCanScrollEnd","direction","isRtl","isCustomScrollingRef","useRef","scrollerRef","hasPointer","scrollTo","useCallback","current","push","firstElementChild","scrollWidth","scrollToStart","i","scrollToEnd","calculateArrowsVisibility","useEffect","addWheelEventHandler","scrollEl","onWheel","e","scrollBy","left","deltaX","deltaY","behavior","preventDefault","listenerOptions","passive","addEventListener","removeEventListener","baseClassName","onMouseEnter","undefined","data-testid","size","offsetY","aria-hidden","tabIndex","className","onClick","div","ref"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusVisible } from '../../hooks/useFocusVisible';\nimport { useFocusVisibleClassName } from '../../hooks/useFocusVisibleClassName';\nimport { easeInOutSine } from '../../lib/fx';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasRef, HTMLAttributesWithRootRef } from '../../types';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { ScrollArrow, type ScrollArrowProps } from '../ScrollArrow/ScrollArrow';\nimport styles from './HorizontalScroll.module.css';\n\n/* eslint-disable jsdoc/require-jsdoc */\ninterface ScrollContext {\n scrollElement: HTMLElement | null;\n scrollAnimationDuration: number;\n animationQueue: VoidFunction[];\n getScrollPosition: (currentPosition: number) => number;\n onScrollToEndBorder: VoidFunction;\n onScrollEnd: VoidFunction;\n onScrollStart: VoidFunction;\n /**\n * Начальная ширина прокрутки.\n * В некоторых случаях может отличаться от текущей ширины прокрутки из-за transforms: translate.\n */\n initialScrollWidth: number;\n textDirection: 'ltr' | 'rtl';\n}\n/* eslint-enable jsdoc/require-jsdoc */\n\nexport type ScrollPositionHandler = (currentPosition: number) => number;\n\nexport interface HorizontalScrollProps\n extends HTMLAttributesWithRootRef<HTMLDivElement>,\n HasRef<HTMLDivElement> {\n /**\n * Функция для расчета величины прокрутки при нажатии на левую стрелку.\n */\n getScrollToLeft?: ScrollPositionHandler;\n /**\n * Функция для расчета величины прокрутки при нажатии на правую стрелку.\n */\n getScrollToRight?: ScrollPositionHandler;\n /**\n * Размер стрелок.\n */\n arrowSize?: ScrollArrowProps['size'];\n /**\n * Смещает иконки кнопок навигации по вертикали.\n */\n arrowOffsetY?: number | string;\n /**\n * Показывать ли стрелки.\n */\n showArrows?: boolean | 'always';\n /**\n * Длительность анимации скролла.\n */\n scrollAnimationDuration?: number;\n /**\n * Добавляет возможность прокручивать контент на любое колесо мыши.\n * По умолчанию прокручивается как любой горизонтальный контент через shift.\n */\n scrollOnAnyWheel?: boolean;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении предыдущего элемента.\n */\n prevButtonTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении следующего элемента.\n */\n nextButtonTestId?: string;\n /**\n * Позволяет поменять тег используемый для обертки над контентом, прокинутым в `children`.\n */\n ContentWrapperComponent?: React.ElementType;\n /**\n * `ref` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperRef?: React.Ref<HTMLElement>;\n /**\n * Специфичный `className` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperClassName?: string;\n}\n\n/**\n * Timing method.\n */\nfunction now() {\n return performance && performance.now ? performance.now() : Date.now();\n}\n\n/**\n * Округление к большему по модулю.\n *\n * ## Пример\n *\n * ```ts\n * import { strict as assert } from 'node:assert';\n *\n * assert.equal(roundingAwayFromZero(5.1), 6)\n * assert.equal(roundingAwayFromZero(-5.1), -6)\n * ```\n */\nfunction roundingAwayFromZero(value: number): number {\n return value > 0 ? Math.ceil(value) : Math.floor(value);\n}\n\n/**\n * Округляем el.scrollLeft\n * https://github.com/VKCOM/VKUI/pull/2445.\n */\nconst roundUpElementScrollLeft = (el: HTMLElement) => roundingAwayFromZero(el.scrollLeft);\n\n/**\n * Код анимации скрола, на основе полифила: https://github.com/iamdustan/smoothscroll\n * Константа взята из полифила (468), на дизайн-ревью уточнили до 250.\n * @var {number} SCROLL_ONE_FRAME_TIME время анимации скролла\n */\nconst SCROLL_ONE_FRAME_TIME = 250;\n\nfunction doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue,\n onScrollToEndBorder,\n onScrollEnd,\n onScrollStart,\n initialScrollWidth,\n scrollAnimationDuration,\n textDirection,\n}: ScrollContext) {\n if (!scrollElement || !getScrollPosition) {\n return;\n }\n\n /**\n * Крайнее значение сдвига.\n */\n const extremeScrollLeft =\n (textDirection === 'ltr' ? 1 : -1) * (initialScrollWidth - scrollElement.offsetWidth);\n\n const startScrollLeft = roundUpElementScrollLeft(scrollElement);\n const remappedStartScrollLeft = startScrollLeft * (textDirection === 'rtl' ? -1 : 1);\n\n let endScrollLeft = getScrollPosition(remappedStartScrollLeft);\n\n const diff = endScrollLeft - remappedStartScrollLeft;\n if (textDirection === 'rtl') {\n endScrollLeft = startScrollLeft - diff;\n }\n\n onScrollStart();\n\n /**\n * Если окончание прокрутки вышло за ноль.\n */\n if (startScrollLeft * endScrollLeft < 0) {\n endScrollLeft = 0;\n }\n\n if (Math.abs(endScrollLeft) >= Math.abs(extremeScrollLeft)) {\n onScrollToEndBorder();\n endScrollLeft = extremeScrollLeft;\n }\n\n const startTime = now();\n\n (function scroll() {\n const time = now();\n const elapsed = Math.min((time - startTime) / scrollAnimationDuration, 1);\n\n const value = easeInOutSine(elapsed);\n\n const currentScrollLeft = startScrollLeft + (endScrollLeft - startScrollLeft) * value;\n scrollElement.scrollLeft = roundingAwayFromZero(currentScrollLeft);\n\n const scrollEnd =\n textDirection === 'ltr' ? Math.max(0, endScrollLeft) : Math.min(0, endScrollLeft);\n if (roundUpElementScrollLeft(scrollElement) !== scrollEnd && elapsed !== 1) {\n requestAnimationFrame(scroll);\n return;\n }\n\n onScrollEnd();\n animationQueue.shift();\n if (animationQueue.length > 0) {\n animationQueue[0]();\n }\n })();\n}\n\n/**\n * @see https://vkui.io/components/horizontal-scroll\n */\nexport const HorizontalScroll = ({\n children,\n getScrollToLeft,\n getScrollToRight,\n showArrows = true,\n arrowSize = 'm',\n arrowOffsetY,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n getRef,\n scrollOnAnyWheel = false,\n prevButtonTestId,\n nextButtonTestId,\n // ContentWrapper\n ContentWrapperComponent = 'div',\n contentWrapperRef,\n contentWrapperClassName,\n ...restProps\n}: HorizontalScrollProps): React.ReactNode => {\n const [canScrollStart, setCanScrollStart] = React.useState(false);\n const [canScrollEnd, setCanScrollEnd] = React.useState(false);\n const { focusVisible, ...focusEvents } = useFocusVisible();\n const focusVisibleClassNames = useFocusVisibleClassName({\n focusVisible,\n });\n\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const isCustomScrollingRef = React.useRef(false);\n\n const scrollerRef = useExternRef(getRef);\n\n const animationQueue = React.useRef<VoidFunction[]>([]);\n\n const hasPointer = useAdaptivityHasPointer();\n\n const scrollTo = React.useCallback(\n (getScrollPosition: ScrollPositionHandler) => {\n const scrollElement = scrollerRef.current;\n\n animationQueue.current.push(() =>\n doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue: animationQueue.current,\n onScrollToEndBorder: () => setCanScrollEnd(false),\n onScrollEnd: () => (isCustomScrollingRef.current = false),\n onScrollStart: () => (isCustomScrollingRef.current = true),\n initialScrollWidth: scrollElement?.firstElementChild?.scrollWidth || 0,\n scrollAnimationDuration,\n textDirection: direction,\n }),\n );\n if (animationQueue.current.length === 1) {\n animationQueue.current[0]();\n }\n },\n [scrollerRef, scrollAnimationDuration, direction, setCanScrollEnd],\n );\n\n const scrollToStart = React.useCallback(() => {\n const getScrollPosition =\n getScrollToLeft ?? ((i: number) => i - scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToLeft, scrollTo, scrollerRef]);\n\n const scrollToEnd = React.useCallback(() => {\n const getScrollPosition =\n getScrollToRight ?? ((i: number) => i + scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToRight, scrollTo, scrollerRef]);\n\n const calculateArrowsVisibility = React.useCallback(() => {\n if (showArrows && hasPointer && scrollerRef.current && !isCustomScrollingRef.current) {\n const scrollElement = scrollerRef.current;\n const scrollLeft = scrollElement.scrollLeft;\n\n setCanScrollStart(isRtl ? scrollLeft < 0 : scrollLeft > 0);\n setCanScrollEnd(\n Math.abs(roundUpElementScrollLeft(scrollElement)) + scrollElement.offsetWidth <\n scrollElement.scrollWidth,\n );\n }\n }, [showArrows, hasPointer, scrollerRef, isRtl]);\n\n React.useEffect(calculateArrowsVisibility, [calculateArrowsVisibility, children]);\n\n useIsomorphicLayoutEffect(\n function addWheelEventHandler() {\n const scrollEl = scrollerRef.current;\n if (!scrollEl) {\n return noop;\n }\n /**\n * Прокрутка с помощью любого колеса мыши.\n */\n const onWheel = (e: WheelEvent) => {\n scrollerRef.current!.scrollBy({ left: e.deltaX + e.deltaY, behavior: 'auto' });\n e.preventDefault();\n };\n\n const listenerOptions = { passive: false };\n\n if (scrollOnAnyWheel) {\n scrollEl.addEventListener('wheel', onWheel, listenerOptions);\n }\n scrollEl.addEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n\n return () => {\n if (scrollOnAnyWheel) {\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для wheel нет passive свойства\n scrollEl.removeEventListener('wheel', onWheel, listenerOptions);\n }\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для scroll нет passive свойства\n scrollEl.removeEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n };\n },\n [scrollOnAnyWheel, calculateArrowsVisibility, scrollerRef],\n );\n\n return (\n <RootComponent\n {...restProps}\n baseClassName={classNames(\n styles.host,\n 'vkuiInternalHorizontalScroll',\n showArrows === 'always' && styles.withConstArrows,\n isRtl && styles.rtl,\n )}\n onMouseEnter={calculateArrowsVisibility}\n >\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollStart && (\n <ScrollArrow\n data-testid={prevButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"left\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowLeft)}\n onClick={scrollToStart}\n />\n )}\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollEnd && (\n <ScrollArrow\n data-testid={nextButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"right\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowRight)}\n onClick={scrollToEnd}\n />\n )}\n <div\n className={classNames(styles.in, focusVisibleClassNames)}\n ref={scrollerRef}\n tabIndex={0}\n {...focusEvents}\n >\n <ContentWrapperComponent\n className={classNames(styles.inWrapper, contentWrapperClassName)}\n ref={contentWrapperRef}\n >\n {children}\n </ContentWrapperComponent>\n </div>\n </RootComponent>\n );\n};\n"],"names":["React","classNames","noop","useAdaptivityHasPointer","useConfigDirection","useExternRef","useFocusVisible","useFocusVisibleClassName","easeInOutSine","useIsomorphicLayoutEffect","RootComponent","ScrollArrow","now","performance","Date","roundingAwayFromZero","value","Math","ceil","floor","roundUpElementScrollLeft","el","scrollLeft","SCROLL_ONE_FRAME_TIME","doScroll","scrollElement","getScrollPosition","animationQueue","onScrollToEndBorder","onScrollEnd","onScrollStart","initialScrollWidth","scrollAnimationDuration","textDirection","extremeScrollLeft","offsetWidth","startScrollLeft","remappedStartScrollLeft","endScrollLeft","diff","abs","startTime","scroll","time","elapsed","min","currentScrollLeft","scrollEnd","max","requestAnimationFrame","shift","length","HorizontalScroll","children","getScrollToLeft","getScrollToRight","showArrows","arrowSize","arrowOffsetY","getRef","scrollOnAnyWheel","prevButtonTestId","nextButtonTestId","ContentWrapperComponent","contentWrapperRef","contentWrapperClassName","restProps","canScrollStart","setCanScrollStart","useState","canScrollEnd","setCanScrollEnd","focusVisible","focusEvents","focusVisibleClassNames","direction","isRtl","isCustomScrollingRef","useRef","scrollerRef","hasPointer","scrollTo","useCallback","current","push","firstElementChild","scrollWidth","scrollToStart","i","scrollToEnd","calculateArrowsVisibility","useEffect","addWheelEventHandler","scrollEl","onWheel","e","scrollBy","left","deltaX","deltaY","behavior","preventDefault","listenerOptions","passive","addEventListener","removeEventListener","baseClassName","onMouseEnter","undefined","data-testid","size","offsetY","aria-hidden","tabIndex","className","onClick","div","ref"],"mappings":"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"}
|