@vkontakte/vkui 5.7.0 → 5.7.2
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/cjs/components/Banner/Banner.js +1 -1
- package/dist/cjs/components/Banner/Banner.js.map +1 -1
- package/dist/cjs/components/Checkbox/Checkbox.js +3 -1
- package/dist/cjs/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/cjs/components/ChipsSelect/ChipsSelect.js +4 -2
- package/dist/cjs/components/ChipsSelect/ChipsSelect.js.map +1 -1
- package/dist/cjs/components/Group/Group.js +2 -3
- package/dist/cjs/components/Group/Group.js.map +1 -1
- package/dist/cjs/components/HorizontalScroll/HorizontalScroll.js +13 -11
- package/dist/cjs/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/dist/cjs/components/Image/Image.js +52 -37
- package/dist/cjs/components/Image/Image.js.map +1 -1
- package/dist/cjs/components/ImageBase/ImageBase.js +20 -1
- package/dist/cjs/components/ImageBase/ImageBase.js.map +1 -1
- package/dist/cjs/components/MiniInfoCell/MiniInfoCell.js +1 -1
- package/dist/cjs/components/MiniInfoCell/MiniInfoCell.js.map +1 -1
- package/dist/cjs/components/PopoutRoot/PopoutRoot.js +1 -3
- package/dist/cjs/components/PopoutRoot/PopoutRoot.js.map +1 -1
- package/dist/cjs/components/PopoutWrapper/PopoutWrapper.js +1 -1
- package/dist/cjs/components/PopoutWrapper/PopoutWrapper.js.map +1 -1
- package/dist/cjs/components/SelectMimicry/SelectMimicry.d.ts +1 -1
- package/dist/cjs/components/SelectMimicry/SelectMimicry.js +8 -3
- package/dist/cjs/components/SelectMimicry/SelectMimicry.js.map +1 -1
- package/dist/cjs/components/SimpleCell/SimpleCell.js +0 -1
- package/dist/cjs/components/SimpleCell/SimpleCell.js.map +1 -1
- package/dist/cjs/components/View/View.js +4 -4
- package/dist/cjs/components/View/View.js.map +1 -1
- package/dist/cjs/components/View/ViewInfinite.js +4 -4
- package/dist/cjs/components/View/ViewInfinite.js.map +1 -1
- package/dist/cjs/hooks/useAdaptivityHasHover.js +4 -3
- package/dist/cjs/hooks/useAdaptivityHasHover.js.map +1 -1
- package/dist/cjs/hooks/useAdaptivityHasPointer.js +5 -5
- package/dist/cjs/hooks/useAdaptivityHasPointer.js.map +1 -1
- package/dist/cjs/hooks/useAutoFocus.d.ts +2 -0
- package/dist/cjs/hooks/useAutoFocus.js +23 -0
- package/dist/cjs/hooks/useAutoFocus.js.map +1 -0
- package/dist/cjs/hooks/useChipsSelect.js +5 -4
- package/dist/cjs/hooks/useChipsSelect.js.map +1 -1
- package/dist/cjs/hooks/useFocusWithin.js +3 -0
- package/dist/cjs/hooks/useFocusWithin.js.map +1 -1
- package/dist/cjs/hooks/useIsClient.js +2 -1
- package/dist/cjs/hooks/useIsClient.js.map +1 -1
- package/dist/components/Banner/Banner.js +2 -2
- package/dist/components/Banner/Banner.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.js +3 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/ChipsSelect/ChipsSelect.js +4 -2
- package/dist/components/ChipsSelect/ChipsSelect.js.map +1 -1
- package/dist/components/Group/Group.js +2 -3
- package/dist/components/Group/Group.js.map +1 -1
- package/dist/components/HorizontalScroll/HorizontalScroll.js +13 -11
- package/dist/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/dist/components/Image/Image.js +54 -39
- package/dist/components/Image/Image.js.map +1 -1
- package/dist/components/ImageBase/ImageBase.js +20 -1
- package/dist/components/ImageBase/ImageBase.js.map +1 -1
- package/dist/components/MiniInfoCell/MiniInfoCell.js +1 -1
- package/dist/components/MiniInfoCell/MiniInfoCell.js.map +1 -1
- package/dist/components/PopoutRoot/PopoutRoot.js +1 -3
- package/dist/components/PopoutRoot/PopoutRoot.js.map +1 -1
- package/dist/components/PopoutWrapper/PopoutWrapper.js +1 -1
- package/dist/components/PopoutWrapper/PopoutWrapper.js.map +1 -1
- package/dist/components/SelectMimicry/SelectMimicry.d.ts +1 -1
- package/dist/components/SelectMimicry/SelectMimicry.js +8 -3
- package/dist/components/SelectMimicry/SelectMimicry.js.map +1 -1
- package/dist/components/SimpleCell/SimpleCell.js +0 -1
- package/dist/components/SimpleCell/SimpleCell.js.map +1 -1
- package/dist/components/View/View.js +4 -4
- package/dist/components/View/View.js.map +1 -1
- package/dist/components/View/ViewInfinite.js +4 -4
- package/dist/components/View/ViewInfinite.js.map +1 -1
- package/dist/components.css +22 -22
- package/dist/components.css.map +1 -1
- package/dist/components.js.tmp +757 -698
- package/dist/cssm/components/ActionSheet/ActionSheet.module.css +3 -3
- package/dist/cssm/components/Alert/Alert.module.css +4 -4
- package/dist/cssm/components/Banner/Banner.js +2 -2
- package/dist/cssm/components/Banner/Banner.js.map +1 -1
- package/dist/cssm/components/Banner/Banner.module.css +2 -2
- package/dist/cssm/components/Checkbox/Checkbox.js +3 -1
- package/dist/cssm/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/cssm/components/Checkbox/Checkbox.module.css +6 -0
- package/dist/cssm/components/ChipsSelect/ChipsSelect.js +3 -1
- package/dist/cssm/components/ChipsSelect/ChipsSelect.js.map +1 -1
- package/dist/cssm/components/FocusVisible/FocusVisible.module.css +4 -4
- package/dist/cssm/components/Group/Group.js +2 -3
- package/dist/cssm/components/Group/Group.js.map +1 -1
- package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js +13 -11
- package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/dist/cssm/components/Image/Image.js +46 -33
- package/dist/cssm/components/Image/Image.js.map +1 -1
- package/dist/cssm/components/ImageBase/ImageBase.js +20 -1
- package/dist/cssm/components/ImageBase/ImageBase.js.map +1 -1
- package/dist/cssm/components/MiniInfoCell/MiniInfoCell.js +1 -1
- package/dist/cssm/components/MiniInfoCell/MiniInfoCell.js.map +1 -1
- package/dist/cssm/components/ModalPage/ModalPage.module.css +0 -4
- package/dist/cssm/components/ModalRoot/ModalRoot.module.css +2 -2
- package/dist/cssm/components/PanelHeader/PanelHeader.module.css +4 -2
- package/dist/cssm/components/PanelHeaderContext/PanelHeaderContext.module.css +8 -8
- package/dist/cssm/components/Placeholder/Placeholder.module.css +1 -0
- package/dist/cssm/components/PopoutRoot/PopoutRoot.js +1 -3
- package/dist/cssm/components/PopoutRoot/PopoutRoot.js.map +1 -1
- package/dist/cssm/components/PopoutRoot/PopoutRoot.module.css +0 -4
- package/dist/cssm/components/PopoutWrapper/PopoutWrapper.js +1 -1
- package/dist/cssm/components/PopoutWrapper/PopoutWrapper.js.map +1 -1
- package/dist/cssm/components/PopoutWrapper/PopoutWrapper.module.css +2 -2
- package/dist/cssm/components/Popover/Popover.module.css +2 -2
- package/dist/cssm/components/PullToRefresh/PullToRefresh.module.css +4 -4
- package/dist/cssm/components/RichTooltip/RichTooltip.module.css +2 -2
- package/dist/cssm/components/Root/Root.module.css +12 -13
- package/dist/cssm/components/ScreenSpinner/ScreenSpinner.module.css +5 -5
- package/dist/cssm/components/SelectMimicry/SelectMimicry.d.ts +1 -1
- package/dist/cssm/components/SelectMimicry/SelectMimicry.js +6 -2
- package/dist/cssm/components/SelectMimicry/SelectMimicry.js.map +1 -1
- package/dist/cssm/components/SimpleCell/SimpleCell.js +0 -1
- package/dist/cssm/components/SimpleCell/SimpleCell.js.map +1 -1
- package/dist/cssm/components/Snackbar/Snackbar.module.css +4 -4
- package/dist/cssm/components/Tappable/Tappable.module.css +2 -2
- package/dist/cssm/components/TextTooltip/TextTooltip.module.css +2 -2
- package/dist/cssm/components/View/View.js +4 -4
- package/dist/cssm/components/View/View.js.map +1 -1
- package/dist/cssm/components/View/View.module.css +16 -16
- package/dist/cssm/components/View/ViewInfinite.js +4 -4
- package/dist/cssm/components/View/ViewInfinite.js.map +1 -1
- package/dist/cssm/hooks/useAdaptivityHasHover.js +4 -3
- package/dist/cssm/hooks/useAdaptivityHasHover.js.map +1 -1
- package/dist/cssm/hooks/useAdaptivityHasPointer.js +5 -5
- package/dist/cssm/hooks/useAdaptivityHasPointer.js.map +1 -1
- package/dist/cssm/hooks/useAutoFocus.d.ts +2 -0
- package/dist/cssm/hooks/useAutoFocus.js +12 -0
- package/dist/cssm/hooks/useAutoFocus.js.map +1 -0
- package/dist/cssm/hooks/useChipsSelect.js +5 -4
- package/dist/cssm/hooks/useChipsSelect.js.map +1 -1
- package/dist/cssm/hooks/useFocusWithin.js +3 -0
- package/dist/cssm/hooks/useFocusWithin.js.map +1 -1
- package/dist/cssm/hooks/useIsClient.js +2 -1
- package/dist/cssm/hooks/useIsClient.js.map +1 -1
- package/dist/cssm/styles/constants.css +1 -1
- package/dist/hooks/useAdaptivityHasHover.js +4 -3
- package/dist/hooks/useAdaptivityHasHover.js.map +1 -1
- package/dist/hooks/useAdaptivityHasPointer.js +5 -5
- package/dist/hooks/useAdaptivityHasPointer.js.map +1 -1
- package/dist/hooks/useAutoFocus.d.ts +2 -0
- package/dist/hooks/useAutoFocus.js +12 -0
- package/dist/hooks/useAutoFocus.js.map +1 -0
- package/dist/hooks/useChipsSelect.js +5 -4
- package/dist/hooks/useChipsSelect.js.map +1 -1
- package/dist/hooks/useFocusWithin.js +3 -0
- package/dist/hooks/useFocusWithin.js.map +1 -1
- package/dist/hooks/useIsClient.js +2 -1
- package/dist/hooks/useIsClient.js.map +1 -1
- package/dist/vkui.css +22 -22
- package/dist/vkui.css.map +1 -1
- package/dist/vkui.js.tmp +757 -698
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useChipsSelect } from '../../hooks/useChipsSelect';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useGlobalEventListener } from '../../hooks/useGlobalEventListener';\nimport { useDOM } from '../../lib/dom';\nimport type { Placement } from '../../lib/floating';\nimport { defaultFilterFn } from '../../lib/select';\nimport { ChipOption, ChipValue, RenderChip } from '../Chip/Chip';\nimport { ChipsInputProps } from '../ChipsInput/ChipsInput';\nimport { ChipsInputBase, chipsInputDefaultProps } from '../ChipsInputBase/ChipsInputBase';\nimport { CustomSelectDropdown } from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport { FormField } from '../FormField/FormField';\nimport { IconButton } from '../IconButton/IconButton';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport styles from './ChipsSelect.module.css';\n\nexport interface ChipsSelectProps<Option extends ChipOption>\n extends Omit<ChipsInputProps<Option>, 'after'> {\n popupDirection?: 'top' | 'bottom';\n options?: Option[];\n filterFn?:\n | false\n | ((\n value?: string,\n option?: Option,\n getOptionLabel?: Pick<ChipsInputProps<Option>, 'getOptionLabel'>['getOptionLabel'],\n ) => boolean);\n /**\n * Возможность создавать чипы которых нет в списке (по enter или с помощью пункта в меню, см creatableText)\n */\n creatable?: boolean;\n /**\n * Отрисовка лоадера вместо списка опций в выпадающем списке\n */\n fetching?: boolean;\n renderOption?: (props: CustomSelectOptionProps) => React.ReactNode;\n /**\n * Показывать или скрывать уже выбранные опции\n */\n showSelected?: boolean;\n /**\n * Текст для пункта создающего чипы при клике, так же отвечает за то будет ли показан этот пункт (показывается после того как в списке не отсанется опций)\n */\n creatableText?: string;\n /**\n * Текст который показывается если список опций пуст\n */\n emptyText?: string;\n /**\n * Событие срабатывающее перед onChange\n */\n onChangeStart?: (e: React.MouseEvent | React.KeyboardEvent, option: Option) => void;\n /**\n * Закрытие выпадающего списка после выбора элемента\n */\n closeAfterSelect?: boolean;\n fixDropdownWidth?: boolean;\n forceDropdownPortal?: boolean;\n /**\n * Иконка раскрывающегося списка\n */\n icon?: React.ReactNode;\n /**\n * Добавляет значение в список на событие `onBlur` (использовать вместе с `creatable`)\n */\n addOnBlur?: boolean;\n}\n\ntype FocusActionType = 'next' | 'prev';\n\nconst FOCUS_ACTION_NEXT: FocusActionType = 'next';\nconst FOCUS_ACTION_PREV: FocusActionType = 'prev';\n\nconst chipsSelectDefaultProps: ChipsSelectProps<any> = {\n ...chipsInputDefaultProps,\n emptyText: 'Ничего не найдено',\n creatableText: 'Создать значение',\n onChangeStart: noop,\n creatable: false,\n fetching: false,\n showSelected: true,\n closeAfterSelect: true,\n options: [],\n filterFn: defaultFilterFn,\n renderOption(props) {\n return <CustomSelectOption {...props} />;\n },\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ChipsSelect\n */\nexport const ChipsSelect = <Option extends ChipOption>(props: ChipsSelectProps<Option>) => {\n const propsWithDefault = { ...chipsSelectDefaultProps, ...props };\n const {\n style,\n onFocus,\n onBlur,\n onKeyDown,\n className,\n fetching,\n renderOption,\n emptyText,\n getRef,\n getRootRef,\n disabled,\n placeholder,\n tabIndex,\n getOptionValue,\n getOptionLabel,\n showSelected,\n getNewOptionData,\n renderChip,\n popupDirection,\n creatable,\n filterFn,\n inputValue,\n creatableText,\n closeAfterSelect,\n onChangeStart,\n before,\n icon,\n options,\n fixDropdownWidth,\n forceDropdownPortal,\n ...restProps\n } = propsWithDefault;\n\n const { document } = useDOM();\n\n const [popperPlacement, setPopperPlacement] = React.useState<Placement | undefined>(undefined);\n\n const scrollBoxRef = React.useRef<HTMLDivElement>(null);\n const rootRef = useExternRef(getRef);\n const {\n fieldValue,\n selectedOptions = [],\n opened,\n setOpened,\n addOptionFromInput,\n filteredOptions,\n addOption,\n handleInputChange,\n clearInput,\n focusedOption,\n setFocusedOption,\n focusedOptionIndex,\n setFocusedOptionIndex,\n } = useChipsSelect(propsWithDefault);\n\n const showCreatable = Boolean(\n creatable && creatableText && !filteredOptions.length && fieldValue,\n );\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setOpened(true);\n setFocusedOptionIndex(null);\n onFocus!(e);\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n onBlur!(e);\n\n // Не добавляем значение, если его нужно выбрать строго из списка\n if (!e.defaultPrevented && !creatable) {\n e.preventDefault();\n }\n };\n\n const handleClickOutside = (e: MouseEvent) => {\n if (e.target !== rootRef.current && !rootRef.current?.contains(e.target as Node)) {\n setOpened(false);\n }\n };\n\n const chipsSelectOptions = React.useRef<HTMLElement[]>([]).current;\n\n const scrollToElement = (index: number, center = false) => {\n const dropdown = scrollBoxRef.current;\n const item = chipsSelectOptions[index];\n\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 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 const { length } = filteredOptions;\n\n if (index < 0) {\n index = length - 1;\n } else if (index >= length) {\n index = 0;\n }\n\n if (index === oldIndex) {\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 index = index + 1;\n } else if (type === FOCUS_ACTION_PREV) {\n index = index - 1;\n }\n\n focusOptionByIndex(index, focusedOptionIndex);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown!(e);\n\n if (e.key === 'ArrowUp' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_PREV);\n }\n }\n\n if (e.key === 'ArrowDown' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_NEXT);\n }\n }\n\n if (e.key === 'Enter' && !e.defaultPrevented && opened) {\n if (focusedOptionIndex != null) {\n const option = filteredOptions[focusedOptionIndex];\n\n if (option) {\n onChangeStart!(e, option);\n\n if (!e.defaultPrevented) {\n addOption(option);\n setFocusedOptionIndex(null);\n clearInput();\n closeAfterSelect && setOpened(false);\n e.preventDefault();\n }\n } else if (!creatable) {\n e.preventDefault();\n }\n } else if (!creatable) {\n e.preventDefault();\n }\n }\n\n if (['Escape', 'Tab'].includes(e.key) && !e.defaultPrevented && opened) {\n setOpened(false);\n }\n };\n\n React.useEffect(() => {\n if (focusedOptionIndex != null && filteredOptions[focusedOptionIndex]) {\n setFocusedOption(filteredOptions[focusedOptionIndex]);\n } else if (focusedOptionIndex === null || focusedOptionIndex === 0) {\n setFocusedOption(null);\n }\n }, [focusedOptionIndex, filteredOptions, setFocusedOption]);\n\n useGlobalEventListener(document, 'click', handleClickOutside);\n\n const renderChipWrapper = (renderChipProps: RenderChip<Option> | undefined) => {\n if (renderChipProps === undefined) {\n return null;\n }\n const onRemoveWrapper = (e: React.MouseEvent | undefined, value: ChipValue | undefined) => {\n e?.preventDefault();\n e?.stopPropagation();\n\n renderChipProps.onRemove?.(e, value);\n };\n\n return renderChip!({\n ...renderChipProps,\n onRemove: onRemoveWrapper,\n });\n };\n\n const isPopperDirectionTop = popperPlacement?.includes('top');\n\n const onPlacementChange = React.useCallback(\n (placement?: Placement) => {\n setPopperPlacement(placement);\n },\n [setPopperPlacement],\n );\n\n const onDropdownMouseLeave = React.useCallback(() => {\n setFocusedOptionIndex(null);\n }, [setFocusedOptionIndex]);\n\n const toggleOpened = () => {\n setOpened((prevOpened) => !prevOpened);\n };\n\n return (\n <>\n <FormField\n getRootRef={rootRef}\n style={style}\n className={classNames(\n styles['ChipsSelect'],\n opened &&\n (isPopperDirectionTop\n ? styles['ChipsSelect--pop-up']\n : styles['ChipsSelect--pop-down']),\n className,\n )}\n disabled={disabled}\n role=\"application\"\n aria-disabled={disabled}\n aria-readonly={restProps.readOnly}\n after={\n <IconButton\n className={styles['ChipsSelect__dropdown']}\n activeMode=\"\"\n hoverMode=\"\"\n // TODO [>=6]: add label customization\n aria-label={opened ? 'Скрыть' : 'Развернуть'}\n onClick={toggleOpened}\n >\n {icon ?? <DropdownIcon className={styles['ChipsSelect__icon']} opened={opened} />}\n </IconButton>\n }\n before={before}\n >\n <ChipsInputBase\n {...restProps}\n tabIndex={tabIndex}\n value={selectedOptions}\n inputValue={fieldValue}\n getNewOptionData={getNewOptionData}\n getOptionLabel={getOptionLabel}\n getOptionValue={getOptionValue}\n renderChip={renderChipWrapper}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n getRef={getRef}\n disabled={disabled}\n onInputChange={handleInputChange}\n />\n </FormField>\n {opened && (\n <CustomSelectDropdown\n targetRef={rootRef}\n placement={popupDirection}\n scrollBoxRef={scrollBoxRef}\n onPlacementChange={onPlacementChange}\n onMouseLeave={onDropdownMouseLeave}\n fetching={fetching}\n sameWidth={fixDropdownWidth}\n forcePortal={forceDropdownPortal}\n >\n {showCreatable && (\n <CustomSelectOption\n hovered={focusedOptionIndex === 0}\n onMouseDown={addOptionFromInput}\n onMouseEnter={() => setFocusedOptionIndex(0)}\n >\n {creatableText}\n </CustomSelectOption>\n )}\n {!filteredOptions?.length && !showCreatable && emptyText ? (\n <Footnote className={styles['ChipsSelect__empty']}>{emptyText}</Footnote>\n ) : (\n filteredOptions.map((option: Option, index: number) => {\n const label = getOptionLabel!(option);\n const hovered =\n focusedOption && getOptionValue!(option) === getOptionValue!(focusedOption);\n const selected = selectedOptions.find((selectedOption: Option) => {\n return getOptionValue!(selectedOption) === getOptionValue!(option);\n });\n const value = getOptionValue!(option);\n\n return (\n <React.Fragment key={`${typeof value}-${value}`}>\n {renderOption!({\n option,\n hovered: Boolean(hovered),\n children: label,\n selected: !!selected,\n getRootRef: (e) => {\n if (e) {\n return (chipsSelectOptions[index] = e);\n }\n return undefined;\n },\n onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => {\n onChangeStart?.(e, option);\n\n if (!e.defaultPrevented) {\n closeAfterSelect && setOpened(false);\n addOption(option);\n clearInput();\n }\n },\n onMouseEnter: () => setFocusedOptionIndex(index),\n })}\n </React.Fragment>\n );\n })\n )}\n </CustomSelectDropdown>\n )}\n </>\n );\n};\n"],"names":["React","classNames","noop","useChipsSelect","useExternRef","useGlobalEventListener","useDOM","defaultFilterFn","ChipsInputBase","chipsInputDefaultProps","CustomSelectDropdown","CustomSelectOption","DropdownIcon","FormField","IconButton","Footnote","FOCUS_ACTION_NEXT","FOCUS_ACTION_PREV","chipsSelectDefaultProps","emptyText","creatableText","onChangeStart","creatable","fetching","showSelected","closeAfterSelect","options","filterFn","renderOption","props","ChipsSelect","popperPlacement","filteredOptions","propsWithDefault","style","onFocus","onBlur","onKeyDown","className","getRef","getRootRef","disabled","placeholder","tabIndex","getOptionValue","getOptionLabel","getNewOptionData","renderChip","popupDirection","inputValue","before","icon","fixDropdownWidth","forceDropdownPortal","restProps","document","useState","undefined","setPopperPlacement","scrollBoxRef","useRef","rootRef","fieldValue","selectedOptions","opened","setOpened","addOptionFromInput","addOption","handleInputChange","clearInput","focusedOption","setFocusedOption","focusedOptionIndex","setFocusedOptionIndex","showCreatable","Boolean","length","handleFocus","e","handleBlur","defaultPrevented","preventDefault","handleClickOutside","target","current","contains","chipsSelectOptions","scrollToElement","index","center","dropdown","item","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","oldIndex","focusOption","nextIndex","type","handleKeyDown","key","option","includes","useEffect","renderChipWrapper","renderChipProps","onRemoveWrapper","value","stopPropagation","onRemove","isPopperDirectionTop","onPlacementChange","useCallback","placement","onDropdownMouseLeave","toggleOpened","prevOpened","role","aria-disabled","aria-readonly","readOnly","after","activeMode","hoverMode","aria-label","onClick","onInputChange","targetRef","onMouseLeave","sameWidth","forcePortal","hovered","onMouseDown","onMouseEnter","map","label","selected","find","selectedOption","Fragment","children"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useChipsSelect } from '../../hooks/useChipsSelect';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useGlobalEventListener } from '../../hooks/useGlobalEventListener';\nimport { useDOM } from '../../lib/dom';\nimport type { Placement } from '../../lib/floating';\nimport { defaultFilterFn } from '../../lib/select';\nimport { ChipOption, ChipValue, RenderChip } from '../Chip/Chip';\nimport { ChipsInputProps } from '../ChipsInput/ChipsInput';\nimport { ChipsInputBase, chipsInputDefaultProps } from '../ChipsInputBase/ChipsInputBase';\nimport { CustomSelectDropdown } from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport { FormField } from '../FormField/FormField';\nimport { IconButton } from '../IconButton/IconButton';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport styles from './ChipsSelect.module.css';\n\nexport interface ChipsSelectProps<Option extends ChipOption>\n extends Omit<ChipsInputProps<Option>, 'after'> {\n popupDirection?: 'top' | 'bottom';\n options?: Option[];\n filterFn?:\n | false\n | ((\n value?: string,\n option?: Option,\n getOptionLabel?: Pick<ChipsInputProps<Option>, 'getOptionLabel'>['getOptionLabel'],\n ) => boolean);\n /**\n * Возможность создавать чипы которых нет в списке (по enter или с помощью пункта в меню, см creatableText)\n */\n creatable?: boolean;\n /**\n * Отрисовка лоадера вместо списка опций в выпадающем списке\n */\n fetching?: boolean;\n renderOption?: (props: CustomSelectOptionProps) => React.ReactNode;\n /**\n * Показывать или скрывать уже выбранные опции\n */\n showSelected?: boolean;\n /**\n * Текст для пункта создающего чипы при клике, так же отвечает за то будет ли показан этот пункт (показывается после того как в списке не отсанется опций)\n */\n creatableText?: string;\n /**\n * Текст который показывается если список опций пуст\n */\n emptyText?: string;\n /**\n * Событие срабатывающее перед onChange\n */\n onChangeStart?: (e: React.MouseEvent | React.KeyboardEvent, option: Option) => void;\n /**\n * Закрытие выпадающего списка после выбора элемента\n */\n closeAfterSelect?: boolean;\n fixDropdownWidth?: boolean;\n forceDropdownPortal?: boolean;\n /**\n * Иконка раскрывающегося списка\n */\n icon?: React.ReactNode;\n /**\n * Добавляет значение в список на событие `onBlur` (использовать вместе с `creatable`)\n */\n addOnBlur?: boolean;\n}\n\ntype FocusActionType = 'next' | 'prev';\n\nconst FOCUS_ACTION_NEXT: FocusActionType = 'next';\nconst FOCUS_ACTION_PREV: FocusActionType = 'prev';\n\nconst chipsSelectDefaultProps: ChipsSelectProps<any> = {\n ...chipsInputDefaultProps,\n emptyText: 'Ничего не найдено',\n creatableText: 'Создать значение',\n onChangeStart: noop,\n creatable: false,\n fetching: false,\n showSelected: true,\n closeAfterSelect: true,\n options: [],\n filterFn: defaultFilterFn,\n renderOption(props) {\n return <CustomSelectOption {...props} />;\n },\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ChipsSelect\n */\nexport const ChipsSelect = <Option extends ChipOption>(props: ChipsSelectProps<Option>) => {\n const propsWithDefault = { ...chipsSelectDefaultProps, ...props };\n const {\n style,\n onFocus,\n onBlur,\n onKeyDown,\n className,\n fetching,\n renderOption,\n emptyText,\n getRef,\n getRootRef,\n disabled,\n placeholder,\n tabIndex,\n getOptionValue,\n getOptionLabel,\n showSelected,\n getNewOptionData,\n renderChip,\n popupDirection,\n creatable,\n filterFn,\n inputValue,\n creatableText,\n closeAfterSelect,\n onChangeStart,\n before,\n icon,\n options,\n fixDropdownWidth,\n forceDropdownPortal,\n ...restProps\n } = propsWithDefault;\n\n const { document } = useDOM();\n\n const [popperPlacement, setPopperPlacement] = React.useState<Placement | undefined>(undefined);\n\n const scrollBoxRef = React.useRef<HTMLDivElement>(null);\n const rootRef = useExternRef(getRef);\n const {\n fieldValue,\n selectedOptions = [],\n opened,\n setOpened,\n addOptionFromInput,\n filteredOptions,\n addOption,\n handleInputChange,\n clearInput,\n focusedOption,\n setFocusedOption,\n focusedOptionIndex,\n setFocusedOptionIndex,\n } = useChipsSelect(propsWithDefault);\n\n const showCreatable = Boolean(\n creatable && creatableText && !filteredOptions.length && fieldValue,\n );\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setOpened(true);\n setFocusedOptionIndex(null);\n onFocus!(e);\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n onBlur!(e);\n\n // Не добавляем значение, если его нужно выбрать строго из списка\n if (!e.defaultPrevented && !creatable) {\n e.preventDefault();\n }\n };\n\n const handleClickOutside = (e: MouseEvent) => {\n const isClickOutsideFormField = !rootRef.current?.contains(e.target as Node);\n const isClickOutsideDropdown = !scrollBoxRef.current?.contains(e.target as Node);\n\n if (isClickOutsideFormField && isClickOutsideDropdown) {\n setOpened(false);\n }\n };\n\n const chipsSelectOptions = React.useRef<HTMLElement[]>([]).current;\n\n const scrollToElement = (index: number, center = false) => {\n const dropdown = scrollBoxRef.current;\n const item = chipsSelectOptions[index];\n\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 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 const { length } = filteredOptions;\n\n if (index < 0) {\n index = length - 1;\n } else if (index >= length) {\n index = 0;\n }\n\n if (index === oldIndex) {\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 index = index + 1;\n } else if (type === FOCUS_ACTION_PREV) {\n index = index - 1;\n }\n\n focusOptionByIndex(index, focusedOptionIndex);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown!(e);\n\n if (e.key === 'ArrowUp' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_PREV);\n }\n }\n\n if (e.key === 'ArrowDown' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_NEXT);\n }\n }\n\n if (e.key === 'Enter' && !e.defaultPrevented && opened) {\n if (focusedOptionIndex != null) {\n const option = filteredOptions[focusedOptionIndex];\n\n if (option) {\n onChangeStart!(e, option);\n\n if (!e.defaultPrevented) {\n addOption(option);\n setFocusedOptionIndex(null);\n clearInput();\n closeAfterSelect && setOpened(false);\n e.preventDefault();\n }\n } else if (!creatable) {\n e.preventDefault();\n }\n } else if (!creatable) {\n e.preventDefault();\n }\n }\n\n if (['Escape', 'Tab'].includes(e.key) && !e.defaultPrevented && opened) {\n setOpened(false);\n }\n };\n\n React.useEffect(() => {\n if (focusedOptionIndex != null && filteredOptions[focusedOptionIndex]) {\n setFocusedOption(filteredOptions[focusedOptionIndex]);\n } else if (focusedOptionIndex === null || focusedOptionIndex === 0) {\n setFocusedOption(null);\n }\n }, [focusedOptionIndex, filteredOptions, setFocusedOption]);\n\n useGlobalEventListener(document, 'click', handleClickOutside);\n\n const renderChipWrapper = (renderChipProps: RenderChip<Option> | undefined) => {\n if (renderChipProps === undefined) {\n return null;\n }\n const onRemoveWrapper = (e: React.MouseEvent | undefined, value: ChipValue | undefined) => {\n e?.preventDefault();\n e?.stopPropagation();\n\n renderChipProps.onRemove?.(e, value);\n };\n\n return renderChip!({\n ...renderChipProps,\n onRemove: onRemoveWrapper,\n });\n };\n\n const isPopperDirectionTop = popperPlacement?.includes('top');\n\n const onPlacementChange = React.useCallback(\n (placement?: Placement) => {\n setPopperPlacement(placement);\n },\n [setPopperPlacement],\n );\n\n const onDropdownMouseLeave = React.useCallback(() => {\n setFocusedOptionIndex(null);\n }, [setFocusedOptionIndex]);\n\n const toggleOpened = () => {\n setOpened((prevOpened) => !prevOpened);\n };\n\n return (\n <>\n <FormField\n getRootRef={rootRef}\n style={style}\n className={classNames(\n styles['ChipsSelect'],\n opened &&\n (isPopperDirectionTop\n ? styles['ChipsSelect--pop-up']\n : styles['ChipsSelect--pop-down']),\n className,\n )}\n disabled={disabled}\n role=\"application\"\n aria-disabled={disabled}\n aria-readonly={restProps.readOnly}\n after={\n <IconButton\n className={styles['ChipsSelect__dropdown']}\n activeMode=\"\"\n hoverMode=\"\"\n // TODO [>=6]: add label customization\n aria-label={opened ? 'Скрыть' : 'Развернуть'}\n onClick={toggleOpened}\n >\n {icon ?? <DropdownIcon className={styles['ChipsSelect__icon']} opened={opened} />}\n </IconButton>\n }\n before={before}\n >\n <ChipsInputBase\n {...restProps}\n tabIndex={tabIndex}\n value={selectedOptions}\n inputValue={fieldValue}\n getNewOptionData={getNewOptionData}\n getOptionLabel={getOptionLabel}\n getOptionValue={getOptionValue}\n renderChip={renderChipWrapper}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n getRef={getRef}\n disabled={disabled}\n onInputChange={handleInputChange}\n />\n </FormField>\n {opened && (\n <CustomSelectDropdown\n targetRef={rootRef}\n placement={popupDirection}\n scrollBoxRef={scrollBoxRef}\n onPlacementChange={onPlacementChange}\n onMouseLeave={onDropdownMouseLeave}\n fetching={fetching}\n sameWidth={fixDropdownWidth}\n forcePortal={forceDropdownPortal}\n >\n {showCreatable && (\n <CustomSelectOption\n hovered={focusedOptionIndex === 0}\n onMouseDown={addOptionFromInput}\n onMouseEnter={() => setFocusedOptionIndex(0)}\n >\n {creatableText}\n </CustomSelectOption>\n )}\n {!filteredOptions?.length && !showCreatable && emptyText ? (\n <Footnote className={styles['ChipsSelect__empty']}>{emptyText}</Footnote>\n ) : (\n filteredOptions.map((option: Option, index: number) => {\n const label = getOptionLabel!(option);\n const hovered =\n focusedOption && getOptionValue!(option) === getOptionValue!(focusedOption);\n const selected = selectedOptions.find((selectedOption: Option) => {\n return getOptionValue!(selectedOption) === getOptionValue!(option);\n });\n const value = getOptionValue!(option);\n\n return (\n <React.Fragment key={`${typeof value}-${value}`}>\n {renderOption!({\n option,\n hovered: Boolean(hovered),\n children: label,\n selected: !!selected,\n getRootRef: (e) => {\n if (e) {\n return (chipsSelectOptions[index] = e);\n }\n return undefined;\n },\n onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => {\n onChangeStart?.(e, option);\n\n if (!e.defaultPrevented) {\n closeAfterSelect && setOpened(false);\n addOption(option);\n clearInput();\n }\n },\n onMouseEnter: () => setFocusedOptionIndex(index),\n })}\n </React.Fragment>\n );\n })\n )}\n </CustomSelectDropdown>\n )}\n </>\n );\n};\n"],"names":["React","classNames","noop","useChipsSelect","useExternRef","useGlobalEventListener","useDOM","defaultFilterFn","ChipsInputBase","chipsInputDefaultProps","CustomSelectDropdown","CustomSelectOption","DropdownIcon","FormField","IconButton","Footnote","FOCUS_ACTION_NEXT","FOCUS_ACTION_PREV","chipsSelectDefaultProps","emptyText","creatableText","onChangeStart","creatable","fetching","showSelected","closeAfterSelect","options","filterFn","renderOption","props","ChipsSelect","popperPlacement","filteredOptions","propsWithDefault","style","onFocus","onBlur","onKeyDown","className","getRef","getRootRef","disabled","placeholder","tabIndex","getOptionValue","getOptionLabel","getNewOptionData","renderChip","popupDirection","inputValue","before","icon","fixDropdownWidth","forceDropdownPortal","restProps","document","useState","undefined","setPopperPlacement","scrollBoxRef","useRef","rootRef","fieldValue","selectedOptions","opened","setOpened","addOptionFromInput","addOption","handleInputChange","clearInput","focusedOption","setFocusedOption","focusedOptionIndex","setFocusedOptionIndex","showCreatable","Boolean","length","handleFocus","e","handleBlur","defaultPrevented","preventDefault","handleClickOutside","isClickOutsideFormField","current","contains","target","isClickOutsideDropdown","chipsSelectOptions","scrollToElement","index","center","dropdown","item","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","oldIndex","focusOption","nextIndex","type","handleKeyDown","key","option","includes","useEffect","renderChipWrapper","renderChipProps","onRemoveWrapper","value","stopPropagation","onRemove","isPopperDirectionTop","onPlacementChange","useCallback","placement","onDropdownMouseLeave","toggleOpened","prevOpened","role","aria-disabled","aria-readonly","readOnly","after","activeMode","hoverMode","aria-label","onClick","onInputChange","targetRef","onMouseLeave","sameWidth","forcePortal","hovered","onMouseDown","onMouseEnter","map","label","selected","find","selectedOption","Fragment","children"],"mappings":";;;;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,IAAI,QAAQ,kBAAkB;AACnD,SAASC,cAAc,QAAQ,6BAA6B;AAC5D,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,sBAAsB,QAAQ,qCAAqC;AAC5E,SAASC,MAAM,QAAQ,gBAAgB;AAEvC,SAASC,eAAe,QAAQ,mBAAmB;AAGnD,SAASC,cAAc,EAAEC,sBAAsB,QAAQ,mCAAmC;AAC1F,SAASC,oBAAoB,QAAQ,+CAA+C;AACpF,SACEC,kBAAkB,QAEb,2CAA2C;AAClD,SAASC,YAAY,QAAQ,+BAA+B;AAC5D,SAASC,SAAS,QAAQ,yBAAyB;AACnD,SAASC,UAAU,QAAQ,2BAA2B;AACtD,SAASC,QAAQ,QAAQ,kCAAkC;AAyD3D,IAAMC,oBAAqC;AAC3C,IAAMC,oBAAqC;AAE3C,IAAMC,0BAAiD,wCAClDT;IACHU,WAAW;IACXC,eAAe;IACfC,eAAenB;IACfoB,WAAW;IACXC,UAAU;IACVC,cAAc;IACdC,kBAAkB;IAClBC,SAAS,EAAE;IACXC,UAAUpB;IACVqB,cAAAA,SAAAA,aAAaC,KAAK;QAChB,qBAAO,oBAAClB,oBAAuBkB;IACjC;;AAGF;;CAEC,GACD,OAAO,IAAMC,cAAc,SAA4BD;QA0NxBE,kBAsFnBC;IA/SV,IAAMC,mBAAmB,mBAAKf,yBAA4BW;IAC1D,IACEK,QA+BED,iBA/BFC,OACAC,UA8BEF,iBA9BFE,SACAC,SA6BEH,iBA7BFG,QACAC,YA4BEJ,iBA5BFI,WACAC,YA2BEL,iBA3BFK,WACAf,WA0BEU,iBA1BFV,UACAK,eAyBEK,iBAzBFL,cACAT,YAwBEc,iBAxBFd,WACAoB,SAuBEN,iBAvBFM,QACAC,aAsBEP,iBAtBFO,YACAC,WAqBER,iBArBFQ,UACAC,cAoBET,iBApBFS,aACAC,WAmBEV,iBAnBFU,UACAC,iBAkBEX,iBAlBFW,gBACAC,iBAiBEZ,iBAjBFY,gBACArB,eAgBES,iBAhBFT,cACAsB,mBAeEb,iBAfFa,kBACAC,aAcEd,iBAdFc,YACAC,iBAaEf,iBAbFe,gBACA1B,YAYEW,iBAZFX,WACAK,WAWEM,iBAXFN,UACAsB,aAUEhB,iBAVFgB,YACA7B,gBASEa,iBATFb,eACAK,mBAQEQ,iBARFR,kBACAJ,gBAOEY,iBAPFZ,eACA6B,SAMEjB,iBANFiB,QACAC,OAKElB,iBALFkB,MACAzB,UAIEO,iBAJFP,SACA0B,mBAGEnB,iBAHFmB,kBACAC,sBAEEpB,iBAFFoB,qBACGC,uCACDrB;QA/BFC;QACAC;QACAC;QACAC;QACAC;QACAf;QACAK;QACAT;QACAoB;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACArB;QACAsB;QACAC;QACAC;QACA1B;QACAK;QACAsB;QACA7B;QACAK;QACAJ;QACA6B;QACAC;QACAzB;QACA0B;QACAC;;IAIF,IAAM,AAAEE,WAAajD,SAAbiD;IAER,IAA8CvD,mCAAAA,MAAMwD,QAAQ,CAAwBC,gBAA7E1B,kBAAuC/B,oBAAtB0D,qBAAsB1D;IAE9C,IAAM2D,eAAe3D,MAAM4D,MAAM,CAAiB;IAClD,IAAMC,UAAUzD,aAAamC;IAC7B,IAcIpC,kBAAAA,eAAe8B,mBAbjB6B,aAaE3D,gBAbF2D,8CAaE3D,gBAZF4D,iBAAAA,+DAAkB,EAAE,oCACpBC,SAWE7D,gBAXF6D,QACAC,YAUE9D,gBAVF8D,WACAC,qBASE/D,gBATF+D,oBACAlC,kBAQE7B,gBARF6B,iBACAmC,YAOEhE,gBAPFgE,WACAC,oBAMEjE,gBANFiE,mBACAC,aAKElE,gBALFkE,YACAC,gBAIEnE,gBAJFmE,eACAC,mBAGEpE,gBAHFoE,kBACAC,qBAEErE,gBAFFqE,oBACAC,wBACEtE,gBADFsE;IAGF,IAAMC,gBAAgBC,QACpBrD,aAAaF,iBAAiB,CAACY,gBAAgB4C,MAAM,IAAId;IAG3D,IAAMe,cAAc,SAACC;QACnBb,UAAU;QACVQ,sBAAsB;QACtBtC,QAAS2C;IACX;IAEA,IAAMC,aAAa,SAACD;QAClB1C,OAAQ0C;QAER,iEAAiE;QACjE,IAAI,CAACA,EAAEE,gBAAgB,IAAI,CAAC1D,WAAW;YACrCwD,EAAEG,cAAc;QAClB;IACF;IAEA,IAAMC,qBAAqB,SAACJ;YACOjB,kBACDF;QADhC,IAAMwB,0BAA0B,GAACtB,mBAAAA,QAAQuB,OAAO,cAAfvB,uCAAAA,iBAAiBwB,QAAQ,CAACP,EAAEQ,MAAM;QACnE,IAAMC,yBAAyB,GAAC5B,wBAAAA,aAAayB,OAAO,cAApBzB,4CAAAA,sBAAsB0B,QAAQ,CAACP,EAAEQ,MAAM;QAEvE,IAAIH,2BAA2BI,wBAAwB;YACrDtB,UAAU;QACZ;IACF;IAEA,IAAMuB,qBAAqBxF,MAAM4D,MAAM,CAAgB,EAAE,EAAEwB,OAAO;IAElE,IAAMK,kBAAkB,SAACC;YAAeC,0EAAS;QAC/C,IAAMC,WAAWjC,aAAayB,OAAO;QACrC,IAAMS,OAAOL,kBAAkB,CAACE,MAAM;QAEtC,IAAI,CAACG,QAAQ,CAACD,UAAU;YACtB;QACF;QAEA,IAAME,iBAAiBF,SAASG,YAAY;QAC5C,IAAMC,YAAYJ,SAASI,SAAS;QACpC,IAAMC,UAAUJ,KAAKK,SAAS;QAC9B,IAAMC,aAAaN,KAAKE,YAAY;QAEpC,IAAIJ,QAAQ;YACVC,SAASI,SAAS,GAAGC,UAAUH,iBAAiB,IAAIK,aAAa;QACnE,OAAO,IAAIF,UAAUE,aAAaL,iBAAiBE,WAAW;YAC5DJ,SAASI,SAAS,GAAGC,UAAUH,iBAAiBK;QAClD,OAAO,IAAIF,UAAUD,WAAW;YAC9BJ,SAASI,SAAS,GAAGC;QACvB;IACF;IAEA,IAAMG,qBAAqB,SAACV,OAAeW;QACzC,IAAM,AAAEzB,SAAW5C,gBAAX4C;QAER,IAAIc,QAAQ,GAAG;YACbA,QAAQd,SAAS;QACnB,OAAO,IAAIc,SAASd,QAAQ;YAC1Bc,QAAQ;QACV;QAEA,IAAIA,UAAUW,UAAU;YACtB;QACF;QAEAZ,gBAAgBC;QAChBjB,sBAAsBiB;IACxB;IAEA,IAAMY,cAAc,SAACC,WAA0BC;QAC7C,IAAId,QAAQa,cAAc,OAAO,CAAC,IAAIA;QAEtC,IAAIC,SAASxF,mBAAmB;YAC9B0E,QAAQA,QAAQ;QAClB,OAAO,IAAIc,SAASvF,mBAAmB;YACrCyE,QAAQA,QAAQ;QAClB;QAEAU,mBAAmBV,OAAOlB;IAC5B;IAEA,IAAMiC,gBAAgB,SAAC3B;QACrBzC,UAAWyC;QAEX,IAAIA,EAAE4B,GAAG,KAAK,aAAa,CAAC5B,EAAEE,gBAAgB,EAAE;YAC9CF,EAAEG,cAAc;YAEhB,IAAI,CAACjB,QAAQ;gBACXC,UAAU;gBACVQ,sBAAsB;YACxB,OAAO;gBACL6B,YAAY9B,oBAAoBvD;YAClC;QACF;QAEA,IAAI6D,EAAE4B,GAAG,KAAK,eAAe,CAAC5B,EAAEE,gBAAgB,EAAE;YAChDF,EAAEG,cAAc;YAEhB,IAAI,CAACjB,QAAQ;gBACXC,UAAU;gBACVQ,sBAAsB;YACxB,OAAO;gBACL6B,YAAY9B,oBAAoBxD;YAClC;QACF;QAEA,IAAI8D,EAAE4B,GAAG,KAAK,WAAW,CAAC5B,EAAEE,gBAAgB,IAAIhB,QAAQ;YACtD,IAAIQ,sBAAsB,MAAM;gBAC9B,IAAMmC,SAAS3E,eAAe,CAACwC,mBAAmB;gBAElD,IAAImC,QAAQ;oBACVtF,cAAeyD,GAAG6B;oBAElB,IAAI,CAAC7B,EAAEE,gBAAgB,EAAE;wBACvBb,UAAUwC;wBACVlC,sBAAsB;wBACtBJ;wBACA5C,oBAAoBwC,UAAU;wBAC9Ba,EAAEG,cAAc;oBAClB;gBACF,OAAO,IAAI,CAAC3D,WAAW;oBACrBwD,EAAEG,cAAc;gBAClB;YACF,OAAO,IAAI,CAAC3D,WAAW;gBACrBwD,EAAEG,cAAc;YAClB;QACF;QAEA,IAAI;YAAC;YAAU;SAAM,CAAC2B,QAAQ,CAAC9B,EAAE4B,GAAG,KAAK,CAAC5B,EAAEE,gBAAgB,IAAIhB,QAAQ;YACtEC,UAAU;QACZ;IACF;IAEAjE,MAAM6G,SAAS,CAAC;QACd,IAAIrC,sBAAsB,QAAQxC,eAAe,CAACwC,mBAAmB,EAAE;YACrED,iBAAiBvC,eAAe,CAACwC,mBAAmB;QACtD,OAAO,IAAIA,uBAAuB,QAAQA,uBAAuB,GAAG;YAClED,iBAAiB;QACnB;IACF,GAAG;QAACC;QAAoBxC;QAAiBuC;KAAiB;IAE1DlE,uBAAuBkD,UAAU,SAAS2B;IAE1C,IAAM4B,oBAAoB,SAACC;QACzB,IAAIA,oBAAoBtD,WAAW;YACjC,OAAO;QACT;QACA,IAAMuD,kBAAkB,SAAClC,GAAiCmC;gBACxDnC,IACAA,KAEAiC,2BAAAA;aAHAjC,KAAAA,eAAAA,yBAAAA,GAAGG,cAAc;aACjBH,MAAAA,eAAAA,0BAAAA,IAAGoC,eAAe;aAElBH,4BAAAA,CAAAA,mBAAAA,iBAAgBI,QAAQ,cAAxBJ,gDAAAA,+BAAAA,kBAA2BjC,GAAGmC;QAChC;QAEA,OAAOlE,WAAY,wCACdgE;YACHI,UAAUH;;IAEd;IAEA,IAAMI,wBAAuBrF,mBAAAA,6BAAAA,uCAAAA,iBAAiB6E,QAAQ,CAAC;IAEvD,IAAMS,oBAAoBrH,MAAMsH,WAAW,CACzC,SAACC;QACC7D,mBAAmB6D;IACrB,GACA;QAAC7D;KAAmB;IAGtB,IAAM8D,uBAAuBxH,MAAMsH,WAAW,CAAC;QAC7C7C,sBAAsB;IACxB,GAAG;QAACA;KAAsB;IAE1B,IAAMgD,eAAe;QACnBxD,UAAU,SAACyD;mBAAe,CAACA;;IAC7B;IAEA,qBACE,wDACE,oBAAC7G;QACC2B,YAAYqB;QACZ3B,OAAOA;QACPI,WAAWrC,8BAET+D,UACGoD,CAAAA,8EAEiC,GACpC9E;QAEFG,UAAUA;QACVkF,MAAK;QACLC,iBAAenF;QACfoF,iBAAevE,UAAUwE,QAAQ;QACjCC,qBACE,oBAACjH;YACCwB,SAAS;YACT0F,YAAW;YACXC,WAAU;YACV,sCAAsC;YACtCC,cAAYlE,SAAS,WAAW;YAChCmE,SAASV;WAERtE,iBAAAA,kBAAAA,qBAAQ,oBAACvC;YAAa0B,SAAS;YAA+B0B,QAAQA;;QAG3Ed,QAAQA;qBAER,oBAAC1C,wDACK8C;QACJX,UAAUA;QACVsE,OAAOlD;QACPd,YAAYa;QACZhB,kBAAkBA;QAClBD,gBAAgBA;QAChBD,gBAAgBA;QAChBG,YAAY+D;QACZ3E,SAAS0C;QACTzC,QAAQ2C;QACR1C,WAAWoE;QACX/D,aAAaA;QACbH,QAAQA;QACRE,UAAUA;QACV2F,eAAehE;UAGlBJ,wBACC,oBAACtD;QACC2H,WAAWxE;QACX0D,WAAWvE;QACXW,cAAcA;QACd0D,mBAAmBA;QACnBiB,cAAcd;QACdjG,UAAUA;QACVgH,WAAWnF;QACXoF,aAAanF;OAEZqB,+BACC,oBAAC/D;QACC8H,SAASjE,uBAAuB;QAChCkE,aAAaxE;QACbyE,cAAc;mBAAMlE,sBAAsB;;OAEzCrD,gBAGJ,GAACY,mBAAAA,6BAAAA,uCAAAA,iBAAiB4C,MAAM,KAAI,CAACF,iBAAiBvD,0BAC7C,oBAACJ;QAASuB,SAAS;OAAiCnB,aAEpDa,gBAAgB4G,GAAG,CAAC,SAACjC,QAAgBjB;QACnC,IAAMmD,QAAQhG,eAAgB8D;QAC9B,IAAM8B,UACJnE,iBAAiB1B,eAAgB+D,YAAY/D,eAAgB0B;QAC/D,IAAMwE,WAAW/E,gBAAgBgF,IAAI,CAAC,SAACC;YACrC,OAAOpG,eAAgBoG,oBAAoBpG,eAAgB+D;QAC7D;QACA,IAAMM,QAAQrE,eAAgB+D;QAE9B,qBACE,oBAAC3G,MAAMiJ,QAAQ;YAACvC,KAAK,AAAC,GAAkBO,OAAhB,OAAOA,sCAAP,SAAOA,QAAM,KAAS,OAANA;WACrCrF,aAAc;YACb+E,QAAAA;YACA8B,SAAS9D,QAAQ8D;YACjBS,UAAUL;YACVC,UAAU,CAAC,CAACA;YACZtG,YAAY,SAACsC;gBACX,IAAIA,GAAG;oBACL,OAAQU,kBAAkB,CAACE,MAAM,GAAGZ;gBACtC;gBACA,OAAOrB;YACT;YACAiF,aAAa,SAAC5D;oBACZzD;iBAAAA,iBAAAA,2BAAAA,qCAAAA,eAAgByD,GAAG6B;gBAEnB,IAAI,CAAC7B,EAAEE,gBAAgB,EAAE;oBACvBvD,oBAAoBwC,UAAU;oBAC9BE,UAAUwC;oBACVtC;gBACF;YACF;YACAsE,cAAc;uBAAMlE,sBAAsBiB;;QAC5C;IAGN;AAMZ,EAAE"}
|
|
@@ -47,7 +47,6 @@ var warn = warnOnce("Group");
|
|
|
47
47
|
warn('При использовании роли "tabpanel" необходимо задать значение свойств "aria-controls" и "id"');
|
|
48
48
|
}
|
|
49
49
|
var tabIndex = isTabPanel && tabIndexProp === undefined ? 0 : tabIndexProp;
|
|
50
|
-
var separatorClassName = classNames("vkuiGroup__separator", separator === "show" && "vkuiGroup__separator--force");
|
|
51
50
|
return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("section", _object_spread_props(_object_spread({}, restProps), {
|
|
52
51
|
tabIndex: tabIndex,
|
|
53
52
|
ref: getRootRef,
|
|
@@ -62,10 +61,10 @@ var warn = warnOnce("Group");
|
|
|
62
61
|
}), header, children, hasReactNode(description) && /*#__PURE__*/ React.createElement(Footnote, {
|
|
63
62
|
className: "vkuiGroup__description"
|
|
64
63
|
}, description)), separator !== "hide" && /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Spacing, {
|
|
65
|
-
className: classNames(
|
|
64
|
+
className: classNames("vkuiGroup__separator", "vkuiGroup__separator--spacing"),
|
|
66
65
|
size: 16
|
|
67
66
|
}), /*#__PURE__*/ React.createElement(Separator, {
|
|
68
|
-
className: classNames(
|
|
67
|
+
className: classNames("vkuiGroup__separator", "vkuiGroup__separator--separator", separator === "show" && "vkuiGroup__separator--force")
|
|
69
68
|
})));
|
|
70
69
|
};
|
|
71
70
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Group/Group.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { SizeType } from '../../lib/adaptivity';\nimport { Platform } from '../../lib/platform';\nimport { warnOnce } from '../../lib/warnOnce';\nimport { HasChildren, HasRootRef } from '../../types';\nimport { ModalRootContext } from '../ModalRoot/ModalRootContext';\nimport { Separator } from '../Separator/Separator';\nimport { Spacing } from '../Spacing/Spacing';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport styles from './Group.module.css';\n\nconst sizeXClassNames = {\n none: classNames(styles['Group--sizeX-none'], 'vkuiInternalGroup--sizeX-none'),\n [SizeType.COMPACT]: styles['Group--sizeX-compact'],\n};\n\nexport interface GroupProps\n extends HasRootRef<HTMLElement>,\n React.HTMLAttributes<HTMLElement>,\n HasChildren {\n header?: React.ReactNode;\n description?: React.ReactNode;\n /**\n `show` - разделитель всегда показывается,\n `hide` - разделитель всегда спрятан,\n `auto` - разделитель рисуется автоматически между соседними группами.\n */\n separator?: 'show' | 'hide' | 'auto';\n /**\n * Режим отображения. Если установлен `card`, выглядит как карточка c\n * обводкой и внешними отступами. Если `plain` — без отступов и обводки.\n * По умолчанию режим отображения зависит от `sizeX` (`mode=card` при `sizeX=REGULAR` и `mode=plain` при `sizeX=COMPACT`)\n * В модальных окнах по умолчанию `plain`.\n */\n mode?: 'plain' | 'card';\n /**\n * Отвечает за отступы вокруг контента в режиме `card`.\n */\n padding?: 's' | 'm';\n}\n\nconst warn = warnOnce('Group');\n/**\n * @see https://vkcom.github.io/VKUI/#/Group\n */\nexport const Group = ({\n header,\n description,\n children,\n separator = 'auto',\n getRootRef,\n mode: modeProps,\n padding = 'm',\n className,\n tabIndex: tabIndexProp,\n ...restProps\n}: GroupProps) => {\n const { isInsideModal } = React.useContext(ModalRootContext);\n const platform = usePlatform();\n const { sizeX = 'none' } = useAdaptivity();\n\n let mode: GroupProps['mode'] | 'none' = modeProps;\n\n if (!modeProps) {\n // Подробнее в \"none\" можно прочитать в ADAPTIVITY_GUIDE.md\n mode = isInsideModal ? 'plain' : 'none';\n }\n\n if (mode === 'none' && sizeX !== 'none') {\n mode = sizeX === SizeType.REGULAR ? 'card' : 'plain';\n }\n\n const isTabPanel = restProps.role === 'tabpanel';\n\n if (\n process.env.NODE_ENV === 'development' &&\n isTabPanel &&\n (!restProps['aria-controls'] || !restProps['id'])\n ) {\n warn(\n 'При использовании роли \"tabpanel\" необходимо задать значение свойств \"aria-controls\" и \"id\"',\n );\n }\n\n const tabIndex = isTabPanel && tabIndexProp === undefined ? 0 : tabIndexProp;\n\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Group/Group.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { SizeType } from '../../lib/adaptivity';\nimport { Platform } from '../../lib/platform';\nimport { warnOnce } from '../../lib/warnOnce';\nimport { HasChildren, HasRootRef } from '../../types';\nimport { ModalRootContext } from '../ModalRoot/ModalRootContext';\nimport { Separator } from '../Separator/Separator';\nimport { Spacing } from '../Spacing/Spacing';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport styles from './Group.module.css';\n\nconst sizeXClassNames = {\n none: classNames(styles['Group--sizeX-none'], 'vkuiInternalGroup--sizeX-none'),\n [SizeType.COMPACT]: styles['Group--sizeX-compact'],\n};\n\nexport interface GroupProps\n extends HasRootRef<HTMLElement>,\n React.HTMLAttributes<HTMLElement>,\n HasChildren {\n header?: React.ReactNode;\n description?: React.ReactNode;\n /**\n `show` - разделитель всегда показывается,\n `hide` - разделитель всегда спрятан,\n `auto` - разделитель рисуется автоматически между соседними группами.\n */\n separator?: 'show' | 'hide' | 'auto';\n /**\n * Режим отображения. Если установлен `card`, выглядит как карточка c\n * обводкой и внешними отступами. Если `plain` — без отступов и обводки.\n * По умолчанию режим отображения зависит от `sizeX` (`mode=card` при `sizeX=REGULAR` и `mode=plain` при `sizeX=COMPACT`)\n * В модальных окнах по умолчанию `plain`.\n */\n mode?: 'plain' | 'card';\n /**\n * Отвечает за отступы вокруг контента в режиме `card`.\n */\n padding?: 's' | 'm';\n}\n\nconst warn = warnOnce('Group');\n/**\n * @see https://vkcom.github.io/VKUI/#/Group\n */\nexport const Group = ({\n header,\n description,\n children,\n separator = 'auto',\n getRootRef,\n mode: modeProps,\n padding = 'm',\n className,\n tabIndex: tabIndexProp,\n ...restProps\n}: GroupProps) => {\n const { isInsideModal } = React.useContext(ModalRootContext);\n const platform = usePlatform();\n const { sizeX = 'none' } = useAdaptivity();\n\n let mode: GroupProps['mode'] | 'none' = modeProps;\n\n if (!modeProps) {\n // Подробнее в \"none\" можно прочитать в ADAPTIVITY_GUIDE.md\n mode = isInsideModal ? 'plain' : 'none';\n }\n\n if (mode === 'none' && sizeX !== 'none') {\n mode = sizeX === SizeType.REGULAR ? 'card' : 'plain';\n }\n\n const isTabPanel = restProps.role === 'tabpanel';\n\n if (\n process.env.NODE_ENV === 'development' &&\n isTabPanel &&\n (!restProps['aria-controls'] || !restProps['id'])\n ) {\n warn(\n 'При использовании роли \"tabpanel\" необходимо задать значение свойств \"aria-controls\" и \"id\"',\n );\n }\n\n const tabIndex = isTabPanel && tabIndexProp === undefined ? 0 : tabIndexProp;\n\n return (\n <>\n <section\n {...restProps}\n tabIndex={tabIndex}\n ref={getRootRef}\n className={classNames(\n 'vkuiInternalGroup',\n styles['Group'],\n isInsideModal && styles['Group--inside-modal'],\n platform === Platform.IOS && styles['Group--ios'],\n sizeX !== SizeType.REGULAR && sizeXClassNames[sizeX],\n mode &&\n {\n none: classNames(styles['Group--mode-none'], 'vkuiInternalGroup--mode-none'),\n plain: classNames(styles['Group--mode-plain'], 'vkuiInternalGroup--mode-plain'),\n card: classNames(styles['Group--mode-card'], 'vkuiInternalGroup--mode-card'),\n }[mode],\n {\n s: styles['Group--padding-s'],\n m: styles['Group--padding-m'],\n }[padding],\n className,\n )}\n >\n {header}\n {children}\n {hasReactNode(description) && (\n <Footnote className={styles['Group__description']}>{description}</Footnote>\n )}\n </section>\n\n {separator !== 'hide' && (\n <React.Fragment>\n <Spacing\n className={classNames(styles['Group__separator'], styles['Group__separator--spacing'])}\n size={16}\n />\n <Separator\n className={classNames(\n styles['Group__separator'],\n styles['Group__separator--separator'],\n separator === 'show' && styles['Group__separator--force'],\n )}\n />\n </React.Fragment>\n )}\n </>\n );\n};\n"],"names":["React","classNames","hasReactNode","useAdaptivity","usePlatform","SizeType","Platform","warnOnce","ModalRootContext","Separator","Spacing","Footnote","sizeXClassNames","none","COMPACT","warn","Group","header","description","children","separator","getRootRef","mode","modeProps","padding","className","tabIndex","tabIndexProp","restProps","isInsideModal","useContext","platform","sizeX","REGULAR","isTabPanel","role","process","env","NODE_ENV","undefined","section","ref","IOS","plain","card","s","m","Fragment","size"],"mappings":";;;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,YAAY,QAAQ,kBAAkB;AAC3D,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SAASC,QAAQ,QAAQ,uBAAuB;AAChD,SAASC,QAAQ,QAAQ,qBAAqB;AAC9C,SAASC,QAAQ,QAAQ,qBAAqB;AAE9C,SAASC,gBAAgB,QAAQ,gCAAgC;AACjE,SAASC,SAAS,QAAQ,yBAAyB;AACnD,SAASC,OAAO,QAAQ,qBAAqB;AAC7C,SAASC,QAAQ,QAAQ,kCAAkC;AAG3D,IAAMC;IACJC,MAAMZ,oCAAwC;GAC7CI,SAASS,OAAO;AA4BnB,IAAMC,OAAOR,SAAS;AACtB;;CAEC,GACD,OAAO,IAAMS,QAAQ;QACnBC,gBAAAA,QACAC,qBAAAA,aACAC,kBAAAA,oCACAC,WAAAA,0CAAY,2BACZC,oBAAAA,YACAC,AAAMC,mBAAND,8BACAE,SAAAA,sCAAU,sBACVC,mBAAAA,WACAC,AAAUC,sBAAVD,UACGE;QATHX;QACAC;QACAC;QACAC;QACAC;QACAC;QACAE;QACAC;QACAC;;IAGA,IAAM,AAAEG,gBAAkB7B,MAAM8B,UAAU,CAACtB,kBAAnCqB;IACR,IAAME,WAAW3B;IACjB,IAA2BD,iBAAAA,wCAAAA,eAAnB6B,OAAAA,0CAAQ;IAEhB,IAAIV,OAAoCC;IAExC,IAAI,CAACA,WAAW;QACd,2DAA2D;QAC3DD,OAAOO,gBAAgB,UAAU;IACnC;IAEA,IAAIP,SAAS,UAAUU,UAAU,QAAQ;QACvCV,OAAOU,UAAU3B,SAAS4B,OAAO,GAAG,SAAS;IAC/C;IAEA,IAAMC,aAAaN,UAAUO,IAAI,KAAK;IAEtC,IACEC,QAAQC,GAAG,CAACC,QAAQ,KAAK,iBACzBJ,cACC,CAAA,CAACN,SAAS,CAAC,gBAAgB,IAAI,CAACA,SAAS,CAAC,KAAK,AAAD,GAC/C;QACAb,KACE;IAEJ;IAEA,IAAMW,WAAWQ,cAAcP,iBAAiBY,YAAY,IAAIZ;IAEhE,qBACE,wDACE,oBAACa,mDACKZ;QACJF,UAAUA;QACVe,KAAKpB;QACLI,WAAWxB,WACT,kCAEA4B,4CACAE,aAAazB,SAASoC,GAAG,sBACzBV,UAAU3B,SAAS4B,OAAO,IAAIrB,eAAe,CAACoB,MAAM,EACpDV,QACE,CAAA;YACET,MAAMZ,mCAAuC;YAC7C0C,OAAO1C,oCAAwC;YAC/C2C,MAAM3C,mCAAuC;QAC/C,CAAA,CAAC,CAACqB,KAAK,EACT;YACEuB,CAAC;YACDC,CAAC;QACH,CAAC,CAACtB,QAAQ,EACVC;QAGDR,QACAE,UACAjB,aAAagB,8BACZ,oBAACP;QAASc,SAAS;OAAiCP,eAIvDE,cAAc,wBACb,oBAACpB,MAAM+C,QAAQ,sBACb,oBAACrC;QACCe,WAAWxB;QACX+C,MAAM;sBAER,oBAACvC;QACCgB,WAAWxB,sEAGTmB,cAAc;;AAO5B,EAAE"}
|
|
@@ -131,7 +131,7 @@ function doScroll(param) {
|
|
|
131
131
|
scrollTo,
|
|
132
132
|
scrollerRef
|
|
133
133
|
]);
|
|
134
|
-
var
|
|
134
|
+
var calculateArrowsVisibility = React.useCallback(function() {
|
|
135
135
|
if (showArrows && hasPointer && scrollerRef.current && !isCustomScrollingRef.current) {
|
|
136
136
|
var scrollElement = scrollerRef.current;
|
|
137
137
|
setCanScrollLeft(scrollElement.scrollLeft > 0);
|
|
@@ -142,19 +142,20 @@ function doScroll(param) {
|
|
|
142
142
|
scrollerRef,
|
|
143
143
|
showArrows
|
|
144
144
|
]);
|
|
145
|
-
var scrollEvent = useEventListener("scroll",
|
|
146
|
-
React.useEffect(function() {
|
|
147
|
-
if (scrollerRef.current) {
|
|
148
|
-
|
|
145
|
+
var scrollEvent = useEventListener("scroll", calculateArrowsVisibility);
|
|
146
|
+
React.useEffect(function addScrollerRefToScrollEvent() {
|
|
147
|
+
if (!scrollerRef.current) {
|
|
148
|
+
return noop;
|
|
149
149
|
}
|
|
150
|
+
scrollEvent.add(scrollerRef.current);
|
|
151
|
+
return scrollEvent.remove;
|
|
150
152
|
}, [
|
|
151
153
|
scrollEvent,
|
|
152
154
|
scrollerRef
|
|
153
155
|
]);
|
|
154
|
-
React.useEffect(
|
|
155
|
-
|
|
156
|
-
children
|
|
157
|
-
onscroll
|
|
156
|
+
React.useEffect(calculateArrowsVisibility, [
|
|
157
|
+
calculateArrowsVisibility,
|
|
158
|
+
children
|
|
158
159
|
]);
|
|
159
160
|
/**
|
|
160
161
|
* Прокрутка с помощью любого колеса мыши
|
|
@@ -168,7 +169,7 @@ function doScroll(param) {
|
|
|
168
169
|
scrollerRef
|
|
169
170
|
]);
|
|
170
171
|
var wheelEvent = useEventListener("wheel", onwheel);
|
|
171
|
-
React.useEffect(function() {
|
|
172
|
+
React.useEffect(function addScrollerRefToWheelEvent() {
|
|
172
173
|
if (!scrollerRef.current || !scrollOnAnyWheel) {
|
|
173
174
|
return noop;
|
|
174
175
|
}
|
|
@@ -180,7 +181,8 @@ function doScroll(param) {
|
|
|
180
181
|
scrollOnAnyWheel
|
|
181
182
|
]);
|
|
182
183
|
return /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({}, restProps), {
|
|
183
|
-
className: classNames("vkuiHorizontalScroll", "vkuiInternalHorizontalScroll", showArrows === "always" && "vkuiHorizontalScroll--withConstArrows", className)
|
|
184
|
+
className: classNames("vkuiHorizontalScroll", "vkuiInternalHorizontalScroll", showArrows === "always" && "vkuiHorizontalScroll--withConstArrows", className),
|
|
185
|
+
onMouseEnter: calculateArrowsVisibility
|
|
184
186
|
}), showArrows && (hasPointer || hasPointer === undefined) && canScrollLeft && /*#__PURE__*/ React.createElement(ScrollArrow, {
|
|
185
187
|
size: arrowSize,
|
|
186
188
|
offsetY: arrowOffsetY,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { easeInOutSine } from '../../lib/fx';\nimport { HasRef } from '../../types';\nimport { ScrollArrow } from '../ScrollArrow/ScrollArrow';\nimport styles from './HorizontalScroll.module.css';\n\ninterface ScrollContext {\n scrollElement: HTMLElement | null;\n scrollAnimationDuration: number;\n animationQueue: VoidFunction[];\n getScrollPosition: (currentPosition: number) => number;\n onScrollToRightBorder: VoidFunction;\n onScrollEnd: VoidFunction;\n onScrollStart: VoidFunction;\n /**\n * Начальная ширина прокрутки.\n * В некоторых случаях может отличаться от текущей ширины прокрутки из-за transforms: translate\n */\n initialScrollWidth: number;\n}\n\nexport type ScrollPositionHandler = (currentPosition: number) => number;\n\nexport interface HorizontalScrollProps\n extends React.HTMLAttributes<HTMLDivElement>,\n HasRef<HTMLDivElement> {\n /**\n * Функция для расчета величины прокрутки при клике на левую стрелку.\n */\n getScrollToLeft?: ScrollPositionHandler;\n /**\n * Функция для расчета величины прокрутки при клике на правую стрелку.\n */\n getScrollToRight?: ScrollPositionHandler;\n arrowSize?: 'm' | 'l';\n /**\n * Смещает иконки кнопок навигации по вертикали.\n */\n arrowOffsetY?: number | string;\n showArrows?: boolean | 'always';\n scrollAnimationDuration?: number;\n /**\n * Добавляет возможность прокручивать контент на любое колесо мыши.\n * По умолчанию прокручивается как любой горизонтальный контент через shift.\n */\n scrollOnAnyWheel?: boolean;\n}\n\n/**\n * timing method\n */\nfunction now() {\n return performance && performance.now ? performance.now() : Date.now();\n}\n\n/**\n * Округляем el.scrollLeft\n * https://github.com/VKCOM/VKUI/pull/2445\n */\nconst roundUpElementScrollLeft = (el: HTMLElement) => Math.ceil(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 onScrollToRightBorder,\n onScrollEnd,\n onScrollStart,\n initialScrollWidth,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n}: ScrollContext) {\n if (!scrollElement || !getScrollPosition) {\n return;\n }\n\n /**\n * максимальное значение сдвига влево\n */\n const maxLeft = initialScrollWidth - scrollElement.offsetWidth;\n\n let startLeft = roundUpElementScrollLeft(scrollElement);\n let endLeft = getScrollPosition(startLeft);\n\n onScrollStart();\n\n if (endLeft >= maxLeft) {\n onScrollToRightBorder();\n endLeft = maxLeft;\n }\n\n const startTime = now();\n\n (function scroll() {\n if (!scrollElement) {\n onScrollEnd();\n return;\n }\n\n const time = now();\n const elapsed = Math.min((time - startTime) / scrollAnimationDuration, 1);\n\n const value = easeInOutSine(elapsed);\n\n const currentLeft = startLeft + (endLeft - startLeft) * value;\n scrollElement.scrollLeft = Math.ceil(currentLeft);\n\n if (roundUpElementScrollLeft(scrollElement) !== Math.max(0, endLeft) && 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://vkcom.github.io/VKUI/#/HorizontalScroll\n */\nexport const HorizontalScroll = ({\n children,\n getScrollToLeft,\n getScrollToRight,\n showArrows = true,\n arrowSize = 'l',\n arrowOffsetY,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n getRef,\n className,\n scrollOnAnyWheel = false,\n ...restProps\n}: HorizontalScrollProps) => {\n const [canScrollLeft, setCanScrollLeft] = React.useState(false);\n const [canScrollRight, setCanScrollRight] = React.useState(false);\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 onScrollToRightBorder: () => setCanScrollRight(false),\n onScrollEnd: () => (isCustomScrollingRef.current = false),\n onScrollStart: () => (isCustomScrollingRef.current = true),\n initialScrollWidth: scrollElement?.firstElementChild?.scrollWidth || 0,\n scrollAnimationDuration,\n }),\n );\n if (animationQueue.current.length === 1) {\n animationQueue.current[0]();\n }\n },\n [scrollAnimationDuration, scrollerRef],\n );\n\n const scrollToLeft = React.useCallback(() => {\n const getScrollPosition =\n getScrollToLeft ?? ((i: number) => i - scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToLeft, scrollTo, scrollerRef]);\n\n const scrollToRight = React.useCallback(() => {\n const getScrollPosition =\n getScrollToRight ?? ((i: number) => i + scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToRight, scrollTo, scrollerRef]);\n\n const onscroll = React.useCallback(() => {\n if (showArrows && hasPointer && scrollerRef.current && !isCustomScrollingRef.current) {\n const scrollElement = scrollerRef.current;\n\n setCanScrollLeft(scrollElement.scrollLeft > 0);\n setCanScrollRight(\n roundUpElementScrollLeft(scrollElement) + scrollElement.offsetWidth <\n scrollElement.scrollWidth,\n );\n }\n }, [hasPointer, scrollerRef, showArrows]);\n\n const scrollEvent = useEventListener('scroll', onscroll);\n React.useEffect(() => {\n if (scrollerRef.current) {\n scrollEvent.add(scrollerRef.current);\n }\n }, [scrollEvent, scrollerRef]);\n React.useEffect(onscroll, [scrollerRef, children, onscroll]);\n\n /**\n * Прокрутка с помощью любого колеса мыши\n */\n const onwheel = React.useCallback(\n (e: WheelEvent) => {\n scrollerRef.current!.scrollBy({ left: e.deltaX + e.deltaY, behavior: 'auto' });\n e.preventDefault();\n },\n [scrollerRef],\n );\n\n const wheelEvent = useEventListener('wheel', onwheel);\n React.useEffect(() => {\n if (!scrollerRef.current || !scrollOnAnyWheel) {\n return noop;\n }\n\n wheelEvent.add(scrollerRef.current);\n\n return wheelEvent.remove;\n }, [wheelEvent, scrollerRef, scrollOnAnyWheel]);\n\n return (\n <div\n {...restProps}\n className={classNames(\n styles['HorizontalScroll'],\n 'vkuiInternalHorizontalScroll',\n showArrows === 'always' && styles['HorizontalScroll--withConstArrows'],\n className,\n )}\n >\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollLeft && (\n <ScrollArrow\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"left\"\n className={classNames(\n styles['HorizontalScroll__arrow'],\n styles['HorizontalScroll__arrowLeft'],\n )}\n onClick={scrollToLeft}\n />\n )}\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollRight && (\n <ScrollArrow\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"right\"\n className={classNames(\n styles['HorizontalScroll__arrow'],\n styles['HorizontalScroll__arrowRight'],\n )}\n onClick={scrollToRight}\n />\n )}\n <div className={styles['HorizontalScroll__in']} ref={scrollerRef}>\n <div className={styles['HorizontalScroll__in-wrapper']}>{children}</div>\n </div>\n </div>\n );\n};\n"],"names":["React","classNames","noop","useAdaptivityHasPointer","useEventListener","useExternRef","easeInOutSine","ScrollArrow","now","performance","Date","roundUpElementScrollLeft","el","Math","ceil","scrollLeft","SCROLL_ONE_FRAME_TIME","doScroll","scrollElement","getScrollPosition","animationQueue","onScrollToRightBorder","onScrollEnd","onScrollStart","initialScrollWidth","scrollAnimationDuration","maxLeft","offsetWidth","startLeft","endLeft","startTime","scroll","time","elapsed","min","value","currentLeft","max","requestAnimationFrame","shift","length","HorizontalScroll","children","getScrollToLeft","getScrollToRight","showArrows","arrowSize","arrowOffsetY","getRef","className","scrollOnAnyWheel","restProps","useState","canScrollLeft","setCanScrollLeft","canScrollRight","setCanScrollRight","isCustomScrollingRef","useRef","scrollerRef","hasPointer","scrollTo","useCallback","current","push","firstElementChild","scrollWidth","scrollToLeft","i","scrollToRight","onscroll","scrollEvent","useEffect","add","onwheel","e","scrollBy","left","deltaX","deltaY","behavior","preventDefault","wheelEvent","remove","div","undefined","size","offsetY","direction","onClick","ref"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { easeInOutSine } from '../../lib/fx';\nimport { HasRef } from '../../types';\nimport { ScrollArrow } from '../ScrollArrow/ScrollArrow';\nimport styles from './HorizontalScroll.module.css';\n\ninterface ScrollContext {\n scrollElement: HTMLElement | null;\n scrollAnimationDuration: number;\n animationQueue: VoidFunction[];\n getScrollPosition: (currentPosition: number) => number;\n onScrollToRightBorder: VoidFunction;\n onScrollEnd: VoidFunction;\n onScrollStart: VoidFunction;\n /**\n * Начальная ширина прокрутки.\n * В некоторых случаях может отличаться от текущей ширины прокрутки из-за transforms: translate\n */\n initialScrollWidth: number;\n}\n\nexport type ScrollPositionHandler = (currentPosition: number) => number;\n\nexport interface HorizontalScrollProps\n extends React.HTMLAttributes<HTMLDivElement>,\n HasRef<HTMLDivElement> {\n /**\n * Функция для расчета величины прокрутки при клике на левую стрелку.\n */\n getScrollToLeft?: ScrollPositionHandler;\n /**\n * Функция для расчета величины прокрутки при клике на правую стрелку.\n */\n getScrollToRight?: ScrollPositionHandler;\n arrowSize?: 'm' | 'l';\n /**\n * Смещает иконки кнопок навигации по вертикали.\n */\n arrowOffsetY?: number | string;\n showArrows?: boolean | 'always';\n scrollAnimationDuration?: number;\n /**\n * Добавляет возможность прокручивать контент на любое колесо мыши.\n * По умолчанию прокручивается как любой горизонтальный контент через shift.\n */\n scrollOnAnyWheel?: boolean;\n}\n\n/**\n * timing method\n */\nfunction now() {\n return performance && performance.now ? performance.now() : Date.now();\n}\n\n/**\n * Округляем el.scrollLeft\n * https://github.com/VKCOM/VKUI/pull/2445\n */\nconst roundUpElementScrollLeft = (el: HTMLElement) => Math.ceil(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 onScrollToRightBorder,\n onScrollEnd,\n onScrollStart,\n initialScrollWidth,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n}: ScrollContext) {\n if (!scrollElement || !getScrollPosition) {\n return;\n }\n\n /**\n * максимальное значение сдвига влево\n */\n const maxLeft = initialScrollWidth - scrollElement.offsetWidth;\n\n let startLeft = roundUpElementScrollLeft(scrollElement);\n let endLeft = getScrollPosition(startLeft);\n\n onScrollStart();\n\n if (endLeft >= maxLeft) {\n onScrollToRightBorder();\n endLeft = maxLeft;\n }\n\n const startTime = now();\n\n (function scroll() {\n if (!scrollElement) {\n onScrollEnd();\n return;\n }\n\n const time = now();\n const elapsed = Math.min((time - startTime) / scrollAnimationDuration, 1);\n\n const value = easeInOutSine(elapsed);\n\n const currentLeft = startLeft + (endLeft - startLeft) * value;\n scrollElement.scrollLeft = Math.ceil(currentLeft);\n\n if (roundUpElementScrollLeft(scrollElement) !== Math.max(0, endLeft) && 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://vkcom.github.io/VKUI/#/HorizontalScroll\n */\nexport const HorizontalScroll = ({\n children,\n getScrollToLeft,\n getScrollToRight,\n showArrows = true,\n arrowSize = 'l',\n arrowOffsetY,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n getRef,\n className,\n scrollOnAnyWheel = false,\n ...restProps\n}: HorizontalScrollProps) => {\n const [canScrollLeft, setCanScrollLeft] = React.useState(false);\n const [canScrollRight, setCanScrollRight] = React.useState(false);\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 onScrollToRightBorder: () => setCanScrollRight(false),\n onScrollEnd: () => (isCustomScrollingRef.current = false),\n onScrollStart: () => (isCustomScrollingRef.current = true),\n initialScrollWidth: scrollElement?.firstElementChild?.scrollWidth || 0,\n scrollAnimationDuration,\n }),\n );\n if (animationQueue.current.length === 1) {\n animationQueue.current[0]();\n }\n },\n [scrollAnimationDuration, scrollerRef],\n );\n\n const scrollToLeft = React.useCallback(() => {\n const getScrollPosition =\n getScrollToLeft ?? ((i: number) => i - scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToLeft, scrollTo, scrollerRef]);\n\n const scrollToRight = 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\n setCanScrollLeft(scrollElement.scrollLeft > 0);\n setCanScrollRight(\n roundUpElementScrollLeft(scrollElement) + scrollElement.offsetWidth <\n scrollElement.scrollWidth,\n );\n }\n }, [hasPointer, scrollerRef, showArrows]);\n\n const scrollEvent = useEventListener('scroll', calculateArrowsVisibility);\n React.useEffect(\n function addScrollerRefToScrollEvent() {\n if (!scrollerRef.current) {\n return noop;\n }\n\n scrollEvent.add(scrollerRef.current);\n return scrollEvent.remove;\n },\n [scrollEvent, scrollerRef],\n );\n\n React.useEffect(calculateArrowsVisibility, [calculateArrowsVisibility, children]);\n\n /**\n * Прокрутка с помощью любого колеса мыши\n */\n const onwheel = React.useCallback(\n (e: WheelEvent) => {\n scrollerRef.current!.scrollBy({ left: e.deltaX + e.deltaY, behavior: 'auto' });\n e.preventDefault();\n },\n [scrollerRef],\n );\n\n const wheelEvent = useEventListener('wheel', onwheel);\n React.useEffect(\n function addScrollerRefToWheelEvent() {\n if (!scrollerRef.current || !scrollOnAnyWheel) {\n return noop;\n }\n\n wheelEvent.add(scrollerRef.current);\n\n return wheelEvent.remove;\n },\n [wheelEvent, scrollerRef, scrollOnAnyWheel],\n );\n\n return (\n <div\n {...restProps}\n className={classNames(\n styles['HorizontalScroll'],\n 'vkuiInternalHorizontalScroll',\n showArrows === 'always' && styles['HorizontalScroll--withConstArrows'],\n className,\n )}\n onMouseEnter={calculateArrowsVisibility}\n >\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollLeft && (\n <ScrollArrow\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"left\"\n className={classNames(\n styles['HorizontalScroll__arrow'],\n styles['HorizontalScroll__arrowLeft'],\n )}\n onClick={scrollToLeft}\n />\n )}\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollRight && (\n <ScrollArrow\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"right\"\n className={classNames(\n styles['HorizontalScroll__arrow'],\n styles['HorizontalScroll__arrowRight'],\n )}\n onClick={scrollToRight}\n />\n )}\n <div className={styles['HorizontalScroll__in']} ref={scrollerRef}>\n <div className={styles['HorizontalScroll__in-wrapper']}>{children}</div>\n </div>\n </div>\n );\n};\n"],"names":["React","classNames","noop","useAdaptivityHasPointer","useEventListener","useExternRef","easeInOutSine","ScrollArrow","now","performance","Date","roundUpElementScrollLeft","el","Math","ceil","scrollLeft","SCROLL_ONE_FRAME_TIME","doScroll","scrollElement","getScrollPosition","animationQueue","onScrollToRightBorder","onScrollEnd","onScrollStart","initialScrollWidth","scrollAnimationDuration","maxLeft","offsetWidth","startLeft","endLeft","startTime","scroll","time","elapsed","min","value","currentLeft","max","requestAnimationFrame","shift","length","HorizontalScroll","children","getScrollToLeft","getScrollToRight","showArrows","arrowSize","arrowOffsetY","getRef","className","scrollOnAnyWheel","restProps","useState","canScrollLeft","setCanScrollLeft","canScrollRight","setCanScrollRight","isCustomScrollingRef","useRef","scrollerRef","hasPointer","scrollTo","useCallback","current","push","firstElementChild","scrollWidth","scrollToLeft","i","scrollToRight","calculateArrowsVisibility","scrollEvent","useEffect","addScrollerRefToScrollEvent","add","remove","onwheel","e","scrollBy","left","deltaX","deltaY","behavior","preventDefault","wheelEvent","addScrollerRefToWheelEvent","div","onMouseEnter","undefined","size","offsetY","direction","onClick","ref"],"mappings":";;;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,IAAI,QAAQ,kBAAkB;AACnD,SAASC,uBAAuB,QAAQ,sCAAsC;AAC9E,SAASC,gBAAgB,QAAQ,+BAA+B;AAChE,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,aAAa,QAAQ,eAAe;AAE7C,SAASC,WAAW,QAAQ,6BAA6B;AA6CzD;;CAEC,GACD,SAASC;IACP,OAAOC,eAAeA,YAAYD,GAAG,GAAGC,YAAYD,GAAG,KAAKE,KAAKF,GAAG;AACtE;AAEA;;;CAGC,GACD,IAAMG,2BAA2B,SAACC;WAAoBC,KAAKC,IAAI,CAACF,GAAGG,UAAU;;AAE7E;;;;CAIC,GACD,IAAMC,wBAAwB;AAE9B,SAASC,SAAS,KASF;QARdC,gBADgB,MAChBA,eACAC,oBAFgB,MAEhBA,mBACAC,iBAHgB,MAGhBA,gBACAC,wBAJgB,MAIhBA,uBACAC,cALgB,MAKhBA,aACAC,gBANgB,MAMhBA,eACAC,qBAPgB,MAOhBA,qDAPgB,MAQhBC,yBAAAA,sEAA0BT;IAE1B,IAAI,CAACE,iBAAiB,CAACC,mBAAmB;QACxC;IACF;IAEA;;GAEC,GACD,IAAMO,UAAUF,qBAAqBN,cAAcS,WAAW;IAE9D,IAAIC,YAAYjB,yBAAyBO;IACzC,IAAIW,UAAUV,kBAAkBS;IAEhCL;IAEA,IAAIM,WAAWH,SAAS;QACtBL;QACAQ,UAAUH;IACZ;IAEA,IAAMI,YAAYtB;IAEjB,CAAA,SAASuB;QACR,IAAI,CAACb,eAAe;YAClBI;YACA;QACF;QAEA,IAAMU,OAAOxB;QACb,IAAMyB,UAAUpB,KAAKqB,GAAG,CAAC,AAACF,CAAAA,OAAOF,SAAQ,IAAKL,yBAAyB;QAEvE,IAAMU,QAAQ7B,cAAc2B;QAE5B,IAAMG,cAAcR,YAAY,AAACC,CAAAA,UAAUD,SAAQ,IAAKO;QACxDjB,cAAcH,UAAU,GAAGF,KAAKC,IAAI,CAACsB;QAErC,IAAIzB,yBAAyBO,mBAAmBL,KAAKwB,GAAG,CAAC,GAAGR,YAAYI,YAAY,GAAG;YACrFK,sBAAsBP;YACtB;QACF;QAEAT;QACAF,eAAemB,KAAK;QACpB,IAAInB,eAAeoB,MAAM,GAAG,GAAG;YAC7BpB,cAAc,CAAC,EAAE;QACnB;IACF,CAAA;AACF;AAEA;;CAEC,GACD,OAAO,IAAMqB,mBAAmB;QAC9BC,kBAAAA,UACAC,yBAAAA,iBACAC,0BAAAA,6CACAC,YAAAA,4CAAa,oDACbC,WAAAA,0CAAY,wBACZC,sBAAAA,sDACAtB,yBAAAA,sEAA0BT,wDAC1BgC,gBAAAA,QACAC,mBAAAA,4CACAC,kBAAAA,wDAAmB,iCAChBC;QAVHT;QACAC;QACAC;QACAC;QACAC;QACAC;QACAtB;QACAuB;QACAC;QACAC;;IAGA,IAA0ClD,mCAAAA,MAAMoD,QAAQ,CAAC,YAAlDC,gBAAmCrD,oBAApBsD,mBAAoBtD;IAC1C,IAA4CA,oCAAAA,MAAMoD,QAAQ,CAAC,YAApDG,iBAAqCvD,qBAArBwD,oBAAqBxD;IAE5C,IAAMyD,uBAAuBzD,MAAM0D,MAAM,CAAC;IAE1C,IAAMC,cAActD,aAAa2C;IAEjC,IAAM5B,iBAAiBpB,MAAM0D,MAAM,CAAiB,EAAE;IAEtD,IAAME,aAAazD;IAEnB,IAAM0D,WAAW7D,MAAM8D,WAAW,CAChC,SAAC3C;QACC,IAAMD,gBAAgByC,YAAYI,OAAO;QAEzC3C,eAAe2C,OAAO,CAACC,IAAI,CAAC;gBAQJ9C,kCAAAA;mBAPtBD,SAAS;gBACPC,eAAAA;gBACAC,mBAAAA;gBACAC,gBAAgBA,eAAe2C,OAAO;gBACtC1C,uBAAuB;2BAAMmC,kBAAkB;;gBAC/ClC,aAAa;2BAAOmC,qBAAqBM,OAAO,GAAG;;gBACnDxC,eAAe;2BAAOkC,qBAAqBM,OAAO,GAAG;;gBACrDvC,oBAAoBN,EAAAA,iBAAAA,2BAAAA,sCAAAA,mCAAAA,eAAe+C,iBAAiB,cAAhC/C,uDAAAA,iCAAkCgD,WAAW,KAAI;gBACrEzC,yBAAAA;YACF;;QAEF,IAAIL,eAAe2C,OAAO,CAACvB,MAAM,KAAK,GAAG;YACvCpB,eAAe2C,OAAO,CAAC,EAAE;QAC3B;IACF,GACA;QAACtC;QAAyBkC;KAAY;IAGxC,IAAMQ,eAAenE,MAAM8D,WAAW,CAAC;QACrC,IAAM3C,oBACJwB,4BAAAA,6BAAAA,kBAAoB,SAACyB;mBAAcA,IAAIT,YAAYI,OAAO,CAAEpC,WAAW;;QACzEkC,SAAS1C;IACX,GAAG;QAACwB;QAAiBkB;QAAUF;KAAY;IAE3C,IAAMU,gBAAgBrE,MAAM8D,WAAW,CAAC;QACtC,IAAM3C,oBACJyB,6BAAAA,8BAAAA,mBAAqB,SAACwB;mBAAcA,IAAIT,YAAYI,OAAO,CAAEpC,WAAW;;QAC1EkC,SAAS1C;IACX,GAAG;QAACyB;QAAkBiB;QAAUF;KAAY;IAE5C,IAAMW,4BAA4BtE,MAAM8D,WAAW,CAAC;QAClD,IAAIjB,cAAce,cAAcD,YAAYI,OAAO,IAAI,CAACN,qBAAqBM,OAAO,EAAE;YACpF,IAAM7C,gBAAgByC,YAAYI,OAAO;YAEzCT,iBAAiBpC,cAAcH,UAAU,GAAG;YAC5CyC,kBACE7C,yBAAyBO,iBAAiBA,cAAcS,WAAW,GACjET,cAAcgD,WAAW;QAE/B;IACF,GAAG;QAACN;QAAYD;QAAad;KAAW;IAExC,IAAM0B,cAAcnE,iBAAiB,UAAUkE;IAC/CtE,MAAMwE,SAAS,CACb,SAASC;QACP,IAAI,CAACd,YAAYI,OAAO,EAAE;YACxB,OAAO7D;QACT;QAEAqE,YAAYG,GAAG,CAACf,YAAYI,OAAO;QACnC,OAAOQ,YAAYI,MAAM;IAC3B,GACA;QAACJ;QAAaZ;KAAY;IAG5B3D,MAAMwE,SAAS,CAACF,2BAA2B;QAACA;QAA2B5B;KAAS;IAEhF;;GAEC,GACD,IAAMkC,UAAU5E,MAAM8D,WAAW,CAC/B,SAACe;QACClB,YAAYI,OAAO,CAAEe,QAAQ,CAAC;YAAEC,MAAMF,EAAEG,MAAM,GAAGH,EAAEI,MAAM;YAAEC,UAAU;QAAO;QAC5EL,EAAEM,cAAc;IAClB,GACA;QAACxB;KAAY;IAGf,IAAMyB,aAAahF,iBAAiB,SAASwE;IAC7C5E,MAAMwE,SAAS,CACb,SAASa;QACP,IAAI,CAAC1B,YAAYI,OAAO,IAAI,CAACb,kBAAkB;YAC7C,OAAOhD;QACT;QAEAkF,WAAWV,GAAG,CAACf,YAAYI,OAAO;QAElC,OAAOqB,WAAWT,MAAM;IAC1B,GACA;QAACS;QAAYzB;QAAaT;KAAiB;IAG7C,qBACE,oBAACoC,+CACKnC;QACJF,WAAWhD,mCAET,gCACA4C,eAAe,qDACfI;QAEFsC,cAAcjB;QAEbzB,cAAee,CAAAA,cAAcA,eAAe4B,SAAQ,KAAMnC,+BACzD,oBAAC9C;QACCkF,MAAM3C;QACN4C,SAAS3C;QACT4C,WAAU;QACV1C,WAAWhD;QAIX2F,SAASzB;QAGZtB,cAAee,CAAAA,cAAcA,eAAe4B,SAAQ,KAAMjC,gCACzD,oBAAChD;QACCkF,MAAM3C;QACN4C,SAAS3C;QACT4C,WAAU;QACV1C,WAAWhD;QAIX2F,SAASvB;sBAGb,oBAACiB;QAAIrC,SAAS;QAAkC4C,KAAKlC;qBACnD,oBAAC2B;QAAIrC,SAAS;OAA2CP;AAIjE,EAAE"}
|
|
@@ -5,61 +5,76 @@ import * as React from "react";
|
|
|
5
5
|
import { ImageBase } from "../ImageBase/ImageBase";
|
|
6
6
|
import { ImageBadge } from "./ImageBadge/ImageBadge";
|
|
7
7
|
export var IMAGE_DEFAULT_SIZE = 48;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/ export var Image = function(_param) {
|
|
11
|
-
var _param_size = _param.size, size = _param_size === void 0 ? IMAGE_DEFAULT_SIZE : _param_size, tmp = _param.borderRadius, borderRadiusProp = tmp === void 0 ? "m" : tmp, style = _param.style, className = _param.className, restProps = _object_without_properties(_param, [
|
|
12
|
-
"size",
|
|
13
|
-
"borderRadius",
|
|
14
|
-
"style",
|
|
15
|
-
"className"
|
|
16
|
-
]);
|
|
17
|
-
var borderRadius;
|
|
18
|
-
switch(borderRadiusProp){
|
|
8
|
+
var getBorderRadiusBySize = function(size, borderRadius) {
|
|
9
|
+
switch(borderRadius){
|
|
19
10
|
case "s":
|
|
20
11
|
{
|
|
21
12
|
if (size <= 32) {
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
13
|
+
return 2;
|
|
14
|
+
}
|
|
15
|
+
if (size <= 56) {
|
|
16
|
+
return 3;
|
|
25
17
|
}
|
|
26
|
-
|
|
27
|
-
break;
|
|
18
|
+
return 4;
|
|
28
19
|
}
|
|
29
20
|
case "m":
|
|
30
21
|
{
|
|
31
22
|
if (size <= 32) {
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
return 3;
|
|
24
|
+
}
|
|
25
|
+
if (size <= 48) {
|
|
26
|
+
return 4;
|
|
27
|
+
}
|
|
28
|
+
if (size <= 72) {
|
|
29
|
+
return 6;
|
|
39
30
|
}
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
if (size <= 80) {
|
|
32
|
+
return 8;
|
|
33
|
+
}
|
|
34
|
+
return 10;
|
|
42
35
|
}
|
|
43
36
|
case "l":
|
|
44
37
|
{
|
|
45
38
|
if (size <= 16) {
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} else if (size <= 48) {
|
|
54
|
-
borderRadius = 10;
|
|
55
|
-
} else if (size <= 56) {
|
|
56
|
-
borderRadius = 12;
|
|
57
|
-
} else if (size <= 64) {
|
|
58
|
-
borderRadius = 14;
|
|
39
|
+
return 4;
|
|
40
|
+
}
|
|
41
|
+
if (size <= 20) {
|
|
42
|
+
return 5;
|
|
43
|
+
}
|
|
44
|
+
if (size <= 32) {
|
|
45
|
+
return 6;
|
|
59
46
|
}
|
|
60
|
-
|
|
47
|
+
if (size <= 40) {
|
|
48
|
+
return 8;
|
|
49
|
+
}
|
|
50
|
+
if (size <= 48) {
|
|
51
|
+
return 10;
|
|
52
|
+
}
|
|
53
|
+
if (size <= 56) {
|
|
54
|
+
return 12;
|
|
55
|
+
}
|
|
56
|
+
if (size <= 64) {
|
|
57
|
+
return 14;
|
|
58
|
+
}
|
|
59
|
+
return 16;
|
|
61
60
|
}
|
|
62
61
|
}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* @see https://vkcom.github.io/VKUI/#/Image
|
|
65
|
+
*/ export var Image = function(_param) {
|
|
66
|
+
var _param_size = _param.size, size = _param_size === void 0 ? IMAGE_DEFAULT_SIZE : _param_size, tmp = _param.borderRadius, borderRadiusProp = tmp === void 0 ? "m" : tmp, style = _param.style, className = _param.className, restProps = _object_without_properties(_param, [
|
|
67
|
+
"size",
|
|
68
|
+
"borderRadius",
|
|
69
|
+
"style",
|
|
70
|
+
"className"
|
|
71
|
+
]);
|
|
72
|
+
var borderRadius = React.useMemo(function() {
|
|
73
|
+
return getBorderRadiusBySize(size, borderRadiusProp);
|
|
74
|
+
}, [
|
|
75
|
+
size,
|
|
76
|
+
borderRadiusProp
|
|
77
|
+
]);
|
|
63
78
|
return /*#__PURE__*/ React.createElement(ImageBase, _object_spread_props(_object_spread({}, restProps), {
|
|
64
79
|
size: size,
|
|
65
80
|
style: _object_spread_props(_object_spread({}, style), {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Image/Image.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ImageBase, type ImageBaseOverlayProps, type ImageBaseProps } from '../ImageBase/ImageBase';\nimport { ImageBadge, type ImageBadgeProps } from './ImageBadge/ImageBadge';\n\nexport type { ImageBadgeProps, ImageBaseOverlayProps as ImageOverlayProps };\n\nexport const IMAGE_DEFAULT_SIZE = 48;\n\nexport interface ImageProps extends Omit<ImageBaseProps, 'badge'> {\n /**\n * Размер закругления.\n */\n borderRadius?: 's' | 'l' | 'm';\n}\n\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Image/Image.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ImageBase, type ImageBaseOverlayProps, type ImageBaseProps } from '../ImageBase/ImageBase';\nimport { ImageBadge, type ImageBadgeProps } from './ImageBadge/ImageBadge';\n\nexport type { ImageBadgeProps, ImageBaseOverlayProps as ImageOverlayProps };\n\nexport const IMAGE_DEFAULT_SIZE = 48;\n\nexport interface ImageProps extends Omit<ImageBaseProps, 'badge'> {\n /**\n * Размер закругления.\n */\n borderRadius?: 's' | 'l' | 'm';\n}\n\nconst getBorderRadiusBySize = (\n size: Exclude<ImageBaseProps['size'], undefined>,\n borderRadius: Exclude<ImageProps['borderRadius'], undefined>,\n) => {\n switch (borderRadius) {\n case 's': {\n if (size <= 32) {\n return 2;\n }\n if (size <= 56) {\n return 3;\n }\n return 4;\n }\n case 'm': {\n if (size <= 32) {\n return 3;\n }\n if (size <= 48) {\n return 4;\n }\n if (size <= 72) {\n return 6;\n }\n if (size <= 80) {\n return 8;\n }\n return 10;\n }\n case 'l': {\n if (size <= 16) {\n return 4;\n }\n if (size <= 20) {\n return 5;\n }\n if (size <= 32) {\n return 6;\n }\n if (size <= 40) {\n return 8;\n }\n if (size <= 48) {\n return 10;\n }\n if (size <= 56) {\n return 12;\n }\n if (size <= 64) {\n return 14;\n }\n return 16;\n }\n }\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Image\n */\nexport const Image = ({\n size = IMAGE_DEFAULT_SIZE,\n borderRadius: borderRadiusProp = 'm',\n style,\n className,\n ...restProps\n}: ImageProps) => {\n const borderRadius = React.useMemo(\n () => getBorderRadiusBySize(size, borderRadiusProp),\n [size, borderRadiusProp],\n );\n\n return (\n <ImageBase\n {...restProps}\n size={size}\n style={{ ...style, borderRadius }}\n className={className}\n />\n );\n};\n\nImage.Badge = ImageBadge;\n\nImage.Overlay = ImageBase.Overlay;\n"],"names":["React","ImageBase","ImageBadge","IMAGE_DEFAULT_SIZE","getBorderRadiusBySize","size","borderRadius","Image","borderRadiusProp","style","className","restProps","useMemo","Badge","Overlay"],"mappings":";;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,SAAS,QAAyD,yBAAyB;AACpG,SAASC,UAAU,QAA8B,0BAA0B;AAI3E,OAAO,IAAMC,qBAAqB,GAAG;AASrC,IAAMC,wBAAwB,SAC5BC,MACAC;IAEA,OAAQA;QACN,KAAK;YAAK;gBACR,IAAID,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,OAAO;YACT;QACA,KAAK;YAAK;gBACR,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,OAAO;YACT;QACA,KAAK;YAAK;gBACR,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,IAAIA,QAAQ,IAAI;oBACd,OAAO;gBACT;gBACA,OAAO;YACT;IACF;AACF;AAEA;;CAEC,GACD,OAAO,IAAME,QAAQ;6BACnBF,MAAAA,gCAAOF,kCACOK,aAAdF,cAAcE,mBAAAA,iBAAmB,MAAnBA,KACdC,eAAAA,OACAC,mBAAAA,WACGC;QAJHN;QACAC;QACAG;QACAC;;IAGA,IAAMJ,eAAeN,MAAMY,OAAO,CAChC;eAAMR,sBAAsBC,MAAMG;OAClC;QAACH;QAAMG;KAAiB;IAG1B,qBACE,oBAACP,mDACKU;QACJN,MAAMA;QACNI,OAAO,wCAAKA;YAAOH,cAAAA;;QACnBI,WAAWA;;AAGjB,EAAE;AAEFH,MAAMM,KAAK,GAAGX;AAEdK,MAAMO,OAAO,GAAGb,UAAUa,OAAO"}
|
|
@@ -4,6 +4,7 @@ import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_
|
|
|
4
4
|
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { classNames } from "@vkontakte/vkjs";
|
|
7
|
+
import { useExternRef } from "../../hooks/useExternRef";
|
|
7
8
|
import { ImageBaseBadge } from "./ImageBaseBadge/ImageBaseBadge";
|
|
8
9
|
import { ImageBaseOverlay } from "./ImageBaseOverlay/ImageBaseOverlay";
|
|
9
10
|
import { ImageBaseContext } from "./context";
|
|
@@ -54,6 +55,9 @@ export { ImageBaseContext };
|
|
|
54
55
|
}
|
|
55
56
|
var handleImageLoad = function(event) {
|
|
56
57
|
var _onLoad;
|
|
58
|
+
if (loaded) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
57
61
|
setLoaded(true);
|
|
58
62
|
setFailed(false);
|
|
59
63
|
(_onLoad = onLoad) === null || _onLoad === void 0 ? void 0 : _onLoad(event);
|
|
@@ -64,6 +68,21 @@ export { ImageBaseContext };
|
|
|
64
68
|
setFailed(true);
|
|
65
69
|
(_onError = onError) === null || _onError === void 0 ? void 0 : _onError(event);
|
|
66
70
|
};
|
|
71
|
+
var imgRef = useExternRef(getRef);
|
|
72
|
+
var isOnLoadStatusCheckedRef = React.useRef(false);
|
|
73
|
+
React.useEffect(function dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater() {
|
|
74
|
+
if (isOnLoadStatusCheckedRef.current) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
isOnLoadStatusCheckedRef.current = true;
|
|
78
|
+
if (imgRef.current && imgRef.current.complete && !loaded) {
|
|
79
|
+
var event = new Event("load");
|
|
80
|
+
imgRef.current.dispatchEvent(event);
|
|
81
|
+
}
|
|
82
|
+
}, [
|
|
83
|
+
imgRef,
|
|
84
|
+
loaded
|
|
85
|
+
]);
|
|
67
86
|
var sizeClassName = function() {
|
|
68
87
|
switch(size){
|
|
69
88
|
case 28:
|
|
@@ -94,7 +113,7 @@ export { ImageBaseContext };
|
|
|
94
113
|
"aria-label": ariaLabel,
|
|
95
114
|
onClick: onClick
|
|
96
115
|
}), hasSrc && /*#__PURE__*/ React.createElement("img", {
|
|
97
|
-
ref:
|
|
116
|
+
ref: imgRef,
|
|
98
117
|
alt: alt,
|
|
99
118
|
className: "vkuiImageBase__img",
|
|
100
119
|
crossOrigin: crossOrigin,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ImageBase/ImageBase.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport type { HasRef, HasRootRef, LiteralUnion } from '../../types';\nimport { ImageBaseBadge, type ImageBaseBadgeProps } from './ImageBaseBadge/ImageBaseBadge';\nimport { ImageBaseOverlay, type ImageBaseOverlayProps } from './ImageBaseOverlay/ImageBaseOverlay';\nimport { ImageBaseContext } from './context';\nimport type { ImageBaseContextProps, ImageBaseExpectedIconProps, ImageBaseSize } from './types';\nimport { validateFallbackIcon, validateSize } from './validators';\nimport styles from './ImageBase.module.css';\n\nexport type {\n ImageBaseSize,\n ImageBaseExpectedIconProps,\n ImageBaseBadgeProps,\n ImageBaseOverlayProps,\n ImageBaseContextProps,\n};\n\nexport {\n getBadgeIconSizeByImageBaseSize,\n getFallbackIconSizeByImageBaseSize,\n getOverlayIconSizeByImageBaseSize,\n} from './helpers';\n\nexport { ImageBaseContext };\n\nexport interface ImageBaseProps\n extends React.ImgHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLImageElement> {\n /**\n * Задаёт размер картинки.\n *\n * Используйте размеры заданные дизайн-системой `16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 56 | 64 | 72 | 80 | 88 | 96`.\n *\n * > ⚠️ Использование кастомного размера – это пограничный кейс.\n */\n size?: LiteralUnion<ImageBaseSize, number>;\n /**\n * Включает или отключает обводку.\n */\n withBorder?: boolean;\n /**\n * Фолбек на случай, если картинка не прогрузилась.\n *\n * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getFallbackIconSizeByImageBaseSize()`.\n *\n * > Предпочтительней использовать иконки из `@vkontakte/icons`.\n *\n * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же\n * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы\n * > использовали иконку.\n *\n * > ⚠️ Может перекрывать `children`.\n */\n fallbackIcon?: React.ReactElement<ImageBaseExpectedIconProps>;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ImageBase\n */\nexport const ImageBase = ({\n alt,\n crossOrigin,\n decoding,\n loading,\n referrerPolicy,\n sizes,\n src,\n srcSet,\n useMap,\n getRef,\n size = 24,\n width,\n height,\n style,\n className,\n getRootRef,\n withBorder = true,\n 'fallbackIcon': fallbackIconProp,\n children,\n 'aria-label': ariaLabel,\n onClick,\n onLoad,\n onError,\n ...restProps\n}: ImageBaseProps) => {\n const [loaded, setLoaded] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n\n const hasSrc = src || srcSet;\n const needShowFallbackIcon = (failed || !hasSrc) && React.isValidElement(fallbackIconProp);\n\n const fallbackIcon = needShowFallbackIcon ? fallbackIconProp : null;\n\n if (process.env.NODE_ENV === 'development') {\n validateSize(size);\n if (fallbackIcon) {\n validateFallbackIcon(size, { name: 'fallbackIcon', value: fallbackIcon });\n }\n }\n\n const handleImageLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(true);\n setFailed(false);\n onLoad?.(event);\n };\n\n const handleImageError = (event: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(false);\n setFailed(true);\n onError?.(event);\n };\n\n const sizeClassName = (() => {\n switch (size) {\n case 28:\n return styles['ImageBase--size-28'];\n case 32:\n return styles['ImageBase--size-32'];\n case 40:\n return styles['ImageBase--size-40'];\n case 48:\n return styles['ImageBase--size-48'];\n case 72:\n return styles['ImageBase--size-72'];\n }\n\n return null;\n })();\n\n return (\n <ImageBaseContext.Provider value={{ size }}>\n <div\n {...restProps}\n ref={getRootRef}\n style={{ ...style, width: size, height: size }}\n className={classNames(\n className,\n styles['ImageBase'],\n sizeClassName,\n loaded && styles['ImageBase--loaded'],\n )}\n role={hasSrc ? 'img' : 'presentation'}\n aria-label={ariaLabel}\n onClick={onClick}\n >\n {hasSrc && (\n <img\n ref={
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ImageBase/ImageBase.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport type { HasRef, HasRootRef, LiteralUnion } from '../../types';\nimport { ImageBaseBadge, type ImageBaseBadgeProps } from './ImageBaseBadge/ImageBaseBadge';\nimport { ImageBaseOverlay, type ImageBaseOverlayProps } from './ImageBaseOverlay/ImageBaseOverlay';\nimport { ImageBaseContext } from './context';\nimport type { ImageBaseContextProps, ImageBaseExpectedIconProps, ImageBaseSize } from './types';\nimport { validateFallbackIcon, validateSize } from './validators';\nimport styles from './ImageBase.module.css';\n\nexport type {\n ImageBaseSize,\n ImageBaseExpectedIconProps,\n ImageBaseBadgeProps,\n ImageBaseOverlayProps,\n ImageBaseContextProps,\n};\n\nexport {\n getBadgeIconSizeByImageBaseSize,\n getFallbackIconSizeByImageBaseSize,\n getOverlayIconSizeByImageBaseSize,\n} from './helpers';\n\nexport { ImageBaseContext };\n\nexport interface ImageBaseProps\n extends React.ImgHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLImageElement> {\n /**\n * Задаёт размер картинки.\n *\n * Используйте размеры заданные дизайн-системой `16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 56 | 64 | 72 | 80 | 88 | 96`.\n *\n * > ⚠️ Использование кастомного размера – это пограничный кейс.\n */\n size?: LiteralUnion<ImageBaseSize, number>;\n /**\n * Включает или отключает обводку.\n */\n withBorder?: boolean;\n /**\n * Фолбек на случай, если картинка не прогрузилась.\n *\n * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getFallbackIconSizeByImageBaseSize()`.\n *\n * > Предпочтительней использовать иконки из `@vkontakte/icons`.\n *\n * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же\n * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы\n * > использовали иконку.\n *\n * > ⚠️ Может перекрывать `children`.\n */\n fallbackIcon?: React.ReactElement<ImageBaseExpectedIconProps>;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ImageBase\n */\nexport const ImageBase = ({\n alt,\n crossOrigin,\n decoding,\n loading,\n referrerPolicy,\n sizes,\n src,\n srcSet,\n useMap,\n getRef,\n size = 24,\n width,\n height,\n style,\n className,\n getRootRef,\n withBorder = true,\n 'fallbackIcon': fallbackIconProp,\n children,\n 'aria-label': ariaLabel,\n onClick,\n onLoad,\n onError,\n ...restProps\n}: ImageBaseProps) => {\n const [loaded, setLoaded] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n\n const hasSrc = src || srcSet;\n const needShowFallbackIcon = (failed || !hasSrc) && React.isValidElement(fallbackIconProp);\n\n const fallbackIcon = needShowFallbackIcon ? fallbackIconProp : null;\n\n if (process.env.NODE_ENV === 'development') {\n validateSize(size);\n if (fallbackIcon) {\n validateFallbackIcon(size, { name: 'fallbackIcon', value: fallbackIcon });\n }\n }\n\n const handleImageLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {\n if (loaded) {\n return;\n }\n\n setLoaded(true);\n setFailed(false);\n onLoad?.(event);\n };\n\n const handleImageError = (event: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(false);\n setFailed(true);\n onError?.(event);\n };\n\n const imgRef = useExternRef(getRef);\n const isOnLoadStatusCheckedRef = React.useRef(false);\n React.useEffect(\n function dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater() {\n if (isOnLoadStatusCheckedRef.current) {\n return;\n }\n isOnLoadStatusCheckedRef.current = true;\n\n if (imgRef.current && imgRef.current.complete && !loaded) {\n const event = new Event('load');\n imgRef.current.dispatchEvent(event);\n }\n },\n [imgRef, loaded],\n );\n\n const sizeClassName = (() => {\n switch (size) {\n case 28:\n return styles['ImageBase--size-28'];\n case 32:\n return styles['ImageBase--size-32'];\n case 40:\n return styles['ImageBase--size-40'];\n case 48:\n return styles['ImageBase--size-48'];\n case 72:\n return styles['ImageBase--size-72'];\n }\n\n return null;\n })();\n\n return (\n <ImageBaseContext.Provider value={{ size }}>\n <div\n {...restProps}\n ref={getRootRef}\n style={{ ...style, width: size, height: size }}\n className={classNames(\n className,\n styles['ImageBase'],\n sizeClassName,\n loaded && styles['ImageBase--loaded'],\n )}\n role={hasSrc ? 'img' : 'presentation'}\n aria-label={ariaLabel}\n onClick={onClick}\n >\n {hasSrc && (\n <img\n ref={imgRef}\n alt={alt}\n className={styles['ImageBase__img']}\n crossOrigin={crossOrigin}\n decoding={decoding}\n loading={loading}\n referrerPolicy={referrerPolicy}\n sizes={sizes}\n src={src}\n srcSet={srcSet}\n useMap={useMap}\n width={width}\n height={height}\n onLoad={handleImageLoad}\n onError={handleImageError}\n />\n )}\n {fallbackIcon && (\n <div className={classNames(styles['ImageBase__fallback'])}>{fallbackIcon}</div>\n )}\n {children}\n {withBorder && <div aria-hidden className={styles['ImageBase__border']} />}\n </div>\n </ImageBaseContext.Provider>\n );\n};\n\nImageBase.Badge = ImageBaseBadge;\n\nImageBase.Overlay = ImageBaseOverlay;\n"],"names":["React","classNames","useExternRef","ImageBaseBadge","ImageBaseOverlay","ImageBaseContext","validateFallbackIcon","validateSize","getBadgeIconSizeByImageBaseSize","getFallbackIconSizeByImageBaseSize","getOverlayIconSizeByImageBaseSize","ImageBase","alt","crossOrigin","decoding","loading","referrerPolicy","sizes","src","srcSet","useMap","getRef","size","width","height","style","className","getRootRef","withBorder","fallbackIconProp","children","ariaLabel","onClick","onLoad","onError","restProps","useState","loaded","setLoaded","failed","setFailed","hasSrc","needShowFallbackIcon","isValidElement","fallbackIcon","process","env","NODE_ENV","name","value","handleImageLoad","event","handleImageError","imgRef","isOnLoadStatusCheckedRef","useRef","useEffect","dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater","current","complete","Event","dispatchEvent","sizeClassName","Provider","div","ref","role","aria-label","img","aria-hidden","Badge","Overlay"],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ import { Paragraph } from "../Typography/Paragraph/Paragraph";
|
|
|
27
27
|
accent: "vkuiMiniInfoCell--mode-accent",
|
|
28
28
|
more: "vkuiMiniInfoCell--mode-more"
|
|
29
29
|
})[mode], className);
|
|
30
|
-
var cellContent = /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("span", {
|
|
30
|
+
var cellContent = /*#__PURE__*/ React.createElement(React.Fragment, null, hasReactNode(before) && /*#__PURE__*/ React.createElement("span", {
|
|
31
31
|
className: "vkuiMiniInfoCell__before"
|
|
32
32
|
}, before), /*#__PURE__*/ React.createElement("div", {
|
|
33
33
|
className: "vkuiMiniInfoCell__middle"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/MiniInfoCell/MiniInfoCell.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Icon16Chevron } from '@vkontakte/icons';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { Tappable } from '../Tappable/Tappable';\nimport { Paragraph } from '../Typography/Paragraph/Paragraph';\nimport styles from './MiniInfoCell.module.css';\n\nexport interface MiniInfoCellProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Иконка слева.<br />\n * Рекомендуется использовать иконки размера 20.\n */\n before: React.ReactNode;\n\n /**\n * Содержимое справа.<br />\n * `<UsersStack size=\"s\" />` или `<Avatar size={24} />`\n */\n after?: React.ReactNode;\n\n /**\n * Тип ячейки:\n *\n * - `base` – базовая ячейка с серой иконкой и серым текстом.<br />\n * В компонент можно передать `Link`, чтобы визуально сделать часть текста ссылкой.\n * - `add` – тип ячейки, который показывает, что взаимодействие с ней должно вызывать действие добавления чего-то.\n * - `more` – взаимодействие с такой ячейкой должно открывать какую-то подробную информацию.\n */\n mode?: 'base' | 'accent' | 'add' | 'more';\n\n /**\n * Тип отображения текста:\n *\n * - `nowrap` – в одну строку, текст не переносится и обрезается.\n * - `short` – максимально отображается 3 строки, остальное обрезается.\n * - `full` – текст отображается полностью.\n */\n textWrap?: 'nowrap' | 'short' | 'full';\n\n /**\n * Передавать `true`, если предполагается переход при клике по ячейке.\n */\n expandable?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/MiniInfoCell\n */\nexport const MiniInfoCell = ({\n before,\n after,\n children,\n mode = 'base',\n textWrap = 'nowrap',\n expandable = false,\n className,\n ...restProps\n}: MiniInfoCellProps) => {\n const cellClasses = classNames(\n styles['MiniInfoCell'],\n {\n nowrap: styles['MiniInfoCell--textWrap-nowrap'],\n full: styles['MiniInfoCell--textWrap-full'],\n short: styles['MiniInfoCell--textWrap-short'],\n }[textWrap],\n mode !== 'base' &&\n {\n add: styles['MiniInfoCell--mode-add'],\n accent: styles['MiniInfoCell--mode-accent'],\n more: styles['MiniInfoCell--mode-more'],\n }[mode],\n className,\n );\n\n const cellContent = (\n <React.Fragment>\n <span className={styles['MiniInfoCell__before']}>{before}</span
|
|
1
|
+
{"version":3,"sources":["../../../src/components/MiniInfoCell/MiniInfoCell.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Icon16Chevron } from '@vkontakte/icons';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { Tappable } from '../Tappable/Tappable';\nimport { Paragraph } from '../Typography/Paragraph/Paragraph';\nimport styles from './MiniInfoCell.module.css';\n\nexport interface MiniInfoCellProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Иконка слева.<br />\n * Рекомендуется использовать иконки размера 20.\n */\n before: React.ReactNode;\n\n /**\n * Содержимое справа.<br />\n * `<UsersStack size=\"s\" />` или `<Avatar size={24} />`\n */\n after?: React.ReactNode;\n\n /**\n * Тип ячейки:\n *\n * - `base` – базовая ячейка с серой иконкой и серым текстом.<br />\n * В компонент можно передать `Link`, чтобы визуально сделать часть текста ссылкой.\n * - `add` – тип ячейки, который показывает, что взаимодействие с ней должно вызывать действие добавления чего-то.\n * - `more` – взаимодействие с такой ячейкой должно открывать какую-то подробную информацию.\n */\n mode?: 'base' | 'accent' | 'add' | 'more';\n\n /**\n * Тип отображения текста:\n *\n * - `nowrap` – в одну строку, текст не переносится и обрезается.\n * - `short` – максимально отображается 3 строки, остальное обрезается.\n * - `full` – текст отображается полностью.\n */\n textWrap?: 'nowrap' | 'short' | 'full';\n\n /**\n * Передавать `true`, если предполагается переход при клике по ячейке.\n */\n expandable?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/MiniInfoCell\n */\nexport const MiniInfoCell = ({\n before,\n after,\n children,\n mode = 'base',\n textWrap = 'nowrap',\n expandable = false,\n className,\n ...restProps\n}: MiniInfoCellProps) => {\n const cellClasses = classNames(\n styles['MiniInfoCell'],\n {\n nowrap: styles['MiniInfoCell--textWrap-nowrap'],\n full: styles['MiniInfoCell--textWrap-full'],\n short: styles['MiniInfoCell--textWrap-short'],\n }[textWrap],\n mode !== 'base' &&\n {\n add: styles['MiniInfoCell--mode-add'],\n accent: styles['MiniInfoCell--mode-accent'],\n more: styles['MiniInfoCell--mode-more'],\n }[mode],\n className,\n );\n\n const cellContent = (\n <React.Fragment>\n {hasReactNode(before) && <span className={styles['MiniInfoCell__before']}>{before}</span>}\n <div className={styles['MiniInfoCell__middle']}>\n <Paragraph\n className={styles['MiniInfoCell__content']}\n weight={mode === 'more' ? '2' : undefined}\n >\n {children}\n </Paragraph>\n {expandable && <Icon16Chevron />}\n </div>\n {hasReactNode(after) && <span className={styles['MiniInfoCell__after']}>{after}</span>}\n </React.Fragment>\n );\n\n return restProps.onClick ? (\n <Tappable Component=\"div\" role=\"button\" {...restProps} className={cellClasses}>\n {cellContent}\n </Tappable>\n ) : (\n <div {...restProps} className={cellClasses}>\n {cellContent}\n </div>\n );\n};\n"],"names":["React","Icon16Chevron","classNames","hasReactNode","Tappable","Paragraph","MiniInfoCell","before","after","children","mode","textWrap","expandable","className","restProps","cellClasses","nowrap","full","short","add","accent","more","cellContent","Fragment","span","div","weight","undefined","onClick","Component","role"],"mappings":";;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,aAAa,QAAQ,mBAAmB;AACjD,SAASC,UAAU,EAAEC,YAAY,QAAQ,kBAAkB;AAC3D,SAASC,QAAQ,QAAQ,uBAAuB;AAChD,SAASC,SAAS,QAAQ,oCAAoC;AAyC9D;;CAEC,GACD,OAAO,IAAMC,eAAe;QAC1BC,gBAAAA,QACAC,eAAAA,OACAC,kBAAAA,+BACAC,MAAAA,gCAAO,+CACPC,UAAAA,wCAAW,uDACXC,YAAAA,4CAAa,2BACbC,mBAAAA,WACGC;QAPHP;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;;IAGA,IAAME,cAAcb,+BAElB;QACEc,MAAM;QACNC,IAAI;QACJC,KAAK;IACP,CAAC,CAACP,SAAS,EACXD,SAAS,UACP,CAAA;QACES,GAAG;QACHC,MAAM;QACNC,IAAI;IACN,CAAA,CAAC,CAACX,KAAK,EACTG;IAGF,IAAMS,4BACJ,oBAACtB,MAAMuB,QAAQ,QACZpB,aAAaI,yBAAW,oBAACiB;QAAKX,SAAS;OAAmCN,uBAC3E,oBAACkB;QAAIZ,SAAS;qBACZ,oBAACR;QACCQ,SAAS;QACTa,QAAQhB,SAAS,SAAS,MAAMiB;OAE/BlB,WAEFG,4BAAc,oBAACX,uBAEjBE,aAAaK,wBAAU,oBAACgB;QAAKX,SAAS;OAAkCL;IAI7E,OAAOM,UAAUc,OAAO,iBACtB,oBAACxB;QAASyB,WAAU;QAAMC,MAAK;OAAahB;QAAWD,WAAWE;QAC/DO,6BAGH,oBAACG,+CAAQX;QAAWD,WAAWE;QAC5BO;AAGP,EAAE"}
|