@vkontakte/vkui 7.6.4 → 7.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Calendar/Calendar.d.ts.map +1 -1
- package/dist/components/Calendar/Calendar.js +1 -2
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/CalendarHeader/CalendarHeader.js +1 -1
- package/dist/components/CalendarHeader/CalendarHeader.js.map +1 -1
- package/dist/components/CalendarRange/CalendarRange.d.ts.map +1 -1
- package/dist/components/CalendarRange/CalendarRange.js +2 -3
- package/dist/components/CalendarRange/CalendarRange.js.map +1 -1
- package/dist/components/CalendarRange/utils.d.ts.map +1 -1
- package/dist/components/CalendarRange/utils.js +1 -2
- package/dist/components/CalendarRange/utils.js.map +1 -1
- package/dist/components/CalendarTime/CalendarTime.js +1 -1
- package/dist/components/CalendarTime/CalendarTime.js.map +1 -1
- package/dist/components/CarouselBase/CarouselBase.d.ts +1 -1
- package/dist/components/CarouselBase/CarouselBase.d.ts.map +1 -1
- package/dist/components/CarouselBase/CarouselBase.js +38 -18
- package/dist/components/CarouselBase/CarouselBase.js.map +1 -1
- package/dist/components/CarouselBase/CarouselViewPort.d.ts +3 -2
- package/dist/components/CarouselBase/CarouselViewPort.d.ts.map +1 -1
- package/dist/components/CarouselBase/CarouselViewPort.js +13 -1
- package/dist/components/CarouselBase/CarouselViewPort.js.map +1 -1
- package/dist/components/CarouselBase/ScrollArrows.d.ts +3 -2
- package/dist/components/CarouselBase/ScrollArrows.d.ts.map +1 -1
- package/dist/components/CarouselBase/ScrollArrows.js +22 -11
- package/dist/components/CarouselBase/ScrollArrows.js.map +1 -1
- package/dist/components/CarouselBase/types.d.ts +9 -0
- package/dist/components/CarouselBase/types.d.ts.map +1 -1
- package/dist/components/CarouselBase/types.js.map +1 -1
- package/dist/components/Cell/Cell.d.ts +4 -0
- package/dist/components/Cell/Cell.d.ts.map +1 -1
- package/dist/components/Cell/Cell.js +3 -1
- package/dist/components/Cell/Cell.js.map +1 -1
- package/dist/components/DateInput/DateInput.d.ts.map +1 -1
- package/dist/components/DateInput/DateInput.js +1 -2
- package/dist/components/DateInput/DateInput.js.map +1 -1
- package/dist/components/Gallery/Gallery.d.ts +5 -1
- package/dist/components/Gallery/Gallery.d.ts.map +1 -1
- package/dist/components/Gallery/Gallery.js +19 -3
- package/dist/components/Gallery/Gallery.js.map +1 -1
- package/dist/components/ModalPage/ModalPageInternal.js +16 -8
- package/dist/components/ModalPage/ModalPageInternal.js.map +1 -1
- package/dist/components/ModalPage/types.d.ts +2 -2
- package/dist/components/ModalPage/types.d.ts.map +1 -1
- package/dist/components/ModalPage/types.js.map +1 -1
- package/dist/components/Search/Search.d.ts +5 -1
- package/dist/components/Search/Search.d.ts.map +1 -1
- package/dist/components/Search/Search.js +6 -4
- package/dist/components/Search/Search.js.map +1 -1
- package/dist/components.css +1 -1
- package/dist/components.css.map +1 -1
- package/dist/cssm/components/Calendar/Calendar.js +1 -2
- package/dist/cssm/components/Calendar/Calendar.js.map +1 -1
- package/dist/cssm/components/CalendarHeader/CalendarHeader.js +1 -1
- package/dist/cssm/components/CalendarHeader/CalendarHeader.js.map +1 -1
- package/dist/cssm/components/CalendarRange/CalendarRange.js +2 -3
- package/dist/cssm/components/CalendarRange/CalendarRange.js.map +1 -1
- package/dist/cssm/components/CalendarRange/utils.js +1 -2
- package/dist/cssm/components/CalendarRange/utils.js.map +1 -1
- package/dist/cssm/components/CalendarTime/CalendarTime.js +1 -1
- package/dist/cssm/components/CalendarTime/CalendarTime.js.map +1 -1
- package/dist/cssm/components/CarouselBase/CarouselBase.js +31 -15
- package/dist/cssm/components/CarouselBase/CarouselBase.js.map +1 -1
- package/dist/cssm/components/CarouselBase/CarouselBase.module.css +2 -0
- package/dist/cssm/components/CarouselBase/CarouselViewPort.js +13 -1
- package/dist/cssm/components/CarouselBase/CarouselViewPort.js.map +1 -1
- package/dist/cssm/components/CarouselBase/ScrollArrows.js +14 -7
- package/dist/cssm/components/CarouselBase/ScrollArrows.js.map +1 -1
- package/dist/cssm/components/CarouselBase/types.js.map +1 -1
- package/dist/cssm/components/Cell/Cell.js +2 -1
- package/dist/cssm/components/Cell/Cell.js.map +1 -1
- package/dist/cssm/components/DateInput/DateInput.js +1 -2
- package/dist/cssm/components/DateInput/DateInput.js.map +1 -1
- package/dist/cssm/components/Gallery/Gallery.js +14 -1
- package/dist/cssm/components/Gallery/Gallery.js.map +1 -1
- package/dist/cssm/components/ModalCard/ModalCard.module.css +0 -1
- package/dist/cssm/components/ModalOutlet/ModalOutlet.module.css +1 -0
- package/dist/cssm/components/ModalPage/ModalPage.module.css +2 -9
- package/dist/cssm/components/ModalPage/ModalPageInternal.js +16 -8
- package/dist/cssm/components/ModalPage/ModalPageInternal.js.map +1 -1
- package/dist/cssm/components/ModalPage/types.js.map +1 -1
- package/dist/cssm/components/Search/Search.js +4 -3
- package/dist/cssm/components/Search/Search.js.map +1 -1
- package/dist/cssm/hooks/useCalendar.js +1 -2
- package/dist/cssm/hooks/useCalendar.js.map +1 -1
- package/dist/cssm/hooks/useTodayDate.js +2 -2
- package/dist/cssm/hooks/useTodayDate.js.map +1 -1
- package/dist/cssm/lib/calendar.js +8 -12
- package/dist/cssm/lib/calendar.js.map +1 -1
- package/dist/cssm/lib/date.js +142 -1
- package/dist/cssm/lib/date.js.map +1 -1
- package/dist/cssm/styles/constants.css +3 -0
- package/dist/hooks/useCalendar.d.ts.map +1 -1
- package/dist/hooks/useCalendar.js +1 -2
- package/dist/hooks/useCalendar.js.map +1 -1
- package/dist/hooks/useTodayDate.js +2 -2
- package/dist/hooks/useTodayDate.js.map +1 -1
- package/dist/lib/calendar.d.ts.map +1 -1
- package/dist/lib/calendar.js +8 -12
- package/dist/lib/calendar.js.map +1 -1
- package/dist/lib/date.d.ts +41 -0
- package/dist/lib/date.d.ts.map +1 -1
- package/dist/lib/date.js +142 -1
- package/dist/lib/date.js.map +1 -1
- package/dist/vkui.css +1 -1
- package/dist/vkui.css.map +1 -1
- package/package.json +3 -4
- package/src/components/Calendar/Calendar.tsx +6 -2
- package/src/components/CalendarHeader/CalendarHeader.tsx +1 -1
- package/src/components/CalendarRange/CalendarRange.tsx +9 -3
- package/src/components/CalendarRange/utils.ts +1 -2
- package/src/components/CalendarTime/CalendarTime.tsx +1 -1
- package/src/components/CarouselBase/CarouselBase.module.css +2 -0
- package/src/components/CarouselBase/CarouselBase.module.css.d.ts.map +1 -1
- package/src/components/CarouselBase/CarouselBase.tsx +38 -16
- package/src/components/CarouselBase/CarouselViewPort.tsx +25 -2
- package/src/components/CarouselBase/ScrollArrows.tsx +14 -2
- package/src/components/CarouselBase/types.ts +9 -0
- package/src/components/Cell/Cell.tsx +6 -0
- package/src/components/DateInput/DateInput.tsx +8 -2
- package/src/components/Gallery/Gallery.tsx +20 -0
- package/src/components/ModalCard/ModalCard.module.css +0 -1
- package/src/components/ModalCard/ModalCard.module.css.d.ts.map +1 -1
- package/src/components/ModalOutlet/ModalOutlet.module.css +1 -0
- package/src/components/ModalPage/ModalPage.module.css +2 -9
- package/src/components/ModalPage/ModalPage.module.css.d.ts.map +1 -1
- package/src/components/ModalPage/ModalPageInternal.tsx +8 -11
- package/src/components/ModalPage/types.ts +5 -2
- package/src/components/Search/Search.tsx +44 -31
- package/src/hooks/useCalendar.ts +1 -2
- package/src/hooks/useTodayDate.ts +2 -2
- package/src/lib/calendar.ts +12 -10
- package/src/lib/date.ts +187 -0
- package/src/lib/floating/useFloatingWithInteractions/__snapshots__/useFloatingWithInteractions.test.tsx.snap +1 -1
- package/src/styles/constants.css +3 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/DateInput/DateInput.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon20CalendarOutline } from '@vkontakte/icons';\nimport { classNames } from '@vkontakte/vkjs';\nimport { startOfDay, startOfMinute } from 'date-fns';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useDateInput } from '../../hooks/useDateInput';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { type UseFocusTrapProps } from '../../hooks/useFocusTrap';\nimport { dateFormatter, dateTimeFormatter, isMatch, parse } from '../../lib/date';\nimport type { PlacementWithAuto } from '../../lib/floating';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasRootRef } from '../../types';\nimport { Calendar, type CalendarProps, type CalendarTestsProps } from '../Calendar/Calendar';\nimport { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';\nimport { FocusTrap } from '../FocusTrap/FocusTrap';\nimport { FormField, type FormFieldProps } from '../FormField/FormField';\nimport { IconButton } from '../IconButton/IconButton';\nimport { InputLikeDivider } from '../InputLike/InputLikeDivider';\nimport { NumberInputLike } from '../NumberInputLike/NumberInputLike';\nimport { Popper } from '../Popper/Popper';\nimport { Text } from '../Typography/Text/Text';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport { useDateInputValue } from './hooks';\nimport '../InputLike/InputLike.module.css'; // Reorder css\nimport styles from './DateInput.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n};\n\nexport type DateInputPropsTestsProps = {\n /**\n * Передает атрибут `data-testid` для поля ввода дня.\n */\n dayFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода месяца.\n */\n monthFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода года.\n */\n yearFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода часа.\n */\n hourFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода минут.\n */\n minuteFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки показа календаря.\n */\n showCalendarButtonTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки даты.\n */\n clearButtonTestId?: string;\n};\n\nexport interface DateInputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLDivElement>,\n 'value' | 'defaultValue' | 'onChange' | 'size'\n >,\n Pick<\n CalendarProps,\n | 'disablePast'\n | 'disableFuture'\n | 'enableTime'\n | 'shouldDisableDate'\n | 'onChange'\n | 'value'\n | 'defaultValue'\n | 'doneButtonText'\n | 'DoneButton'\n | 'weekStartsOn'\n | 'disablePickers'\n | 'changeHoursLabel'\n | 'changeMinutesLabel'\n | 'prevMonthLabel'\n | 'nextMonthLabel'\n | 'changeMonthLabel'\n | 'changeYearLabel'\n | 'showNeighboringMonth'\n | 'size'\n | 'viewDate'\n | 'onHeaderChange'\n | 'onNextMonth'\n | 'onPrevMonth'\n | 'prevMonthIcon'\n | 'nextMonthIcon'\n | 'minDateTime'\n | 'maxDateTime'\n | 'renderDayContent'\n >,\n Pick<UseFocusTrapProps, 'restoreFocus'>,\n HasRootRef<HTMLDivElement>,\n Omit<FormFieldProps, 'maxHeight'>,\n DateInputPropsTestsProps {\n /**\n * Передает атрибуты `data-testid` для интерактивных элементов в календаре.\n */\n calendarTestsProps?: CalendarTestsProps;\n /**\n * Расположение календаря относительно поля ввода.\n */\n calendarPlacement?: PlacementWithAuto;\n /**\n * Автоматически закрывать календарь при изменениях.\n */\n closeOnChange?: boolean;\n /**\n * `aria-label` для календаря.\n */\n calendarLabel?: string;\n /**\n * Label для кнопки очистки. Делает доступным для ассистивных технологий.\n */\n clearFieldLabel?: string;\n /**\n * Label для кнопки открытия календаря. Делает доступным для ассистивных технологий.\n */\n showCalendarLabel?: string;\n /**\n * Отключение открытия календаря.\n */\n disableCalendar?: boolean;\n /**\n * Обработчик изменения состояния открытия календаря.\n */\n onCalendarOpenChanged?: (opened: boolean) => void;\n /**\n * `aria-label` для поля изменения дня.\n */\n changeDayLabel?: string;\n /**\n * Обработчик нажатия на кнопку `\"Done\"`. Используется совместно с флагом `enableTime`.\n */\n onApply?: (value?: Date) => void;\n /**\n * Функция для кастомного форматирования отображаемого значения даты.\n * Позволяет переопределить стандартное отображение даты и вернуть собственное представление.\n */\n renderCustomValue?: (date: Date | undefined) => React.ReactNode;\n /**\n * Часовой пояс для отображения даты.\n */\n timezone?: string;\n /**\n * Включает режим в котором DateInput доступен\n * для ассистивных технологий.\n * В этом режиме:\n * - календарь больше не открывает при фокусе на DateInput;\n * - иконка календаря видна всегда, чтобы пользователи\n * ассистивных технологий могли открыть календарь по клику на иконку;\n * - календарь при открытии получает фокус, клавиатурный\n * фокус зациклен и не выходит за пределы календаря пока календарь не закрыт.\n */\n accessible?: boolean /* TODO [>=v8] включить по умолчанию */;\n /**\n * Позволяет отключить захват фокуса при появлении календаря.\n */\n disableFocusTrap?: UseFocusTrapProps['disabled'];\n}\n\nconst elementsConfig = (index: number) => {\n let length = 2;\n let min = 1;\n let max = 0;\n\n switch (index) {\n case 0:\n max = 31;\n break;\n case 1:\n max = 12;\n break;\n case 2:\n max = 2100;\n min = 1900;\n length = 4;\n break;\n case 3:\n max = 23;\n break;\n case 4:\n max = 59;\n break;\n }\n\n return { length, min, max };\n};\n\nconst getInternalValue = (value: CalendarProps['value']) => {\n const newValue = ['', '', '', '', ''];\n if (value) {\n newValue[0] = String(value.getDate()).padStart(2, '0');\n newValue[1] = String(value.getMonth() + 1).padStart(2, '0');\n newValue[2] = String(value.getFullYear()).padStart(4, '0');\n newValue[3] = String(value.getHours()).padStart(2, '0');\n newValue[4] = String(value.getMinutes()).padStart(2, '0');\n }\n return newValue;\n};\n\nconst CALENDAR_MUTATION_OBSERVER_OPTIONS: MutationObserverInit = {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['tabindex'],\n};\n\n/**\n * @see https://vkui.io/components/date-input\n */\nexport const DateInput = ({\n enableTime,\n shouldDisableDate,\n disableFuture,\n disablePast,\n minDateTime,\n maxDateTime,\n 'value': valueProp,\n defaultValue,\n onChange,\n 'calendarPlacement': calendarPlacementProp = 'bottom-start',\n style,\n className,\n doneButtonText,\n DoneButton,\n closeOnChange = true,\n disablePickers,\n getRootRef,\n name,\n autoFocus,\n disabled,\n accessible,\n calendarLabel = 'Календарь',\n prevMonthLabel = 'Предыдущий месяц',\n nextMonthLabel = 'Следующий месяц',\n changeDayLabel = 'День',\n changeMonthLabel = 'Месяц',\n changeYearLabel = 'Год',\n changeHoursLabel = 'Час',\n changeMinutesLabel = 'Минута',\n clearFieldLabel = 'Очистить поле',\n showCalendarLabel = 'Показать календарь',\n showNeighboringMonth,\n size,\n viewDate,\n onHeaderChange,\n onNextMonth,\n onPrevMonth,\n prevMonthIcon,\n nextMonthIcon,\n renderDayContent,\n onCalendarOpenChanged,\n calendarTestsProps,\n dayFieldTestId,\n monthFieldTestId,\n yearFieldTestId,\n hourFieldTestId,\n minuteFieldTestId,\n showCalendarButtonTestId,\n clearButtonTestId,\n id,\n onApply,\n renderCustomValue,\n timezone,\n restoreFocus,\n disableFocusTrap,\n readOnly,\n 'disableCalendar': disableCalendarProp = false,\n 'aria-label': ariaLabel = '',\n ...props\n}: DateInputProps): React.ReactNode => {\n const daysRef = React.useRef<HTMLSpanElement>(null);\n const monthsRef = React.useRef<HTMLSpanElement>(null);\n const yearsRef = React.useRef<HTMLSpanElement>(null);\n const hoursRef = React.useRef<HTMLSpanElement>(null);\n const minutesRef = React.useRef<HTMLSpanElement>(null);\n\n const disableCalendar = readOnly ? true : disableCalendarProp;\n\n const { value, updateValue, setInternalValue, getLastUpdatedValue, clearValue } =\n useDateInputValue({\n value: valueProp,\n defaultValue,\n onChange,\n timezone,\n });\n\n const maxElement = enableTime ? 4 : 2;\n\n const onInternalValueChange = React.useCallback(\n (internalValue: string[]) => {\n for (let i = 0; i <= maxElement; i += 1) {\n if (internalValue[i].length < elementsConfig(i).length) {\n return;\n }\n }\n\n let formattedValue = `${internalValue[0]}.${internalValue[1]}.${internalValue[2]}`;\n let mask = 'dd.MM.yyyy';\n if (enableTime) {\n formattedValue += ` ${internalValue[3]}:${internalValue[4]}`;\n mask += ' HH:mm';\n }\n\n if (isMatch(formattedValue, mask)) {\n const now = new Date();\n updateValue(\n parse(formattedValue, mask, value ?? (enableTime ? startOfMinute(now) : startOfDay(now))),\n );\n }\n },\n [enableTime, maxElement, updateValue, value],\n );\n\n const refs = React.useMemo(\n () => [daysRef, monthsRef, yearsRef, hoursRef, minutesRef],\n [daysRef, monthsRef, yearsRef, hoursRef, minutesRef],\n );\n\n const {\n rootRef,\n calendarRef,\n open,\n internalValue,\n handleKeyDown,\n setFocusedElement,\n handleFieldEnter,\n clear,\n removeFocusFromField,\n closeCalendar,\n toggleCalendar,\n openCalendar,\n handleRestoreFocus,\n } = useDateInput({\n maxElement,\n refs,\n autoFocus,\n disabled: disabled || readOnly,\n elementsConfig,\n onClear: clearValue,\n onInternalValueChange,\n getInternalValue,\n value,\n onCalendarOpenChanged,\n accessible,\n });\n\n const { sizeY = 'none' } = useAdaptivity();\n\n const handleRootRef = useExternRef(rootRef, getRootRef);\n\n useIsomorphicLayoutEffect(\n function resetValueOnCloseCalendar() {\n if (!open) {\n setInternalValue(getLastUpdatedValue());\n }\n },\n [open, getLastUpdatedValue],\n );\n\n const onCalendarChange = React.useCallback(\n (value?: Date | undefined) => {\n if (!value) {\n return;\n }\n if (enableTime) {\n setInternalValue(value);\n return;\n }\n updateValue(value);\n if (closeOnChange) {\n removeFocusFromField();\n }\n },\n [enableTime, updateValue, closeOnChange, setInternalValue, removeFocusFromField],\n );\n\n const onDoneButtonClick = React.useCallback(() => {\n if (!value) {\n return;\n }\n const newValue = updateValue(value);\n onApply?.(newValue);\n removeFocusFromField();\n }, [onApply, removeFocusFromField, updateValue, value]);\n\n const customValue = React.useMemo(\n () => !open && renderCustomValue?.(value || undefined),\n [open, renderCustomValue, value],\n );\n\n // при переключении месяцев высота календаря может меняться,\n // чтобы календарь не прыгал при переключении месяцев каждый раз на\n // лучшую позицию мы запоминаем последнюю удачную, чтобы календарь оставался\n // на ней, пока помещается.\n const [calendarPlacement, setCalendarPlacement] =\n React.useState<PlacementWithAuto>(calendarPlacementProp);\n\n const { locale } = useConfigProvider();\n const currentDateLabel = value\n ? new Intl.DateTimeFormat(locale, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n }).format(value)\n : null;\n const currentDateLabelId = React.useId();\n const ariaLabelId = React.useId();\n\n const showCalendarOnInputAreaClick = React.useCallback(() => {\n handleFieldEnter();\n if (accessible) {\n openCalendar();\n }\n }, [handleFieldEnter, openCalendar, accessible]);\n\n return (\n <FormField\n style={style}\n className={classNames(sizeY !== 'regular' && sizeYClassNames[sizeY], className)}\n getRootRef={handleRootRef}\n role=\"group\"\n aria-labelledby={`${ariaLabelId} ${currentDateLabelId}`}\n after={\n <React.Fragment>\n {!disableCalendar && (accessible || (!accessible && !value)) ? (\n <IconButton\n hoverMode=\"opacity\"\n label={showCalendarLabel}\n onClick={toggleCalendar}\n data-testid={showCalendarButtonTestId}\n >\n <Icon20CalendarOutline />\n </IconButton>\n ) : null}\n {value && !readOnly ? (\n <IconButton\n hoverMode=\"opacity\"\n label={clearFieldLabel}\n onClick={clear}\n data-testid={clearButtonTestId}\n >\n <Icon16Clear />\n </IconButton>\n ) : null}\n </React.Fragment>\n }\n disabled={disabled}\n {...props}\n >\n <div className={styles.wrapper}>\n {ariaLabel && <VisuallyHidden id={ariaLabelId}>{ariaLabel}</VisuallyHidden>}\n {currentDateLabel && (\n <VisuallyHidden id={currentDateLabelId}>{currentDateLabel}</VisuallyHidden>\n )}\n <VisuallyHidden\n id={id}\n Component=\"input\"\n readOnly\n aria-hidden\n tabIndex={readOnly ? 0 : -1}\n name={name}\n value={\n value\n ? enableTime\n ? dateTimeFormatter.format(value)\n : dateFormatter.format(value)\n : ''\n }\n onFocus={handleFieldEnter}\n />\n <Text\n className={classNames(styles.input, customValue && styles.hidden)}\n // Инцидент: в PR https://github.com/VKCOM/VKUI/pull/6649 стабильно ломается порядок стилей\n // из-за чего `.Typography--normalize` перебивает стили.\n normalize={false}\n Component=\"span\" // для <span> нормализация не нужна\n onClick={showCalendarOnInputAreaClick}\n >\n <NumberInputLike\n value={internalValue[0]}\n minValue={1}\n maxValue={31}\n length={2}\n getRootRef={daysRef}\n index={0}\n onKeyDown={handleKeyDown}\n onElementSelect={setFocusedElement}\n label={changeDayLabel}\n readOnly={readOnly}\n data-testid={dayFieldTestId}\n />\n <InputLikeDivider>.</InputLikeDivider>\n <NumberInputLike\n value={internalValue[1]}\n minValue={1}\n maxValue={12}\n length={2}\n getRootRef={monthsRef}\n index={1}\n onElementSelect={setFocusedElement}\n onKeyDown={handleKeyDown}\n readOnly={readOnly}\n label={changeMonthLabel}\n data-testid={monthFieldTestId}\n />\n <InputLikeDivider>.</InputLikeDivider>\n <NumberInputLike\n value={internalValue[2]}\n minValue={1}\n maxValue={275750}\n length={4}\n getRootRef={yearsRef}\n index={2}\n onElementSelect={setFocusedElement}\n readOnly={readOnly}\n label={changeYearLabel}\n onKeyDown={handleKeyDown}\n data-testid={yearFieldTestId}\n />\n {enableTime && (\n <React.Fragment>\n <InputLikeDivider className={styles.inputTimeDivider}> </InputLikeDivider>\n <NumberInputLike\n value={internalValue[3]}\n minValue={1}\n maxValue={24}\n length={2}\n getRootRef={hoursRef}\n index={3}\n onElementSelect={setFocusedElement}\n readOnly={readOnly}\n label={changeHoursLabel}\n onKeyDown={handleKeyDown}\n data-testid={hourFieldTestId}\n />\n <InputLikeDivider>:</InputLikeDivider>\n <NumberInputLike\n value={internalValue[4]}\n minValue={1}\n maxValue={59}\n length={2}\n getRootRef={minutesRef}\n index={4}\n onElementSelect={setFocusedElement}\n readOnly={readOnly}\n label={changeMinutesLabel}\n onKeyDown={handleKeyDown}\n data-testid={minuteFieldTestId}\n />\n </React.Fragment>\n )}\n </Text>\n {customValue && (\n <Text className={styles.customValue} aria-hidden normalize={false}>\n {customValue}\n </Text>\n )}\n </div>\n {open && !disableCalendar && (\n <Popper\n targetRef={rootRef}\n offsetByMainAxis={8}\n placement={calendarPlacement}\n onPlacementChange={setCalendarPlacement}\n autoUpdateOnTargetResize\n >\n <FocusTrap\n onClose={closeCalendar}\n disabled={disableFocusTrap ?? !accessible}\n restoreFocus={restoreFocus ?? (Boolean(accessible) && handleRestoreFocus)}\n captureEscapeKeyboardEvent={false}\n mutationObserverOptions={CALENDAR_MUTATION_OBSERVER_OPTIONS}\n >\n <Calendar\n aria-label={calendarLabel}\n role=\"dialog\"\n value={value}\n onChange={onCalendarChange}\n enableTime={enableTime}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n onDoneButtonClick={onDoneButtonClick}\n getRootRef={calendarRef}\n doneButtonText={doneButtonText}\n DoneButton={DoneButton}\n disablePickers={disablePickers}\n changeHoursLabel={changeHoursLabel}\n changeMinutesLabel={changeMinutesLabel}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n showNeighboringMonth={showNeighboringMonth}\n renderDayContent={renderDayContent}\n size={size}\n viewDate={viewDate}\n onHeaderChange={onHeaderChange}\n onNextMonth={onNextMonth}\n onPrevMonth={onPrevMonth}\n prevMonthIcon={prevMonthIcon}\n nextMonthIcon={nextMonthIcon}\n minDateTime={minDateTime}\n maxDateTime={maxDateTime}\n {...calendarTestsProps}\n />\n </FocusTrap>\n </Popper>\n )}\n </FormField>\n );\n};\n"],"names":["React","Icon16Clear","Icon20CalendarOutline","classNames","startOfDay","startOfMinute","useAdaptivity","useDateInput","useExternRef","dateFormatter","dateTimeFormatter","isMatch","parse","useIsomorphicLayoutEffect","Calendar","useConfigProvider","FocusTrap","FormField","IconButton","InputLikeDivider","NumberInputLike","Popper","Text","VisuallyHidden","useDateInputValue","styles","sizeYClassNames","none","sizeYNone","compact","sizeYCompact","elementsConfig","index","length","min","max","getInternalValue","value","newValue","String","getDate","padStart","getMonth","getFullYear","getHours","getMinutes","CALENDAR_MUTATION_OBSERVER_OPTIONS","childList","subtree","attributes","attributeFilter","DateInput","enableTime","shouldDisableDate","disableFuture","disablePast","minDateTime","maxDateTime","valueProp","defaultValue","onChange","calendarPlacementProp","style","className","doneButtonText","DoneButton","closeOnChange","disablePickers","getRootRef","name","autoFocus","disabled","accessible","calendarLabel","prevMonthLabel","nextMonthLabel","changeDayLabel","changeMonthLabel","changeYearLabel","changeHoursLabel","changeMinutesLabel","clearFieldLabel","showCalendarLabel","showNeighboringMonth","size","viewDate","onHeaderChange","onNextMonth","onPrevMonth","prevMonthIcon","nextMonthIcon","renderDayContent","onCalendarOpenChanged","calendarTestsProps","dayFieldTestId","monthFieldTestId","yearFieldTestId","hourFieldTestId","minuteFieldTestId","showCalendarButtonTestId","clearButtonTestId","id","onApply","renderCustomValue","timezone","restoreFocus","disableFocusTrap","readOnly","disableCalendarProp","ariaLabel","props","daysRef","useRef","monthsRef","yearsRef","hoursRef","minutesRef","disableCalendar","updateValue","setInternalValue","getLastUpdatedValue","clearValue","maxElement","onInternalValueChange","useCallback","internalValue","i","formattedValue","mask","now","Date","refs","useMemo","rootRef","calendarRef","open","handleKeyDown","setFocusedElement","handleFieldEnter","clear","removeFocusFromField","closeCalendar","toggleCalendar","openCalendar","handleRestoreFocus","onClear","sizeY","handleRootRef","resetValueOnCloseCalendar","onCalendarChange","onDoneButtonClick","customValue","undefined","calendarPlacement","setCalendarPlacement","useState","locale","currentDateLabel","Intl","DateTimeFormat","weekday","year","month","day","format","currentDateLabelId","useId","ariaLabelId","showCalendarOnInputAreaClick","role","aria-labelledby","after","Fragment","hoverMode","label","onClick","data-testid","div","wrapper","Component","aria-hidden","tabIndex","onFocus","input","hidden","normalize","minValue","maxValue","onKeyDown","onElementSelect","inputTimeDivider","targetRef","offsetByMainAxis","placement","onPlacementChange","autoUpdateOnTargetResize","onClose","Boolean","captureEscapeKeyboardEvent","mutationObserverOptions","aria-label"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/DateInput/DateInput.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon20CalendarOutline } from '@vkontakte/icons';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useDateInput } from '../../hooks/useDateInput';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { type UseFocusTrapProps } from '../../hooks/useFocusTrap';\nimport {\n dateFormatter,\n dateTimeFormatter,\n isMatch,\n parse,\n startOfDay,\n startOfMinute,\n} from '../../lib/date';\nimport type { PlacementWithAuto } from '../../lib/floating';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasRootRef } from '../../types';\nimport { Calendar, type CalendarProps, type CalendarTestsProps } from '../Calendar/Calendar';\nimport { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';\nimport { FocusTrap } from '../FocusTrap/FocusTrap';\nimport { FormField, type FormFieldProps } from '../FormField/FormField';\nimport { IconButton } from '../IconButton/IconButton';\nimport { InputLikeDivider } from '../InputLike/InputLikeDivider';\nimport { NumberInputLike } from '../NumberInputLike/NumberInputLike';\nimport { Popper } from '../Popper/Popper';\nimport { Text } from '../Typography/Text/Text';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport { useDateInputValue } from './hooks';\nimport '../InputLike/InputLike.module.css'; // Reorder css\nimport styles from './DateInput.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n};\n\nexport type DateInputPropsTestsProps = {\n /**\n * Передает атрибут `data-testid` для поля ввода дня.\n */\n dayFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода месяца.\n */\n monthFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода года.\n */\n yearFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода часа.\n */\n hourFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для поля ввода минут.\n */\n minuteFieldTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки показа календаря.\n */\n showCalendarButtonTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки даты.\n */\n clearButtonTestId?: string;\n};\n\nexport interface DateInputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLDivElement>,\n 'value' | 'defaultValue' | 'onChange' | 'size'\n >,\n Pick<\n CalendarProps,\n | 'disablePast'\n | 'disableFuture'\n | 'enableTime'\n | 'shouldDisableDate'\n | 'onChange'\n | 'value'\n | 'defaultValue'\n | 'doneButtonText'\n | 'DoneButton'\n | 'weekStartsOn'\n | 'disablePickers'\n | 'changeHoursLabel'\n | 'changeMinutesLabel'\n | 'prevMonthLabel'\n | 'nextMonthLabel'\n | 'changeMonthLabel'\n | 'changeYearLabel'\n | 'showNeighboringMonth'\n | 'size'\n | 'viewDate'\n | 'onHeaderChange'\n | 'onNextMonth'\n | 'onPrevMonth'\n | 'prevMonthIcon'\n | 'nextMonthIcon'\n | 'minDateTime'\n | 'maxDateTime'\n | 'renderDayContent'\n >,\n Pick<UseFocusTrapProps, 'restoreFocus'>,\n HasRootRef<HTMLDivElement>,\n Omit<FormFieldProps, 'maxHeight'>,\n DateInputPropsTestsProps {\n /**\n * Передает атрибуты `data-testid` для интерактивных элементов в календаре.\n */\n calendarTestsProps?: CalendarTestsProps;\n /**\n * Расположение календаря относительно поля ввода.\n */\n calendarPlacement?: PlacementWithAuto;\n /**\n * Автоматически закрывать календарь при изменениях.\n */\n closeOnChange?: boolean;\n /**\n * `aria-label` для календаря.\n */\n calendarLabel?: string;\n /**\n * Label для кнопки очистки. Делает доступным для ассистивных технологий.\n */\n clearFieldLabel?: string;\n /**\n * Label для кнопки открытия календаря. Делает доступным для ассистивных технологий.\n */\n showCalendarLabel?: string;\n /**\n * Отключение открытия календаря.\n */\n disableCalendar?: boolean;\n /**\n * Обработчик изменения состояния открытия календаря.\n */\n onCalendarOpenChanged?: (opened: boolean) => void;\n /**\n * `aria-label` для поля изменения дня.\n */\n changeDayLabel?: string;\n /**\n * Обработчик нажатия на кнопку `\"Done\"`. Используется совместно с флагом `enableTime`.\n */\n onApply?: (value?: Date) => void;\n /**\n * Функция для кастомного форматирования отображаемого значения даты.\n * Позволяет переопределить стандартное отображение даты и вернуть собственное представление.\n */\n renderCustomValue?: (date: Date | undefined) => React.ReactNode;\n /**\n * Часовой пояс для отображения даты.\n */\n timezone?: string;\n /**\n * Включает режим в котором DateInput доступен\n * для ассистивных технологий.\n * В этом режиме:\n * - календарь больше не открывает при фокусе на DateInput;\n * - иконка календаря видна всегда, чтобы пользователи\n * ассистивных технологий могли открыть календарь по клику на иконку;\n * - календарь при открытии получает фокус, клавиатурный\n * фокус зациклен и не выходит за пределы календаря пока календарь не закрыт.\n */\n accessible?: boolean /* TODO [>=v8] включить по умолчанию */;\n /**\n * Позволяет отключить захват фокуса при появлении календаря.\n */\n disableFocusTrap?: UseFocusTrapProps['disabled'];\n}\n\nconst elementsConfig = (index: number) => {\n let length = 2;\n let min = 1;\n let max = 0;\n\n switch (index) {\n case 0:\n max = 31;\n break;\n case 1:\n max = 12;\n break;\n case 2:\n max = 2100;\n min = 1900;\n length = 4;\n break;\n case 3:\n max = 23;\n break;\n case 4:\n max = 59;\n break;\n }\n\n return { length, min, max };\n};\n\nconst getInternalValue = (value: CalendarProps['value']) => {\n const newValue = ['', '', '', '', ''];\n if (value) {\n newValue[0] = String(value.getDate()).padStart(2, '0');\n newValue[1] = String(value.getMonth() + 1).padStart(2, '0');\n newValue[2] = String(value.getFullYear()).padStart(4, '0');\n newValue[3] = String(value.getHours()).padStart(2, '0');\n newValue[4] = String(value.getMinutes()).padStart(2, '0');\n }\n return newValue;\n};\n\nconst CALENDAR_MUTATION_OBSERVER_OPTIONS: MutationObserverInit = {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['tabindex'],\n};\n\n/**\n * @see https://vkui.io/components/date-input\n */\nexport const DateInput = ({\n enableTime,\n shouldDisableDate,\n disableFuture,\n disablePast,\n minDateTime,\n maxDateTime,\n 'value': valueProp,\n defaultValue,\n onChange,\n 'calendarPlacement': calendarPlacementProp = 'bottom-start',\n style,\n className,\n doneButtonText,\n DoneButton,\n closeOnChange = true,\n disablePickers,\n getRootRef,\n name,\n autoFocus,\n disabled,\n accessible,\n calendarLabel = 'Календарь',\n prevMonthLabel = 'Предыдущий месяц',\n nextMonthLabel = 'Следующий месяц',\n changeDayLabel = 'День',\n changeMonthLabel = 'Месяц',\n changeYearLabel = 'Год',\n changeHoursLabel = 'Час',\n changeMinutesLabel = 'Минута',\n clearFieldLabel = 'Очистить поле',\n showCalendarLabel = 'Показать календарь',\n showNeighboringMonth,\n size,\n viewDate,\n onHeaderChange,\n onNextMonth,\n onPrevMonth,\n prevMonthIcon,\n nextMonthIcon,\n renderDayContent,\n onCalendarOpenChanged,\n calendarTestsProps,\n dayFieldTestId,\n monthFieldTestId,\n yearFieldTestId,\n hourFieldTestId,\n minuteFieldTestId,\n showCalendarButtonTestId,\n clearButtonTestId,\n id,\n onApply,\n renderCustomValue,\n timezone,\n restoreFocus,\n disableFocusTrap,\n readOnly,\n 'disableCalendar': disableCalendarProp = false,\n 'aria-label': ariaLabel = '',\n ...props\n}: DateInputProps): React.ReactNode => {\n const daysRef = React.useRef<HTMLSpanElement>(null);\n const monthsRef = React.useRef<HTMLSpanElement>(null);\n const yearsRef = React.useRef<HTMLSpanElement>(null);\n const hoursRef = React.useRef<HTMLSpanElement>(null);\n const minutesRef = React.useRef<HTMLSpanElement>(null);\n\n const disableCalendar = readOnly ? true : disableCalendarProp;\n\n const { value, updateValue, setInternalValue, getLastUpdatedValue, clearValue } =\n useDateInputValue({\n value: valueProp,\n defaultValue,\n onChange,\n timezone,\n });\n\n const maxElement = enableTime ? 4 : 2;\n\n const onInternalValueChange = React.useCallback(\n (internalValue: string[]) => {\n for (let i = 0; i <= maxElement; i += 1) {\n if (internalValue[i].length < elementsConfig(i).length) {\n return;\n }\n }\n\n let formattedValue = `${internalValue[0]}.${internalValue[1]}.${internalValue[2]}`;\n let mask = 'dd.MM.yyyy';\n if (enableTime) {\n formattedValue += ` ${internalValue[3]}:${internalValue[4]}`;\n mask += ' HH:mm';\n }\n\n if (isMatch(formattedValue, mask)) {\n const now = new Date();\n updateValue(\n parse(formattedValue, mask, value ?? (enableTime ? startOfMinute(now) : startOfDay(now))),\n );\n }\n },\n [enableTime, maxElement, updateValue, value],\n );\n\n const refs = React.useMemo(\n () => [daysRef, monthsRef, yearsRef, hoursRef, minutesRef],\n [daysRef, monthsRef, yearsRef, hoursRef, minutesRef],\n );\n\n const {\n rootRef,\n calendarRef,\n open,\n internalValue,\n handleKeyDown,\n setFocusedElement,\n handleFieldEnter,\n clear,\n removeFocusFromField,\n closeCalendar,\n toggleCalendar,\n openCalendar,\n handleRestoreFocus,\n } = useDateInput({\n maxElement,\n refs,\n autoFocus,\n disabled: disabled || readOnly,\n elementsConfig,\n onClear: clearValue,\n onInternalValueChange,\n getInternalValue,\n value,\n onCalendarOpenChanged,\n accessible,\n });\n\n const { sizeY = 'none' } = useAdaptivity();\n\n const handleRootRef = useExternRef(rootRef, getRootRef);\n\n useIsomorphicLayoutEffect(\n function resetValueOnCloseCalendar() {\n if (!open) {\n setInternalValue(getLastUpdatedValue());\n }\n },\n [open, getLastUpdatedValue],\n );\n\n const onCalendarChange = React.useCallback(\n (value?: Date | undefined) => {\n if (!value) {\n return;\n }\n if (enableTime) {\n setInternalValue(value);\n return;\n }\n updateValue(value);\n if (closeOnChange) {\n removeFocusFromField();\n }\n },\n [enableTime, updateValue, closeOnChange, setInternalValue, removeFocusFromField],\n );\n\n const onDoneButtonClick = React.useCallback(() => {\n if (!value) {\n return;\n }\n const newValue = updateValue(value);\n onApply?.(newValue);\n removeFocusFromField();\n }, [onApply, removeFocusFromField, updateValue, value]);\n\n const customValue = React.useMemo(\n () => !open && renderCustomValue?.(value || undefined),\n [open, renderCustomValue, value],\n );\n\n // при переключении месяцев высота календаря может меняться,\n // чтобы календарь не прыгал при переключении месяцев каждый раз на\n // лучшую позицию мы запоминаем последнюю удачную, чтобы календарь оставался\n // на ней, пока помещается.\n const [calendarPlacement, setCalendarPlacement] =\n React.useState<PlacementWithAuto>(calendarPlacementProp);\n\n const { locale } = useConfigProvider();\n const currentDateLabel = value\n ? new Intl.DateTimeFormat(locale, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n }).format(value)\n : null;\n const currentDateLabelId = React.useId();\n const ariaLabelId = React.useId();\n\n const showCalendarOnInputAreaClick = React.useCallback(() => {\n handleFieldEnter();\n if (accessible) {\n openCalendar();\n }\n }, [handleFieldEnter, openCalendar, accessible]);\n\n return (\n <FormField\n style={style}\n className={classNames(sizeY !== 'regular' && sizeYClassNames[sizeY], className)}\n getRootRef={handleRootRef}\n role=\"group\"\n aria-labelledby={`${ariaLabelId} ${currentDateLabelId}`}\n after={\n <React.Fragment>\n {!disableCalendar && (accessible || (!accessible && !value)) ? (\n <IconButton\n hoverMode=\"opacity\"\n label={showCalendarLabel}\n onClick={toggleCalendar}\n data-testid={showCalendarButtonTestId}\n >\n <Icon20CalendarOutline />\n </IconButton>\n ) : null}\n {value && !readOnly ? (\n <IconButton\n hoverMode=\"opacity\"\n label={clearFieldLabel}\n onClick={clear}\n data-testid={clearButtonTestId}\n >\n <Icon16Clear />\n </IconButton>\n ) : null}\n </React.Fragment>\n }\n disabled={disabled}\n {...props}\n >\n <div className={styles.wrapper}>\n {ariaLabel && <VisuallyHidden id={ariaLabelId}>{ariaLabel}</VisuallyHidden>}\n {currentDateLabel && (\n <VisuallyHidden id={currentDateLabelId}>{currentDateLabel}</VisuallyHidden>\n )}\n <VisuallyHidden\n id={id}\n Component=\"input\"\n readOnly\n aria-hidden\n tabIndex={readOnly ? 0 : -1}\n name={name}\n value={\n value\n ? enableTime\n ? dateTimeFormatter.format(value)\n : dateFormatter.format(value)\n : ''\n }\n onFocus={handleFieldEnter}\n />\n <Text\n className={classNames(styles.input, customValue && styles.hidden)}\n // Инцидент: в PR https://github.com/VKCOM/VKUI/pull/6649 стабильно ломается порядок стилей\n // из-за чего `.Typography--normalize` перебивает стили.\n normalize={false}\n Component=\"span\" // для <span> нормализация не нужна\n onClick={showCalendarOnInputAreaClick}\n >\n <NumberInputLike\n value={internalValue[0]}\n minValue={1}\n maxValue={31}\n length={2}\n getRootRef={daysRef}\n index={0}\n onKeyDown={handleKeyDown}\n onElementSelect={setFocusedElement}\n label={changeDayLabel}\n readOnly={readOnly}\n data-testid={dayFieldTestId}\n />\n <InputLikeDivider>.</InputLikeDivider>\n <NumberInputLike\n value={internalValue[1]}\n minValue={1}\n maxValue={12}\n length={2}\n getRootRef={monthsRef}\n index={1}\n onElementSelect={setFocusedElement}\n onKeyDown={handleKeyDown}\n readOnly={readOnly}\n label={changeMonthLabel}\n data-testid={monthFieldTestId}\n />\n <InputLikeDivider>.</InputLikeDivider>\n <NumberInputLike\n value={internalValue[2]}\n minValue={1}\n maxValue={275750}\n length={4}\n getRootRef={yearsRef}\n index={2}\n onElementSelect={setFocusedElement}\n readOnly={readOnly}\n label={changeYearLabel}\n onKeyDown={handleKeyDown}\n data-testid={yearFieldTestId}\n />\n {enableTime && (\n <React.Fragment>\n <InputLikeDivider className={styles.inputTimeDivider}> </InputLikeDivider>\n <NumberInputLike\n value={internalValue[3]}\n minValue={1}\n maxValue={24}\n length={2}\n getRootRef={hoursRef}\n index={3}\n onElementSelect={setFocusedElement}\n readOnly={readOnly}\n label={changeHoursLabel}\n onKeyDown={handleKeyDown}\n data-testid={hourFieldTestId}\n />\n <InputLikeDivider>:</InputLikeDivider>\n <NumberInputLike\n value={internalValue[4]}\n minValue={1}\n maxValue={59}\n length={2}\n getRootRef={minutesRef}\n index={4}\n onElementSelect={setFocusedElement}\n readOnly={readOnly}\n label={changeMinutesLabel}\n onKeyDown={handleKeyDown}\n data-testid={minuteFieldTestId}\n />\n </React.Fragment>\n )}\n </Text>\n {customValue && (\n <Text className={styles.customValue} aria-hidden normalize={false}>\n {customValue}\n </Text>\n )}\n </div>\n {open && !disableCalendar && (\n <Popper\n targetRef={rootRef}\n offsetByMainAxis={8}\n placement={calendarPlacement}\n onPlacementChange={setCalendarPlacement}\n autoUpdateOnTargetResize\n >\n <FocusTrap\n onClose={closeCalendar}\n disabled={disableFocusTrap ?? !accessible}\n restoreFocus={restoreFocus ?? (Boolean(accessible) && handleRestoreFocus)}\n captureEscapeKeyboardEvent={false}\n mutationObserverOptions={CALENDAR_MUTATION_OBSERVER_OPTIONS}\n >\n <Calendar\n aria-label={calendarLabel}\n role=\"dialog\"\n value={value}\n onChange={onCalendarChange}\n enableTime={enableTime}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n onDoneButtonClick={onDoneButtonClick}\n getRootRef={calendarRef}\n doneButtonText={doneButtonText}\n DoneButton={DoneButton}\n disablePickers={disablePickers}\n changeHoursLabel={changeHoursLabel}\n changeMinutesLabel={changeMinutesLabel}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n showNeighboringMonth={showNeighboringMonth}\n renderDayContent={renderDayContent}\n size={size}\n viewDate={viewDate}\n onHeaderChange={onHeaderChange}\n onNextMonth={onNextMonth}\n onPrevMonth={onPrevMonth}\n prevMonthIcon={prevMonthIcon}\n nextMonthIcon={nextMonthIcon}\n minDateTime={minDateTime}\n maxDateTime={maxDateTime}\n {...calendarTestsProps}\n />\n </FocusTrap>\n </Popper>\n )}\n </FormField>\n );\n};\n"],"names":["React","Icon16Clear","Icon20CalendarOutline","classNames","useAdaptivity","useDateInput","useExternRef","dateFormatter","dateTimeFormatter","isMatch","parse","startOfDay","startOfMinute","useIsomorphicLayoutEffect","Calendar","useConfigProvider","FocusTrap","FormField","IconButton","InputLikeDivider","NumberInputLike","Popper","Text","VisuallyHidden","useDateInputValue","styles","sizeYClassNames","none","sizeYNone","compact","sizeYCompact","elementsConfig","index","length","min","max","getInternalValue","value","newValue","String","getDate","padStart","getMonth","getFullYear","getHours","getMinutes","CALENDAR_MUTATION_OBSERVER_OPTIONS","childList","subtree","attributes","attributeFilter","DateInput","enableTime","shouldDisableDate","disableFuture","disablePast","minDateTime","maxDateTime","valueProp","defaultValue","onChange","calendarPlacementProp","style","className","doneButtonText","DoneButton","closeOnChange","disablePickers","getRootRef","name","autoFocus","disabled","accessible","calendarLabel","prevMonthLabel","nextMonthLabel","changeDayLabel","changeMonthLabel","changeYearLabel","changeHoursLabel","changeMinutesLabel","clearFieldLabel","showCalendarLabel","showNeighboringMonth","size","viewDate","onHeaderChange","onNextMonth","onPrevMonth","prevMonthIcon","nextMonthIcon","renderDayContent","onCalendarOpenChanged","calendarTestsProps","dayFieldTestId","monthFieldTestId","yearFieldTestId","hourFieldTestId","minuteFieldTestId","showCalendarButtonTestId","clearButtonTestId","id","onApply","renderCustomValue","timezone","restoreFocus","disableFocusTrap","readOnly","disableCalendarProp","ariaLabel","props","daysRef","useRef","monthsRef","yearsRef","hoursRef","minutesRef","disableCalendar","updateValue","setInternalValue","getLastUpdatedValue","clearValue","maxElement","onInternalValueChange","useCallback","internalValue","i","formattedValue","mask","now","Date","refs","useMemo","rootRef","calendarRef","open","handleKeyDown","setFocusedElement","handleFieldEnter","clear","removeFocusFromField","closeCalendar","toggleCalendar","openCalendar","handleRestoreFocus","onClear","sizeY","handleRootRef","resetValueOnCloseCalendar","onCalendarChange","onDoneButtonClick","customValue","undefined","calendarPlacement","setCalendarPlacement","useState","locale","currentDateLabel","Intl","DateTimeFormat","weekday","year","month","day","format","currentDateLabelId","useId","ariaLabelId","showCalendarOnInputAreaClick","role","aria-labelledby","after","Fragment","hoverMode","label","onClick","data-testid","div","wrapper","Component","aria-hidden","tabIndex","onFocus","input","hidden","normalize","minValue","maxValue","onKeyDown","onElementSelect","inputTimeDivider","targetRef","offsetByMainAxis","placement","onPlacementChange","autoUpdateOnTargetResize","onClose","Boolean","captureEscapeKeyboardEvent","mutationObserverOptions","aria-label"],"mappings":"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"}
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { clamp } from "../../helpers/math.js";
|
|
5
|
+
import { useExternRef } from "../../hooks/useExternRef.js";
|
|
6
|
+
import { useFocusWithin } from "../../hooks/useFocusWithin.js";
|
|
5
7
|
import { useIsClient } from "../../hooks/useIsClient.js";
|
|
6
8
|
import { callMultiple } from "../../lib/callMultiple.js";
|
|
9
|
+
import { useIsomorphicLayoutEffect } from "../../lib/useIsomorphicLayoutEffect.js";
|
|
7
10
|
import { CarouselBase } from "../CarouselBase/CarouselBase.js";
|
|
8
11
|
import { useAutoPlay } from "./hooks.js";
|
|
9
12
|
/**
|
|
10
13
|
* @see https://vkui.io/components/gallery
|
|
11
|
-
*/ export const Gallery = ({ initialSlideIndex = 0, children, timeout = 0, onChange, bullets, onDragStart, onDragEnd, ...props })=>{
|
|
14
|
+
*/ export const Gallery = ({ initialSlideIndex = 0, children, timeout = 0, onChange, bullets, onDragStart, onDragEnd, getRootRef, onMouseOver, onMouseOut, ...props })=>{
|
|
15
|
+
const rootRef = useExternRef(getRootRef);
|
|
12
16
|
const [localSlideIndex, setSlideIndex] = React.useState(initialSlideIndex);
|
|
13
17
|
const isControlled = typeof props.slideIndex === 'number';
|
|
14
18
|
const slideIndex = isControlled ? props.slideIndex ?? 0 : localSlideIndex;
|
|
@@ -17,6 +21,7 @@ import { useAutoPlay } from "./hooks.js";
|
|
|
17
21
|
]);
|
|
18
22
|
const childCount = slides.length;
|
|
19
23
|
const isClient = useIsClient();
|
|
24
|
+
const focusWithin = useFocusWithin(rootRef);
|
|
20
25
|
const handleChange = React.useCallback((current)=>{
|
|
21
26
|
if (current === slideIndex) {
|
|
22
27
|
return;
|
|
@@ -47,14 +52,22 @@ import { useAutoPlay } from "./hooks.js";
|
|
|
47
52
|
safeSlideIndex,
|
|
48
53
|
slideIndex
|
|
49
54
|
]);
|
|
55
|
+
useIsomorphicLayoutEffect(()=>focusWithin ? autoPlayControls.pause() : autoPlayControls.resume(), [
|
|
56
|
+
focusWithin,
|
|
57
|
+
autoPlayControls.pause,
|
|
58
|
+
autoPlayControls.resume
|
|
59
|
+
]);
|
|
50
60
|
if (!isClient) {
|
|
51
61
|
return null;
|
|
52
62
|
}
|
|
53
63
|
return /*#__PURE__*/ _jsx(CarouselBase, {
|
|
54
64
|
dragDisabled: isControlled && !onChange,
|
|
65
|
+
getRootRef: rootRef,
|
|
55
66
|
...props,
|
|
56
67
|
onDragStart: callMultiple(onDragStart, autoPlayControls.pause),
|
|
57
68
|
onDragEnd: callMultiple(onDragEnd, autoPlayControls.resume),
|
|
69
|
+
onMouseEnter: callMultiple(onMouseOver, autoPlayControls.pause),
|
|
70
|
+
onMouseLeave: callMultiple(onMouseOut, autoPlayControls.resume),
|
|
58
71
|
bullets: childCount > 0 && bullets,
|
|
59
72
|
slideIndex: safeSlideIndex,
|
|
60
73
|
onChange: handleChange,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Gallery/Gallery.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { clamp } from '../../helpers/math';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { CarouselBase } from '../CarouselBase/CarouselBase';\nimport type { BaseGalleryProps } from '../CarouselBase/types';\nimport { useAutoPlay } from './hooks';\n\nexport interface GalleryProps extends BaseGalleryProps {\n /**\n * Индекс слайда по умолчанию.\n */\n initialSlideIndex?: number;\n /**\n * При передаче происходит автоматический переход к следующему слайду через переданное время в ms.\n */\n timeout?: number;\n}\n\n/**\n * @see https://vkui.io/components/gallery\n */\nexport const Gallery = ({\n initialSlideIndex = 0,\n children,\n timeout = 0,\n onChange,\n bullets,\n onDragStart,\n onDragEnd,\n ...props\n}: GalleryProps): React.ReactNode => {\n const [localSlideIndex, setSlideIndex] = React.useState(initialSlideIndex);\n const isControlled = typeof props.slideIndex === 'number';\n const slideIndex = isControlled ? (props.slideIndex ?? 0) : localSlideIndex;\n const slides = React.useMemo(\n () => React.Children.toArray(children).filter((item) => Boolean(item)),\n [children],\n );\n const childCount = slides.length;\n const isClient = useIsClient();\n\n const handleChange: GalleryProps['onChange'] = React.useCallback(\n (current: number) => {\n if (current === slideIndex) {\n return;\n }\n !isControlled && setSlideIndex(current);\n onChange && onChange(current);\n },\n [isControlled, onChange, slideIndex],\n );\n\n const autoPlayControls = useAutoPlay({\n timeout,\n slideIndex,\n onNext: () => handleChange((slideIndex + 1) % childCount),\n });\n\n // prevent invalid slideIndex\n // any slide index is invalid with no slides, just keep it as is\n const safeSlideIndex = childCount > 0 ? clamp(slideIndex, 0, childCount - 1) : slideIndex;\n // notify parent in controlled mode\n React.useEffect(() => {\n if (onChange && safeSlideIndex !== slideIndex) {\n onChange(safeSlideIndex);\n }\n setSlideIndex(safeSlideIndex);\n }, [onChange, safeSlideIndex, slideIndex]);\n\n if (!isClient) {\n return null;\n }\n\n return (\n <CarouselBase\n dragDisabled={isControlled && !onChange}\n {...props}\n onDragStart={callMultiple(onDragStart, autoPlayControls.pause)}\n onDragEnd={callMultiple(onDragEnd, autoPlayControls.resume)}\n bullets={childCount > 0 && bullets}\n slideIndex={safeSlideIndex}\n onChange={handleChange}\n >\n {slides}\n </CarouselBase>\n );\n};\n"],"names":["React","clamp","useIsClient","callMultiple","CarouselBase","useAutoPlay","Gallery","initialSlideIndex","children","timeout","onChange","bullets","onDragStart","onDragEnd","props","localSlideIndex","setSlideIndex","useState","isControlled","slideIndex","slides","useMemo","Children","toArray","filter","item","Boolean","childCount","length","isClient","handleChange","useCallback","current","autoPlayControls","onNext","safeSlideIndex","useEffect","dragDisabled","
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Gallery/Gallery.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { clamp } from '../../helpers/math';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusWithin } from '../../hooks/useFocusWithin';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { CarouselBase } from '../CarouselBase/CarouselBase';\nimport type { BaseGalleryProps } from '../CarouselBase/types';\nimport { useAutoPlay } from './hooks';\n\nexport interface GalleryProps extends BaseGalleryProps {\n /**\n * Индекс слайда по умолчанию.\n */\n initialSlideIndex?: number;\n /**\n * При передаче происходит автоматический переход к следующему слайду через переданное время в ms.\n * Автоматический переход будет ставиться на паузу при:\n * - начале свайпа для переключения слайда;\n * - фокусе на любой элемент внутри компонента;\n * - при наведении мыши на компонент.\n */\n timeout?: number;\n}\n\n/**\n * @see https://vkui.io/components/gallery\n */\nexport const Gallery = ({\n initialSlideIndex = 0,\n children,\n timeout = 0,\n onChange,\n bullets,\n onDragStart,\n onDragEnd,\n getRootRef,\n onMouseOver,\n onMouseOut,\n ...props\n}: GalleryProps): React.ReactNode => {\n const rootRef = useExternRef(getRootRef);\n const [localSlideIndex, setSlideIndex] = React.useState(initialSlideIndex);\n const isControlled = typeof props.slideIndex === 'number';\n const slideIndex = isControlled ? (props.slideIndex ?? 0) : localSlideIndex;\n const slides = React.useMemo(\n () => React.Children.toArray(children).filter((item) => Boolean(item)),\n [children],\n );\n const childCount = slides.length;\n const isClient = useIsClient();\n const focusWithin = useFocusWithin(rootRef);\n\n const handleChange: GalleryProps['onChange'] = React.useCallback(\n (current: number) => {\n if (current === slideIndex) {\n return;\n }\n !isControlled && setSlideIndex(current);\n onChange && onChange(current);\n },\n [isControlled, onChange, slideIndex],\n );\n\n const autoPlayControls = useAutoPlay({\n timeout,\n slideIndex,\n onNext: () => handleChange((slideIndex + 1) % childCount),\n });\n\n // prevent invalid slideIndex\n // any slide index is invalid with no slides, just keep it as is\n const safeSlideIndex = childCount > 0 ? clamp(slideIndex, 0, childCount - 1) : slideIndex;\n // notify parent in controlled mode\n React.useEffect(() => {\n if (onChange && safeSlideIndex !== slideIndex) {\n onChange(safeSlideIndex);\n }\n setSlideIndex(safeSlideIndex);\n }, [onChange, safeSlideIndex, slideIndex]);\n\n useIsomorphicLayoutEffect(\n () => (focusWithin ? autoPlayControls.pause() : autoPlayControls.resume()),\n [focusWithin, autoPlayControls.pause, autoPlayControls.resume],\n );\n\n if (!isClient) {\n return null;\n }\n\n return (\n <CarouselBase\n dragDisabled={isControlled && !onChange}\n getRootRef={rootRef}\n {...props}\n onDragStart={callMultiple(onDragStart, autoPlayControls.pause)}\n onDragEnd={callMultiple(onDragEnd, autoPlayControls.resume)}\n onMouseEnter={callMultiple(onMouseOver, autoPlayControls.pause)}\n onMouseLeave={callMultiple(onMouseOut, autoPlayControls.resume)}\n bullets={childCount > 0 && bullets}\n slideIndex={safeSlideIndex}\n onChange={handleChange}\n >\n {slides}\n </CarouselBase>\n );\n};\n"],"names":["React","clamp","useExternRef","useFocusWithin","useIsClient","callMultiple","useIsomorphicLayoutEffect","CarouselBase","useAutoPlay","Gallery","initialSlideIndex","children","timeout","onChange","bullets","onDragStart","onDragEnd","getRootRef","onMouseOver","onMouseOut","props","rootRef","localSlideIndex","setSlideIndex","useState","isControlled","slideIndex","slides","useMemo","Children","toArray","filter","item","Boolean","childCount","length","isClient","focusWithin","handleChange","useCallback","current","autoPlayControls","onNext","safeSlideIndex","useEffect","pause","resume","dragDisabled","onMouseEnter","onMouseLeave"],"mappings":"AAAA;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,KAAK,QAAQ,wBAAqB;AAC3C,SAASC,YAAY,QAAQ,8BAA2B;AACxD,SAASC,cAAc,QAAQ,gCAA6B;AAC5D,SAASC,WAAW,QAAQ,6BAA0B;AACtD,SAASC,YAAY,QAAQ,4BAAyB;AACtD,SAASC,yBAAyB,QAAQ,yCAAsC;AAChF,SAASC,YAAY,QAAQ,kCAA+B;AAE5D,SAASC,WAAW,QAAQ,aAAU;AAiBtC;;CAEC,GACD,OAAO,MAAMC,UAAU,CAAC,EACtBC,oBAAoB,CAAC,EACrBC,QAAQ,EACRC,UAAU,CAAC,EACXC,QAAQ,EACRC,OAAO,EACPC,WAAW,EACXC,SAAS,EACTC,UAAU,EACVC,WAAW,EACXC,UAAU,EACV,GAAGC,OACU;IACb,MAAMC,UAAUnB,aAAae;IAC7B,MAAM,CAACK,iBAAiBC,cAAc,GAAGvB,MAAMwB,QAAQ,CAACd;IACxD,MAAMe,eAAe,OAAOL,MAAMM,UAAU,KAAK;IACjD,MAAMA,aAAaD,eAAgBL,MAAMM,UAAU,IAAI,IAAKJ;IAC5D,MAAMK,SAAS3B,MAAM4B,OAAO,CAC1B,IAAM5B,MAAM6B,QAAQ,CAACC,OAAO,CAACnB,UAAUoB,MAAM,CAAC,CAACC,OAASC,QAAQD,QAChE;QAACrB;KAAS;IAEZ,MAAMuB,aAAaP,OAAOQ,MAAM;IAChC,MAAMC,WAAWhC;IACjB,MAAMiC,cAAclC,eAAekB;IAEnC,MAAMiB,eAAyCtC,MAAMuC,WAAW,CAC9D,CAACC;QACC,IAAIA,YAAYd,YAAY;YAC1B;QACF;QACA,CAACD,gBAAgBF,cAAciB;QAC/B3B,YAAYA,SAAS2B;IACvB,GACA;QAACf;QAAcZ;QAAUa;KAAW;IAGtC,MAAMe,mBAAmBjC,YAAY;QACnCI;QACAc;QACAgB,QAAQ,IAAMJ,aAAa,AAACZ,CAAAA,aAAa,CAAA,IAAKQ;IAChD;IAEA,6BAA6B;IAC7B,gEAAgE;IAChE,MAAMS,iBAAiBT,aAAa,IAAIjC,MAAMyB,YAAY,GAAGQ,aAAa,KAAKR;IAC/E,mCAAmC;IACnC1B,MAAM4C,SAAS,CAAC;QACd,IAAI/B,YAAY8B,mBAAmBjB,YAAY;YAC7Cb,SAAS8B;QACX;QACApB,cAAcoB;IAChB,GAAG;QAAC9B;QAAU8B;QAAgBjB;KAAW;IAEzCpB,0BACE,IAAO+B,cAAcI,iBAAiBI,KAAK,KAAKJ,iBAAiBK,MAAM,IACvE;QAACT;QAAaI,iBAAiBI,KAAK;QAAEJ,iBAAiBK,MAAM;KAAC;IAGhE,IAAI,CAACV,UAAU;QACb,OAAO;IACT;IAEA,qBACE,KAAC7B;QACCwC,cAActB,gBAAgB,CAACZ;QAC/BI,YAAYI;QACX,GAAGD,KAAK;QACTL,aAAaV,aAAaU,aAAa0B,iBAAiBI,KAAK;QAC7D7B,WAAWX,aAAaW,WAAWyB,iBAAiBK,MAAM;QAC1DE,cAAc3C,aAAaa,aAAauB,iBAAiBI,KAAK;QAC9DI,cAAc5C,aAAac,YAAYsB,iBAAiBK,MAAM;QAC9DhC,SAASoB,aAAa,KAAKpB;QAC3BY,YAAYiB;QACZ9B,UAAUyB;kBAETX;;AAGP,EAAE"}
|
|
@@ -33,21 +33,14 @@
|
|
|
33
33
|
/* Desktop */
|
|
34
34
|
|
|
35
35
|
.hostDesktop {
|
|
36
|
-
--vkui_internal_ModalPage--desktopStretchedSize: calc(100% - var(--vkui--spacing_size_2xl) * 2);
|
|
37
36
|
--vkui_internal_ModalPage--desktopMaxWidth: 100%;
|
|
38
37
|
--vkui_internal_ModalPage--desktopMaxHeight: 640px;
|
|
39
38
|
--vkui_internal_ModalPage--userHeight: auto;
|
|
40
39
|
|
|
41
40
|
position: relative;
|
|
42
41
|
box-sizing: content-box;
|
|
43
|
-
max-inline-size:
|
|
44
|
-
|
|
45
|
-
var(--vkui_internal_ModalPage--desktopStretchedSize)
|
|
46
|
-
);
|
|
47
|
-
max-block-size: min(
|
|
48
|
-
var(--vkui_internal_ModalPage--desktopMaxHeight),
|
|
49
|
-
var(--vkui_internal_ModalPage--desktopStretchedSize)
|
|
50
|
-
);
|
|
42
|
+
max-inline-size: var(--vkui_internal_ModalPage--desktopMaxWidth);
|
|
43
|
+
max-block-size: min(var(--vkui_internal_ModalPage--desktopMaxHeight), 100%);
|
|
51
44
|
margin-block: auto;
|
|
52
45
|
}
|
|
53
46
|
|
|
@@ -64,7 +64,10 @@ const transitionStateClassNames = {
|
|
|
64
64
|
} : initialStyle;
|
|
65
65
|
const handleSheetRef = useExternRef(setSheetEl, ref);
|
|
66
66
|
const handleSheetScrollRef = useExternRef(setSheetScrollEl, getModalContentRef);
|
|
67
|
-
const [desktopMaxWidthClassName, desktopMaxWidthStyle] =
|
|
67
|
+
const [desktopMaxWidthClassName, desktopMaxWidthStyle] = isDesktop ? resolveDesktopMaxWidth(desktopMaxWidth) : [
|
|
68
|
+
undefined,
|
|
69
|
+
undefined
|
|
70
|
+
];
|
|
68
71
|
const modalOverlay = !disableModalOverlay && /*#__PURE__*/ _jsx(ModalOverlay, {
|
|
69
72
|
getRootRef: setBackdropEl,
|
|
70
73
|
"data-testid": modalOverlayTestId,
|
|
@@ -128,17 +131,22 @@ const desktopMaxWidthClassNames = {
|
|
|
128
131
|
l: styles['hostDesktopMaxWidthL']
|
|
129
132
|
};
|
|
130
133
|
function resolveDesktopMaxWidth(desktopMaxWidth = 's') {
|
|
131
|
-
if (typeof desktopMaxWidth === '
|
|
134
|
+
if (typeof desktopMaxWidth === 'number') {
|
|
132
135
|
return [
|
|
133
|
-
|
|
134
|
-
|
|
136
|
+
undefined,
|
|
137
|
+
{
|
|
138
|
+
'--vkui_internal_ModalPage--desktopMaxWidth': `${desktopMaxWidth}px`
|
|
139
|
+
}
|
|
135
140
|
];
|
|
136
141
|
}
|
|
137
|
-
return [
|
|
142
|
+
return desktopMaxWidthClassNames.hasOwnProperty(desktopMaxWidth) ? [
|
|
143
|
+
desktopMaxWidthClassNames[desktopMaxWidth],
|
|
144
|
+
undefined
|
|
145
|
+
] : [
|
|
138
146
|
undefined,
|
|
139
|
-
|
|
140
|
-
'--vkui_internal_ModalPage--desktopMaxWidth':
|
|
141
|
-
}
|
|
147
|
+
{
|
|
148
|
+
'--vkui_internal_ModalPage--desktopMaxWidth': desktopMaxWidth
|
|
149
|
+
}
|
|
142
150
|
];
|
|
143
151
|
}
|
|
144
152
|
function getHeightCSSVariable(height) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ModalPage/ModalPageInternal.tsx"],"sourcesContent":["'use client';\n/* eslint-disable jsdoc/require-jsdoc */\n\nimport { type ComponentType, type KeyboardEvent, useCallback } from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { mergeStyle } from '../../helpers/mergeStyle';\nimport { useAdaptivityWithJSMediaQueries } from '../../hooks/useAdaptivityWithJSMediaQueries';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useVirtualKeyboardState } from '../../hooks/useVirtualKeyboardState';\nimport { Keys, pressedKey } from '../../lib/accessibility';\nimport { useCSSTransition, type UseCSSTransitionState } from '../../lib/animation';\nimport { type SnapPoint, type SnapPointChange, useBottomSheet } from '../../lib/sheet';\nimport type { CSSCustomProperties } from '../../types';\nimport { useScrollLock } from '../AppRoot/ScrollContext';\nimport { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';\nimport { FocusTrap } from '../FocusTrap/FocusTrap';\nimport { ModalOutlet } from '../ModalOutlet/ModalOutlet';\nimport {\n ModalOverlay as ModalOverlayDefault,\n type ModalOverlayProps,\n} from '../ModalOverlay/ModalOverlay';\nimport { ModalPageBase } from './ModalPageBase';\nimport type { ModalPageProps } from './types';\nimport styles from './ModalPage.module.css';\n\nconst transitionStateClassNames: Partial<Record<UseCSSTransitionState, string>> = {\n appear: styles['documentStateEnter'],\n appearing: styles['documentStateEntering'],\n\n enter: styles['documentStateEnter'],\n entering: styles['documentStateEntering'],\n\n exiting: styles['documentStateExiting'],\n exited: styles['documentStateExited'],\n};\n\nexport interface ModalPageInternalProps\n extends Omit<ModalPageProps, 'nav' | 'keepMounted' | 'settlingHeight' | 'dynamicContentHeight'> {\n snapPoint: SnapPoint;\n ModalOverlay?: ComponentType<ModalOverlayProps>;\n onSnapPointChange?: SnapPointChange;\n}\n\n/**\n * В компоненте заложена вся логика модального окна.\n *\n * @private\n */\nexport const ModalPageInternal = ({\n open,\n header,\n footer,\n size: desktopMaxWidth,\n height,\n children,\n className,\n style,\n snapPoint,\n onSnapPointChange,\n getModalContentRef,\n ModalOverlay = ModalOverlayDefault,\n modalOverlayTestId,\n modalContentTestId,\n modalDismissButtonTestId,\n modalDismissButtonLabel = 'Закрыть',\n outsideButtons,\n noFocusToDialog,\n hideCloseButton,\n preventClose,\n disableContentPanningGesture,\n restoreFocus,\n onOpen,\n onOpened,\n onClose = noop,\n onClosed,\n disableFocusTrap,\n disableModalOverlay,\n ...restProps\n}: ModalPageInternalProps) => {\n const { hasCustomPanelHeaderAfter } = useConfigProvider();\n const [transitionState, { ref, onTransitionEnd }] = useCSSTransition<HTMLDivElement>(open, {\n enableAppear: true,\n onEnter() {\n onOpen?.();\n },\n onEntered() {\n onOpened?.();\n },\n onExited() {\n onClosed?.();\n },\n });\n const opened = transitionState === 'appeared' || transitionState === 'entered';\n const hidden = transitionState === 'exited';\n const closable = !preventClose && opened;\n\n const { sizeX, isDesktop } = useAdaptivityWithJSMediaQueries();\n const bottomSheetEnabled = !isDesktop && !preventClose && transitionState !== 'exited';\n const { opened: keyboardOpened } = useVirtualKeyboardState(bottomSheetEnabled);\n\n const [{ initialStyle, setSheetEl, setSheetScrollEl, setBackdropEl }, bottomSheetEventHandlers] =\n useBottomSheet(bottomSheetEnabled, {\n blocked: keyboardOpened,\n snapPoint,\n sheetCSSProperty: '--vkui_internal_ModalPageDocument--snapPoint',\n backdropCSSProperty: '--vkui_internal--modal-overlay--opacity',\n onSnapPointChange,\n onDismiss() {\n onClose('swipe-down');\n },\n });\n const documentStyle = keyboardOpened\n ? {\n '--vkui_internal_ModalPageDocument--safeAreaInsetBottom': '0px',\n ...initialStyle,\n }\n : initialStyle;\n const handleSheetRef = useExternRef<HTMLDivElement>(setSheetEl, ref);\n const handleSheetScrollRef = useExternRef<HTMLDivElement>(setSheetScrollEl, getModalContentRef);\n\n const [desktopMaxWidthClassName, desktopMaxWidthStyle] = resolveDesktopMaxWidth(\n isDesktop ? desktopMaxWidth : 's',\n );\n\n const modalOverlay = !disableModalOverlay && (\n <ModalOverlay\n getRootRef={setBackdropEl}\n data-testid={modalOverlayTestId}\n visible={open}\n onClick={\n closable\n ? function handleBackdropClick(event) {\n onClose('click-overlay', event);\n }\n : undefined\n }\n />\n );\n const handleEscKeyDown = useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n if (closable && pressedKey(event) === Keys.ESCAPE) {\n onClose('escape-key');\n }\n },\n [closable, onClose],\n );\n\n useScrollLock(!hidden);\n\n return (\n <ModalOutlet\n hidden={hidden}\n isDesktop={isDesktop}\n onKeyDown={handleEscKeyDown}\n disableModalOverlay={disableModalOverlay}\n >\n {modalOverlay}\n <FocusTrap\n {...restProps}\n autoFocus={!noFocusToDialog}\n restoreFocus={restoreFocus}\n role=\"dialog\"\n aria-modal=\"true\"\n disabled={!opened || hidden || disableFocusTrap}\n className={classNames(\n className,\n styles.host,\n isDesktop ? styles.hostDesktop : styles.hostMobile,\n !isDesktop &&\n (hasCustomPanelHeaderAfter\n ? styles.hostMobileSafeAreaInsetTopWithCustomOffset\n : styles.hostMobileSafeAreaInsetTop),\n desktopMaxWidthClassName,\n sizeX === 'regular' && 'vkuiInternalModalPage--sizeX-regular',\n )}\n style={mergeStyle(mergeStyle(desktopMaxWidthStyle, getHeightCSSVariable(height)), style)}\n >\n <ModalPageBase\n {...bottomSheetEventHandlers}\n getRootRef={handleSheetRef}\n getRef={handleSheetScrollRef}\n style={documentStyle}\n className={classNames(\n isDesktop ? styles.documentDesktop : styles.documentMobile,\n transitionStateClassNames[transitionState],\n )}\n onTransitionEnd={onTransitionEnd}\n isDesktop={isDesktop}\n disableContentPanningGesture={disableContentPanningGesture}\n header={header}\n footer={footer}\n outsideButtons={outsideButtons}\n modalContentTestId={modalContentTestId}\n modalDismissButtonTestId={modalDismissButtonTestId}\n modalDismissButtonLabel={modalDismissButtonLabel}\n hideCloseButton={hideCloseButton}\n closable={closable}\n onClose={onClose}\n >\n {children}\n </ModalPageBase>\n </FocusTrap>\n </ModalOutlet>\n );\n};\n\nconst desktopMaxWidthClassNames = {\n s: styles['hostDesktopMaxWidthS'],\n m: styles['hostDesktopMaxWidthM'],\n l: styles['hostDesktopMaxWidthL'],\n};\n\nfunction resolveDesktopMaxWidth(\n desktopMaxWidth: ModalPageInternalProps['size'] = 's',\n): [string | undefined, CSSCustomProperties | undefined] {\n if (typeof desktopMaxWidth === 'string') {\n return [desktopMaxWidthClassNames[desktopMaxWidth], undefined];\n }\n\n return [\n undefined,\n typeof desktopMaxWidth === 'number'\n ? { '--vkui_internal_ModalPage--desktopMaxWidth': `${desktopMaxWidth}px` }\n : undefined,\n ];\n}\n\nfunction getHeightCSSVariable(height?: number | string): CSSCustomProperties | undefined {\n return height !== undefined\n ? {\n '--vkui_internal_ModalPage--userHeight':\n typeof height === 'number' ? `${height}px` : height,\n }\n : undefined;\n}\n"],"names":["useCallback","classNames","noop","mergeStyle","useAdaptivityWithJSMediaQueries","useExternRef","useVirtualKeyboardState","Keys","pressedKey","useCSSTransition","useBottomSheet","useScrollLock","useConfigProvider","FocusTrap","ModalOutlet","ModalOverlay","ModalOverlayDefault","ModalPageBase","styles","transitionStateClassNames","appear","appearing","enter","entering","exiting","exited","ModalPageInternal","open","header","footer","size","desktopMaxWidth","height","children","className","style","snapPoint","onSnapPointChange","getModalContentRef","modalOverlayTestId","modalContentTestId","modalDismissButtonTestId","modalDismissButtonLabel","outsideButtons","noFocusToDialog","hideCloseButton","preventClose","disableContentPanningGesture","restoreFocus","onOpen","onOpened","onClose","onClosed","disableFocusTrap","disableModalOverlay","restProps","hasCustomPanelHeaderAfter","transitionState","ref","onTransitionEnd","enableAppear","onEnter","onEntered","onExited","opened","hidden","closable","sizeX","isDesktop","bottomSheetEnabled","keyboardOpened","initialStyle","setSheetEl","setSheetScrollEl","setBackdropEl","bottomSheetEventHandlers","blocked","sheetCSSProperty","backdropCSSProperty","onDismiss","documentStyle","handleSheetRef","handleSheetScrollRef","desktopMaxWidthClassName","desktopMaxWidthStyle","resolveDesktopMaxWidth","modalOverlay","getRootRef","data-testid","visible","onClick","handleBackdropClick","event","undefined","handleEscKeyDown","ESCAPE","onKeyDown","autoFocus","role","aria-modal","disabled","host","hostDesktop","hostMobile","hostMobileSafeAreaInsetTopWithCustomOffset","hostMobileSafeAreaInsetTop","getHeightCSSVariable","getRef","documentDesktop","documentMobile","desktopMaxWidthClassNames","s","m","l"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ModalPage/ModalPageInternal.tsx"],"sourcesContent":["'use client';\n/* eslint-disable jsdoc/require-jsdoc */\n\nimport { type ComponentType, type KeyboardEvent, useCallback } from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { mergeStyle } from '../../helpers/mergeStyle';\nimport { useAdaptivityWithJSMediaQueries } from '../../hooks/useAdaptivityWithJSMediaQueries';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useVirtualKeyboardState } from '../../hooks/useVirtualKeyboardState';\nimport { Keys, pressedKey } from '../../lib/accessibility';\nimport { useCSSTransition, type UseCSSTransitionState } from '../../lib/animation';\nimport { type SnapPoint, type SnapPointChange, useBottomSheet } from '../../lib/sheet';\nimport type { CSSCustomProperties } from '../../types';\nimport { useScrollLock } from '../AppRoot/ScrollContext';\nimport { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';\nimport { FocusTrap } from '../FocusTrap/FocusTrap';\nimport { ModalOutlet } from '../ModalOutlet/ModalOutlet';\nimport {\n ModalOverlay as ModalOverlayDefault,\n type ModalOverlayProps,\n} from '../ModalOverlay/ModalOverlay';\nimport { ModalPageBase } from './ModalPageBase';\nimport type { ModalPageProps } from './types';\nimport styles from './ModalPage.module.css';\n\nconst transitionStateClassNames: Partial<Record<UseCSSTransitionState, string>> = {\n appear: styles['documentStateEnter'],\n appearing: styles['documentStateEntering'],\n\n enter: styles['documentStateEnter'],\n entering: styles['documentStateEntering'],\n\n exiting: styles['documentStateExiting'],\n exited: styles['documentStateExited'],\n};\n\nexport interface ModalPageInternalProps\n extends Omit<ModalPageProps, 'nav' | 'keepMounted' | 'settlingHeight' | 'dynamicContentHeight'> {\n snapPoint: SnapPoint;\n ModalOverlay?: ComponentType<ModalOverlayProps>;\n onSnapPointChange?: SnapPointChange;\n}\n\n/**\n * В компоненте заложена вся логика модального окна.\n *\n * @private\n */\nexport const ModalPageInternal = ({\n open,\n header,\n footer,\n size: desktopMaxWidth,\n height,\n children,\n className,\n style,\n snapPoint,\n onSnapPointChange,\n getModalContentRef,\n ModalOverlay = ModalOverlayDefault,\n modalOverlayTestId,\n modalContentTestId,\n modalDismissButtonTestId,\n modalDismissButtonLabel = 'Закрыть',\n outsideButtons,\n noFocusToDialog,\n hideCloseButton,\n preventClose,\n disableContentPanningGesture,\n restoreFocus,\n onOpen,\n onOpened,\n onClose = noop,\n onClosed,\n disableFocusTrap,\n disableModalOverlay,\n ...restProps\n}: ModalPageInternalProps) => {\n const { hasCustomPanelHeaderAfter } = useConfigProvider();\n const [transitionState, { ref, onTransitionEnd }] = useCSSTransition<HTMLDivElement>(open, {\n enableAppear: true,\n onEnter() {\n onOpen?.();\n },\n onEntered() {\n onOpened?.();\n },\n onExited() {\n onClosed?.();\n },\n });\n const opened = transitionState === 'appeared' || transitionState === 'entered';\n const hidden = transitionState === 'exited';\n const closable = !preventClose && opened;\n\n const { sizeX, isDesktop } = useAdaptivityWithJSMediaQueries();\n const bottomSheetEnabled = !isDesktop && !preventClose && transitionState !== 'exited';\n const { opened: keyboardOpened } = useVirtualKeyboardState(bottomSheetEnabled);\n\n const [{ initialStyle, setSheetEl, setSheetScrollEl, setBackdropEl }, bottomSheetEventHandlers] =\n useBottomSheet(bottomSheetEnabled, {\n blocked: keyboardOpened,\n snapPoint,\n sheetCSSProperty: '--vkui_internal_ModalPageDocument--snapPoint',\n backdropCSSProperty: '--vkui_internal--modal-overlay--opacity',\n onSnapPointChange,\n onDismiss() {\n onClose('swipe-down');\n },\n });\n const documentStyle = keyboardOpened\n ? {\n '--vkui_internal_ModalPageDocument--safeAreaInsetBottom': '0px',\n ...initialStyle,\n }\n : initialStyle;\n const handleSheetRef = useExternRef<HTMLDivElement>(setSheetEl, ref);\n const handleSheetScrollRef = useExternRef<HTMLDivElement>(setSheetScrollEl, getModalContentRef);\n\n const [desktopMaxWidthClassName, desktopMaxWidthStyle] = isDesktop\n ? resolveDesktopMaxWidth(desktopMaxWidth)\n : [undefined, undefined];\n\n const modalOverlay = !disableModalOverlay && (\n <ModalOverlay\n getRootRef={setBackdropEl}\n data-testid={modalOverlayTestId}\n visible={open}\n onClick={\n closable\n ? function handleBackdropClick(event) {\n onClose('click-overlay', event);\n }\n : undefined\n }\n />\n );\n const handleEscKeyDown = useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n if (closable && pressedKey(event) === Keys.ESCAPE) {\n onClose('escape-key');\n }\n },\n [closable, onClose],\n );\n\n useScrollLock(!hidden);\n\n return (\n <ModalOutlet\n hidden={hidden}\n isDesktop={isDesktop}\n onKeyDown={handleEscKeyDown}\n disableModalOverlay={disableModalOverlay}\n >\n {modalOverlay}\n <FocusTrap\n {...restProps}\n autoFocus={!noFocusToDialog}\n restoreFocus={restoreFocus}\n role=\"dialog\"\n aria-modal=\"true\"\n disabled={!opened || hidden || disableFocusTrap}\n className={classNames(\n className,\n styles.host,\n isDesktop ? styles.hostDesktop : styles.hostMobile,\n !isDesktop &&\n (hasCustomPanelHeaderAfter\n ? styles.hostMobileSafeAreaInsetTopWithCustomOffset\n : styles.hostMobileSafeAreaInsetTop),\n desktopMaxWidthClassName,\n sizeX === 'regular' && 'vkuiInternalModalPage--sizeX-regular',\n )}\n style={mergeStyle(mergeStyle(desktopMaxWidthStyle, getHeightCSSVariable(height)), style)}\n >\n <ModalPageBase\n {...bottomSheetEventHandlers}\n getRootRef={handleSheetRef}\n getRef={handleSheetScrollRef}\n style={documentStyle}\n className={classNames(\n isDesktop ? styles.documentDesktop : styles.documentMobile,\n transitionStateClassNames[transitionState],\n )}\n onTransitionEnd={onTransitionEnd}\n isDesktop={isDesktop}\n disableContentPanningGesture={disableContentPanningGesture}\n header={header}\n footer={footer}\n outsideButtons={outsideButtons}\n modalContentTestId={modalContentTestId}\n modalDismissButtonTestId={modalDismissButtonTestId}\n modalDismissButtonLabel={modalDismissButtonLabel}\n hideCloseButton={hideCloseButton}\n closable={closable}\n onClose={onClose}\n >\n {children}\n </ModalPageBase>\n </FocusTrap>\n </ModalOutlet>\n );\n};\n\nconst desktopMaxWidthClassNames = {\n s: styles['hostDesktopMaxWidthS'],\n m: styles['hostDesktopMaxWidthM'],\n l: styles['hostDesktopMaxWidthL'],\n};\n\nfunction resolveDesktopMaxWidth(\n desktopMaxWidth: ModalPageInternalProps['size'] = 's',\n): [string | undefined, CSSCustomProperties | undefined] {\n if (typeof desktopMaxWidth === 'number') {\n return [undefined, { '--vkui_internal_ModalPage--desktopMaxWidth': `${desktopMaxWidth}px` }];\n }\n\n return desktopMaxWidthClassNames.hasOwnProperty(desktopMaxWidth)\n ? [desktopMaxWidthClassNames[desktopMaxWidth], undefined]\n : [undefined, { '--vkui_internal_ModalPage--desktopMaxWidth': desktopMaxWidth }];\n}\n\nfunction getHeightCSSVariable(height?: number | string): CSSCustomProperties | undefined {\n return height !== undefined\n ? {\n '--vkui_internal_ModalPage--userHeight':\n typeof height === 'number' ? `${height}px` : height,\n }\n : undefined;\n}\n"],"names":["useCallback","classNames","noop","mergeStyle","useAdaptivityWithJSMediaQueries","useExternRef","useVirtualKeyboardState","Keys","pressedKey","useCSSTransition","useBottomSheet","useScrollLock","useConfigProvider","FocusTrap","ModalOutlet","ModalOverlay","ModalOverlayDefault","ModalPageBase","styles","transitionStateClassNames","appear","appearing","enter","entering","exiting","exited","ModalPageInternal","open","header","footer","size","desktopMaxWidth","height","children","className","style","snapPoint","onSnapPointChange","getModalContentRef","modalOverlayTestId","modalContentTestId","modalDismissButtonTestId","modalDismissButtonLabel","outsideButtons","noFocusToDialog","hideCloseButton","preventClose","disableContentPanningGesture","restoreFocus","onOpen","onOpened","onClose","onClosed","disableFocusTrap","disableModalOverlay","restProps","hasCustomPanelHeaderAfter","transitionState","ref","onTransitionEnd","enableAppear","onEnter","onEntered","onExited","opened","hidden","closable","sizeX","isDesktop","bottomSheetEnabled","keyboardOpened","initialStyle","setSheetEl","setSheetScrollEl","setBackdropEl","bottomSheetEventHandlers","blocked","sheetCSSProperty","backdropCSSProperty","onDismiss","documentStyle","handleSheetRef","handleSheetScrollRef","desktopMaxWidthClassName","desktopMaxWidthStyle","resolveDesktopMaxWidth","undefined","modalOverlay","getRootRef","data-testid","visible","onClick","handleBackdropClick","event","handleEscKeyDown","ESCAPE","onKeyDown","autoFocus","role","aria-modal","disabled","host","hostDesktop","hostMobile","hostMobileSafeAreaInsetTopWithCustomOffset","hostMobileSafeAreaInsetTop","getHeightCSSVariable","getRef","documentDesktop","documentMobile","desktopMaxWidthClassNames","s","m","l","hasOwnProperty"],"mappings":"AAAA;;AACA,sCAAsC,GAEtC,SAAiDA,WAAW,QAAQ,QAAQ;AAC5E,SAASC,UAAU,EAAEC,IAAI,QAAQ,kBAAkB;AACnD,SAASC,UAAU,QAAQ,8BAA2B;AACtD,SAASC,+BAA+B,QAAQ,iDAA8C;AAC9F,SAASC,YAAY,QAAQ,8BAA2B;AACxD,SAASC,uBAAuB,QAAQ,yCAAsC;AAC9E,SAASC,IAAI,EAAEC,UAAU,QAAQ,6BAA0B;AAC3D,SAASC,gBAAgB,QAAoC,+BAAsB;AACnF,SAA+CC,cAAc,QAAQ,2BAAkB;AAEvF,SAASC,aAAa,QAAQ,8BAA2B;AACzD,SAASC,iBAAiB,QAAQ,6CAA0C;AAC5E,SAASC,SAAS,QAAQ,4BAAyB;AACnD,SAASC,WAAW,QAAQ,gCAA6B;AACzD,SACEC,gBAAgBC,mBAAmB,QAE9B,kCAA+B;AACtC,SAASC,aAAa,QAAQ,qBAAkB;AAEhD,OAAOC,YAAY,yBAAyB;AAE5C,MAAMC,4BAA4E;IAChFC,QAAQF,MAAM,CAAC,qBAAqB;IACpCG,WAAWH,MAAM,CAAC,wBAAwB;IAE1CI,OAAOJ,MAAM,CAAC,qBAAqB;IACnCK,UAAUL,MAAM,CAAC,wBAAwB;IAEzCM,SAASN,MAAM,CAAC,uBAAuB;IACvCO,QAAQP,MAAM,CAAC,sBAAsB;AACvC;AASA;;;;CAIC,GACD,OAAO,MAAMQ,oBAAoB,CAAC,EAChCC,IAAI,EACJC,MAAM,EACNC,MAAM,EACNC,MAAMC,eAAe,EACrBC,MAAM,EACNC,QAAQ,EACRC,SAAS,EACTC,KAAK,EACLC,SAAS,EACTC,iBAAiB,EACjBC,kBAAkB,EAClBvB,eAAeC,mBAAmB,EAClCuB,kBAAkB,EAClBC,kBAAkB,EAClBC,wBAAwB,EACxBC,0BAA0B,SAAS,EACnCC,cAAc,EACdC,eAAe,EACfC,eAAe,EACfC,YAAY,EACZC,4BAA4B,EAC5BC,YAAY,EACZC,MAAM,EACNC,QAAQ,EACRC,UAAUjD,IAAI,EACdkD,QAAQ,EACRC,gBAAgB,EAChBC,mBAAmB,EACnB,GAAGC,WACoB;IACvB,MAAM,EAAEC,yBAAyB,EAAE,GAAG5C;IACtC,MAAM,CAAC6C,iBAAiB,EAAEC,GAAG,EAAEC,eAAe,EAAE,CAAC,GAAGlD,iBAAiCkB,MAAM;QACzFiC,cAAc;QACdC;YACEZ;QACF;QACAa;YACEZ;QACF;QACAa;YACEX;QACF;IACF;IACA,MAAMY,SAASP,oBAAoB,cAAcA,oBAAoB;IACrE,MAAMQ,SAASR,oBAAoB;IACnC,MAAMS,WAAW,CAACpB,gBAAgBkB;IAElC,MAAM,EAAEG,KAAK,EAAEC,SAAS,EAAE,GAAGhE;IAC7B,MAAMiE,qBAAqB,CAACD,aAAa,CAACtB,gBAAgBW,oBAAoB;IAC9E,MAAM,EAAEO,QAAQM,cAAc,EAAE,GAAGhE,wBAAwB+D;IAE3D,MAAM,CAAC,EAAEE,YAAY,EAAEC,UAAU,EAAEC,gBAAgB,EAAEC,aAAa,EAAE,EAAEC,yBAAyB,GAC7FjE,eAAe2D,oBAAoB;QACjCO,SAASN;QACTlC;QACAyC,kBAAkB;QAClBC,qBAAqB;QACrBzC;QACA0C;YACE5B,QAAQ;QACV;IACF;IACF,MAAM6B,gBAAgBV,iBAClB;QACE,0DAA0D;QAC1D,GAAGC,YAAY;IACjB,IACAA;IACJ,MAAMU,iBAAiB5E,aAA6BmE,YAAYd;IAChE,MAAMwB,uBAAuB7E,aAA6BoE,kBAAkBnC;IAE5E,MAAM,CAAC6C,0BAA0BC,qBAAqB,GAAGhB,YACrDiB,uBAAuBtD,mBACvB;QAACuD;QAAWA;KAAU;IAE1B,MAAMC,eAAe,CAACjC,qCACpB,KAACvC;QACCyE,YAAYd;QACZe,eAAalD;QACbmD,SAAS/D;QACTgE,SACEzB,WACI,SAAS0B,oBAAoBC,KAAK;YAChC1C,QAAQ,iBAAiB0C;QAC3B,IACAP;;IAIV,MAAMQ,mBAAmB9F,YACvB,CAAC6F;QACC,IAAI3B,YAAY1D,WAAWqF,WAAWtF,KAAKwF,MAAM,EAAE;YACjD5C,QAAQ;QACV;IACF,GACA;QAACe;QAAUf;KAAQ;IAGrBxC,cAAc,CAACsD;IAEf,qBACE,MAACnD;QACCmD,QAAQA;QACRG,WAAWA;QACX4B,WAAWF;QACXxC,qBAAqBA;;YAEpBiC;0BACD,KAAC1E;gBACE,GAAG0C,SAAS;gBACb0C,WAAW,CAACrD;gBACZI,cAAcA;gBACdkD,MAAK;gBACLC,cAAW;gBACXC,UAAU,CAACpC,UAAUC,UAAUZ;gBAC/BnB,WAAWjC,WACTiC,WACAhB,OAAOmF,IAAI,EACXjC,YAAYlD,OAAOoF,WAAW,GAAGpF,OAAOqF,UAAU,EAClD,CAACnC,aACEZ,CAAAA,4BACGtC,OAAOsF,0CAA0C,GACjDtF,OAAOuF,0BAA0B,AAAD,GACtCtB,0BACAhB,UAAU,aAAa;gBAEzBhC,OAAOhC,WAAWA,WAAWiF,sBAAsBsB,qBAAqB1E,UAAUG;0BAElF,cAAA,KAAClB;oBACE,GAAG0D,wBAAwB;oBAC5Ba,YAAYP;oBACZ0B,QAAQzB;oBACR/C,OAAO6C;oBACP9C,WAAWjC,WACTmE,YAAYlD,OAAO0F,eAAe,GAAG1F,OAAO2F,cAAc,EAC1D1F,yBAAyB,CAACsC,gBAAgB;oBAE5CE,iBAAiBA;oBACjBS,WAAWA;oBACXrB,8BAA8BA;oBAC9BnB,QAAQA;oBACRC,QAAQA;oBACRc,gBAAgBA;oBAChBH,oBAAoBA;oBACpBC,0BAA0BA;oBAC1BC,yBAAyBA;oBACzBG,iBAAiBA;oBACjBqB,UAAUA;oBACVf,SAASA;8BAERlB;;;;;AAKX,EAAE;AAEF,MAAM6E,4BAA4B;IAChCC,GAAG7F,MAAM,CAAC,uBAAuB;IACjC8F,GAAG9F,MAAM,CAAC,uBAAuB;IACjC+F,GAAG/F,MAAM,CAAC,uBAAuB;AACnC;AAEA,SAASmE,uBACPtD,kBAAkD,GAAG;IAErD,IAAI,OAAOA,oBAAoB,UAAU;QACvC,OAAO;YAACuD;YAAW;gBAAE,8CAA8C,GAAGvD,gBAAgB,EAAE,CAAC;YAAC;SAAE;IAC9F;IAEA,OAAO+E,0BAA0BI,cAAc,CAACnF,mBAC5C;QAAC+E,yBAAyB,CAAC/E,gBAAgB;QAAEuD;KAAU,GACvD;QAACA;QAAW;YAAE,8CAA8CvD;QAAgB;KAAE;AACpF;AAEA,SAAS2E,qBAAqB1E,MAAwB;IACpD,OAAOA,WAAWsD,YACd;QACE,yCACE,OAAOtD,WAAW,WAAW,GAAGA,OAAO,EAAE,CAAC,GAAGA;IACjD,IACAsD;AACN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ModalPage/types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode, Ref, UIEvent } from 'react';\nimport { type UseFocusTrapProps } from '../../hooks/useFocusTrap';\nimport type { NavIdProps } from '../../lib/getNavId';\nimport type { HTMLAttributesWithRootRef } from '../../types';\n\nexport type ModalPageCloseReason =\n | 'click-overlay'\n | 'click-close-button'\n | 'escape-key'\n | 'swipe-down';\n\ntype OmittedStyleAttribute = {\n /**\n * Дополнительные стили.\n */\n style?: Omit<CSSProperties, 'height' | 'maxWidth' | 'maxHeight'>;\n};\n\nexport interface ModalPageProps\n extends NavIdProps,\n Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'id' | 'style'>,\n Pick<UseFocusTrapProps, 'restoreFocus'>,\n OmittedStyleAttribute {\n /**\n * Состояние видимости.\n *\n * @default false\n */\n open?: boolean;\n /**\n * Сохранять ли компонент в DOM при `open={false}`.\n *\n * @default false\n */\n keepMounted?: boolean;\n /**\n * Шапка модальной страницы, `<ModalPageHeader />`.\n */\n header?: ReactNode;\n /**\n * Подвал модальной страницы, `<ModalPageFooter />`.\n */\n footer?: ReactNode;\n /**\n * Задаёт контенту максимальную ширину на десктопе.\n */\n size?: 's' | 'm' | 'l' | number
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ModalPage/types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode, Ref, UIEvent } from 'react';\nimport { type UseFocusTrapProps } from '../../hooks/useFocusTrap';\nimport type { NavIdProps } from '../../lib/getNavId';\nimport type { HTMLAttributesWithRootRef, LiteralUnion } from '../../types';\n\nexport type ModalPageCloseReason =\n | 'click-overlay'\n | 'click-close-button'\n | 'escape-key'\n | 'swipe-down';\n\ntype OmittedStyleAttribute = {\n /**\n * Дополнительные стили.\n */\n style?: Omit<CSSProperties, 'height' | 'maxWidth' | 'maxHeight'>;\n};\n\nexport interface ModalPageProps\n extends NavIdProps,\n Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'id' | 'style'>,\n Pick<UseFocusTrapProps, 'restoreFocus'>,\n OmittedStyleAttribute {\n /**\n * Состояние видимости.\n *\n * @default false\n */\n open?: boolean;\n /**\n * Сохранять ли компонент в DOM при `open={false}`.\n *\n * @default false\n */\n keepMounted?: boolean;\n /**\n * Шапка модальной страницы, `<ModalPageHeader />`.\n */\n header?: ReactNode;\n /**\n * Подвал модальной страницы, `<ModalPageFooter />`.\n */\n footer?: ReactNode;\n /**\n * Задаёт контенту максимальную ширину на десктопе.\n */\n size?: LiteralUnion<\n 's' | 'm' | 'l' | 'auto' | 'fit-content' | 'max-content' | 'min-content',\n string | number\n >;\n /**\n * Задаёт модальному окну фиксированную высоту.\n * Можно передать числовое значение в пикселях, а можно строкой, в том числе и в процентах \"50%\".\n * В мобильной версии 'settlingHeight' будет считаться относительно заданного height.\n */\n height?: string | number;\n /**\n * Процент, на который изначально будет открыта модальная страница.\n *\n * > ⚠️ Следует использовать следующие значения: `25`, `50`, `75`, `100`.\n * > При передаче `< 25` значение приведётся к `25`, при передаче `> 75` значение приведётся к `75`.\n *\n * Игнорируется при включении `dynamicContentHeight`.\n */\n settlingHeight?: number;\n /**\n * Если высота контента в модальной странице может поменяться, нужно установить это свойство.\n */\n dynamicContentHeight?: boolean;\n /**\n * Отключает фокус на интерактивный элемент после открытия модалки.\n *\n * > Важно установить фокус после открытия в любое место модалки используя событие `onOpened`, иначе не будет работать закрытие по нажатию `Esc`.\n */\n noFocusToDialog?: boolean;\n /**\n * Скрывает кнопку закрытия (актуально для iOS, так как можно отрисовать кнопку закрытия внутри модалки).\n */\n hideCloseButton?: boolean;\n /**\n * `data-testid` для содержимого модального окна.\n */\n modalContentTestId?: string;\n /**\n * Возвращает DOM-элемент содержимого модального окна.\n */\n getModalContentRef?: Ref<HTMLDivElement>;\n /**\n * `data-testid` для оверлея.\n */\n modalOverlayTestId?: string;\n /**\n * `data-testid` для кнопки закрытия.\n */\n modalDismissButtonTestId?: string;\n /**\n * Текст для скринридера.\n */\n modalDismissButtonLabel?: string;\n /**\n * Позволяет отключить возможность закрытия модальной страницы (смахивание, клавиша `ESC`, нажатие на подложку).\n *\n * ⚠️ ВНИМАНИЕ: использование этой опции негативно сказывается на пользовательском опыте.\n */\n preventClose?: boolean;\n /**\n * Отключает раскрытие и закрытие панели в мобильном виде.\n */\n disableContentPanningGesture?: boolean;\n /**\n * Будет вызвано при начале открытия модалки.\n */\n onOpen?: VoidFunction;\n /**\n * Будет вызвано при окончательном открытии модалки.\n */\n onOpened?: VoidFunction;\n /**\n * Будет вызвано при начале закрытия модалки.\n */\n onClose?: (reason: ModalPageCloseReason, event?: UIEvent<HTMLElement>) => void;\n /**\n * Будет вызвано при окончательном закрытии модалки.\n */\n onClosed?: VoidFunction;\n /**\n * Управляющие элементы под кнопкой закрытия.\n *\n * Доступно только в `compact`-режиме. Рекомендуется размещать иконки размера 20, обернутые в ModalOutsideButton.\n *\n */\n outsideButtons?: React.ReactNode;\n /**\n * Позволяет отключить захват фокуса.\n *\n * Нужно использовать, когда поверх одной модалки открывается другая, чтобы два `FocusTrap` не конфликтовали.\n */\n disableFocusTrap?: UseFocusTrapProps['disabled'];\n /**\n * Отключает отображение и взаимодействие с фоном модалки.\n * > При использовании `ModalPage` внутри `ModalRoot` есть особенность использования этого свойства.\n * > Об этом можно почитать на странице документации [`ModalRoot`](/components/modal-root#otklyuchenie-zadnego-fona-u-konkretnogo-modalnogo-okna).\n */\n disableModalOverlay?: boolean;\n}\n"],"names":[],"mappings":"AAkBA,WA8HC"}
|
|
@@ -20,7 +20,7 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
|
|
|
20
20
|
import styles from "./Search.module.css";
|
|
21
21
|
/**
|
|
22
22
|
* @see https://vkui.io/components/search
|
|
23
|
-
*/ export const Search = ({ id: idProp, before = /*#__PURE__*/ _jsx(Icon16SearchOutline, {}), className, placeholder = 'Поиск', after = 'Отмена', getRef, icon: iconProp, onIconClick, style, autoComplete = 'off', onChange, iconLabel, clearLabel = 'Очистить', clearButtonTestId, noPadding, getRootRef, findButtonText = 'Найти', findButtonTestId, onFindButtonClick, ...inputProps })=>{
|
|
23
|
+
*/ export const Search = ({ id: idProp, before = /*#__PURE__*/ _jsx(Icon16SearchOutline, {}), className, placeholder = 'Поиск', after = 'Отмена', getRef, icon: iconProp, onIconClick, style, autoComplete = 'off', onChange, iconLabel, clearLabel = 'Очистить', clearButtonTestId, noPadding, getRootRef, findButtonText = 'Найти', findButtonTestId, onFindButtonClick, hideClearButton, ...inputProps })=>{
|
|
24
24
|
const direction = useConfigDirection();
|
|
25
25
|
const isRtl = direction === 'rtl';
|
|
26
26
|
const inputRef = useExternRef(getRef);
|
|
@@ -90,6 +90,7 @@ import styles from "./Search.module.css";
|
|
|
90
90
|
icon
|
|
91
91
|
]
|
|
92
92
|
});
|
|
93
|
+
const showControls = Boolean(iconProp || !hideClearButton || adaptiveSizeY.compact && onFindButtonClick);
|
|
93
94
|
return /*#__PURE__*/ _jsxs("div", {
|
|
94
95
|
className: classNames('vkuiInternalSearch', styles.host, sizeY === 'none' && styles.sizeYNone, sizeY === 'compact' && styles.sizeYCompact, isFocused && styles.focused, hasValue && styles.hasValue, hasAfter && styles.hasAfter, iconProp && styles.hasIcon, inputProps.disabled && styles.disabled, !noPadding && styles.withPadding, isRtl && styles.rtl, className),
|
|
95
96
|
ref: getRootRef,
|
|
@@ -124,11 +125,11 @@ import styles from "./Search.module.css";
|
|
|
124
125
|
})
|
|
125
126
|
]
|
|
126
127
|
}),
|
|
127
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
128
|
+
showControls && /*#__PURE__*/ _jsxs("div", {
|
|
128
129
|
className: styles.controls,
|
|
129
130
|
children: [
|
|
130
131
|
iconProp && (typeof iconProp === 'function' ? iconProp(renderIconButton) : renderIconButton(iconProp)),
|
|
131
|
-
/*#__PURE__*/ _jsxs(IconButton, {
|
|
132
|
+
!hideClearButton && /*#__PURE__*/ _jsxs(IconButton, {
|
|
132
133
|
hoverMode: "opacity",
|
|
133
134
|
onPointerDown: onIconCancelClickStart,
|
|
134
135
|
onClick: onCancel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Search/Search.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon16SearchOutline, Icon24Cancel } from '@vkontakte/icons';\nimport { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityConditionalRender } from '../../hooks/useAdaptivityConditionalRender';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { touchEnabled } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasDataAttribute, HasRef, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: Partial<IconButtonProps> & HasDataAttribute,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLInputElement> {\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode);\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement>;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement>;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string;\n}\n\n/**\n * @see https://vkui.io/components/search\n */\nexport const Search = ({\n id: idProp,\n before = <Icon16SearchOutline />,\n className,\n placeholder = 'Поиск',\n after = 'Отмена',\n getRef,\n icon: iconProp,\n onIconClick,\n style,\n autoComplete = 'off',\n onChange,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n getRootRef,\n findButtonText = 'Найти',\n findButtonTestId,\n onFindButtonClick,\n ...inputProps\n}: SearchProps): React.ReactNode => {\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n const inputRef = useExternRef(getRef);\n const {\n value: isFocused,\n setTrue: setFocusedTrue,\n setFalse: setFocusedFalse,\n } = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = idProp ? idProp : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputProps.value || inputProps.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { sizeY = 'none' } = useAdaptivity();\n const { sizeY: adaptiveSizeY } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n inputProps.onFocus && inputProps.onFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n inputProps.onBlur && inputProps.onBlur(e);\n };\n\n const onCancel = React.useCallback(() => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n }, [inputRef]);\n\n const onIconClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => onIconClick?.(e),\n [onIconClick],\n );\n\n const onIconCancelClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n e.preventDefault();\n inputRef.current?.focus();\n if (touchEnabled()) {\n onCancel();\n }\n },\n [inputRef, onCancel],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (inputProps.value !== undefined) {\n setHasValue(Boolean(inputProps.value));\n }\n }, [inputProps.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputProps.defaultValue));\n });\n\n const renderIconButton: RenderIconButtonFn = (icon, props = {}) => (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconClickStart}\n className={styles.icon}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n onClick={noop}\n {...props}\n >\n <VisuallyHidden>{iconLabel}</VisuallyHidden>\n {icon}\n </IconButton>\n );\n\n return (\n <div\n className={classNames(\n 'vkuiInternalSearch',\n styles.host,\n sizeY === 'none' && styles.sizeYNone,\n sizeY === 'compact' && styles.sizeYCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputProps.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n className,\n )}\n ref={getRootRef}\n style={style}\n >\n <div className={styles.field}>\n <label htmlFor={inputId} className={styles.label}>\n {placeholder}\n </label>\n <div className={styles.input}>\n {before}\n <Headline\n Component=\"input\"\n type=\"search\"\n level=\"1\"\n weight=\"3\"\n {...inputProps}\n id={inputId}\n placeholder={placeholder}\n autoComplete={autoComplete}\n getRootRef={inputRef}\n className={styles.nativeInput}\n onFocus={onFocus}\n onBlur={onBlur}\n onChange={callMultiple(onChange, checkHasValue)}\n />\n </div>\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconCancelClickStart}\n onClick={onCancel}\n className={styles.icon}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputProps.disabled}\n data-testid={clearButtonTestId}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n {adaptiveSizeY.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveSizeY.compact.className)}\n focusVisibleMode=\"inside\"\n onClick={onFindButtonClick}\n tabIndex={hasValue ? undefined : -1}\n data-testid={findButtonTestId}\n >\n {findButtonText}\n </Button>\n )}\n </div>\n </div>\n {hasAfter && (\n <div className={styles.after}>\n <Button\n mode=\"tertiary\"\n size=\"m\"\n focusVisibleMode=\"inside\"\n hoverMode=\"opacity\"\n activeMode=\"opacity\"\n onClick={onCancel}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n >\n <span className={styles.afterTextClip}>{after}</span>\n </Button>\n </div>\n )}\n </div>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","Button","IconButton","Headline","VisuallyHidden","styles","Search","id","idProp","before","className","placeholder","after","getRef","icon","iconProp","onIconClick","style","autoComplete","onChange","iconLabel","clearLabel","clearButtonTestId","noPadding","getRootRef","findButtonText","findButtonTestId","onFindButtonClick","inputProps","direction","isRtl","inputRef","value","isFocused","setTrue","setFocusedTrue","setFalse","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","defaultValue","checkHasValue","e","currentTarget","sizeY","adaptiveSizeY","platform","hasAfter","onFocus","onBlur","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","onPointerDown","onClick","div","host","sizeYNone","sizeYCompact","focused","hasIcon","disabled","withPadding","rtl","ref","field","label","htmlFor","input","Component","type","level","weight","nativeInput","controls","tabIndex","data-testid","compact","mode","size","findButton","focusVisibleMode","activeMode","span","afterTextClip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Search/Search.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon16Clear, Icon16SearchOutline, Icon24Cancel } from '@vkontakte/icons';\nimport { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityConditionalRender } from '../../hooks/useAdaptivityConditionalRender';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { touchEnabled } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasDataAttribute, HasRef, HasRootRef } from '../../types';\nimport { Button } from '../Button/Button';\nimport { IconButton, type IconButtonProps } from '../IconButton/IconButton';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './Search.module.css';\n\nexport type RenderIconButtonFn = (\n icon: React.ReactNode,\n props?: Partial<IconButtonProps> & HasDataAttribute,\n) => React.ReactElement;\n\nexport interface SearchProps\n extends React.InputHTMLAttributes<HTMLInputElement>,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLInputElement> {\n /**\n * Only iOS. Текст кнопки \"отмена\", которая чистит текстовое поле и убирает фокус.\n */\n after?: React.ReactNode;\n /**\n * Контент, отображаемый перед полем ввода.\n */\n before?: React.ReactNode;\n /**\n * Иконка поиска. Может быть React-элементом или функцией, возвращающей элемент.\n */\n icon?: React.ReactNode | ((renderFn: RenderIconButtonFn) => React.ReactNode);\n /**\n * Обработчик нажатия на иконку поиска.\n */\n onIconClick?: React.PointerEventHandler<HTMLElement>;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultValue?: string;\n /**\n * Текст для скринридеров, описывающий иконку поиска.\n */\n iconLabel?: string;\n /**\n * Текст для скринридеров, описывающий кнопку очистки.\n */\n clearLabel?: string;\n /**\n * Передает атрибут `data-testid` для кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Удаляет отступы у компонента.\n */\n noPadding?: boolean;\n /**\n * Текст для кнопки Найти.\n */\n findButtonText?: string;\n /**\n * Обработчик, при нажатии на кнопку \"Найти\".\n */\n onFindButtonClick?: React.MouseEventHandler<HTMLElement>;\n /**\n * Передает атрибут `data-testid` для кнопки поиска.\n */\n findButtonTestId?: string;\n /**\n * Скрывает кнопку очистки.\n */\n hideClearButton?: boolean;\n}\n\n/**\n * @see https://vkui.io/components/search\n */\nexport const Search = ({\n id: idProp,\n before = <Icon16SearchOutline />,\n className,\n placeholder = 'Поиск',\n after = 'Отмена',\n getRef,\n icon: iconProp,\n onIconClick,\n style,\n autoComplete = 'off',\n onChange,\n iconLabel,\n clearLabel = 'Очистить',\n clearButtonTestId,\n noPadding,\n getRootRef,\n findButtonText = 'Найти',\n findButtonTestId,\n onFindButtonClick,\n hideClearButton,\n ...inputProps\n}: SearchProps): React.ReactNode => {\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n const inputRef = useExternRef(getRef);\n const {\n value: isFocused,\n setTrue: setFocusedTrue,\n setFalse: setFocusedFalse,\n } = useBooleanState(false);\n const generatedId = React.useId();\n const inputId = idProp ? idProp : `search-${generatedId}`;\n\n const [hasValue, setHasValue] = React.useState<boolean>(() =>\n Boolean(inputProps.value || inputProps.defaultValue),\n );\n const checkHasValue: React.ChangeEventHandler<HTMLInputElement> = (e) =>\n setHasValue(Boolean(e.currentTarget.value));\n\n const { sizeY = 'none' } = useAdaptivity();\n const { sizeY: adaptiveSizeY } = useAdaptivityConditionalRender();\n const platform = usePlatform();\n\n const hasAfter = platform === 'ios' && hasReactNode(after);\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedTrue();\n inputProps.onFocus && inputProps.onFocus(e);\n };\n\n const onBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n setFocusedFalse();\n inputProps.onBlur && inputProps.onBlur(e);\n };\n\n const onCancel = React.useCallback(() => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeInputValueSetter?.call(inputRef.current, '');\n\n const ev2 = new Event('input', { bubbles: true });\n inputRef.current?.dispatchEvent(ev2);\n }, [inputRef]);\n\n const onIconClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => onIconClick?.(e),\n [onIconClick],\n );\n\n const onIconCancelClickStart: React.PointerEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n e.preventDefault();\n inputRef.current?.focus();\n if (touchEnabled()) {\n onCancel();\n }\n },\n [inputRef, onCancel],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (inputProps.value !== undefined) {\n setHasValue(Boolean(inputProps.value));\n }\n }, [inputProps.value]);\n\n useNativeFormResetListener(inputRef, () => {\n setHasValue(Boolean(inputProps.defaultValue));\n });\n\n const renderIconButton: RenderIconButtonFn = (icon, props = {}) => (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconClickStart}\n className={styles.icon}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n onClick={noop}\n {...props}\n >\n <VisuallyHidden>{iconLabel}</VisuallyHidden>\n {icon}\n </IconButton>\n );\n\n const showControls = Boolean(\n iconProp || !hideClearButton || (adaptiveSizeY.compact && onFindButtonClick),\n );\n\n return (\n <div\n className={classNames(\n 'vkuiInternalSearch',\n styles.host,\n sizeY === 'none' && styles.sizeYNone,\n sizeY === 'compact' && styles.sizeYCompact,\n isFocused && styles.focused,\n hasValue && styles.hasValue,\n hasAfter && styles.hasAfter,\n iconProp && styles.hasIcon,\n inputProps.disabled && styles.disabled,\n !noPadding && styles.withPadding,\n isRtl && styles.rtl,\n className,\n )}\n ref={getRootRef}\n style={style}\n >\n <div className={styles.field}>\n <label htmlFor={inputId} className={styles.label}>\n {placeholder}\n </label>\n <div className={styles.input}>\n {before}\n <Headline\n Component=\"input\"\n type=\"search\"\n level=\"1\"\n weight=\"3\"\n {...inputProps}\n id={inputId}\n placeholder={placeholder}\n autoComplete={autoComplete}\n getRootRef={inputRef}\n className={styles.nativeInput}\n onFocus={onFocus}\n onBlur={onBlur}\n onChange={callMultiple(onChange, checkHasValue)}\n />\n </div>\n {showControls && (\n <div className={styles.controls}>\n {iconProp &&\n (typeof iconProp === 'function'\n ? iconProp(renderIconButton)\n : renderIconButton(iconProp))}\n {!hideClearButton && (\n <IconButton\n hoverMode=\"opacity\"\n onPointerDown={onIconCancelClickStart}\n onClick={onCancel}\n className={styles.icon}\n tabIndex={hasValue ? undefined : -1}\n disabled={inputProps.disabled}\n data-testid={clearButtonTestId}\n >\n <VisuallyHidden>{clearLabel}</VisuallyHidden>\n {platform === 'ios' ? <Icon16Clear /> : <Icon24Cancel />}\n </IconButton>\n )}\n {adaptiveSizeY.compact && onFindButtonClick && (\n <Button\n mode=\"primary\"\n size=\"m\"\n className={classNames(styles.findButton, adaptiveSizeY.compact.className)}\n focusVisibleMode=\"inside\"\n onClick={onFindButtonClick}\n tabIndex={hasValue ? undefined : -1}\n data-testid={findButtonTestId}\n >\n {findButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n {hasAfter && (\n <div className={styles.after}>\n <Button\n mode=\"tertiary\"\n size=\"m\"\n focusVisibleMode=\"inside\"\n hoverMode=\"opacity\"\n activeMode=\"opacity\"\n onClick={onCancel}\n onFocus={setFocusedTrue}\n onBlur={setFocusedFalse}\n >\n <span className={styles.afterTextClip}>{after}</span>\n </Button>\n </div>\n )}\n </div>\n );\n};\n"],"names":["React","Icon16Clear","Icon16SearchOutline","Icon24Cancel","classNames","hasReactNode","noop","useAdaptivity","useAdaptivityConditionalRender","useBooleanState","useConfigDirection","useExternRef","useNativeFormResetListener","usePlatform","callMultiple","touchEnabled","useIsomorphicLayoutEffect","Button","IconButton","Headline","VisuallyHidden","styles","Search","id","idProp","before","className","placeholder","after","getRef","icon","iconProp","onIconClick","style","autoComplete","onChange","iconLabel","clearLabel","clearButtonTestId","noPadding","getRootRef","findButtonText","findButtonTestId","onFindButtonClick","hideClearButton","inputProps","direction","isRtl","inputRef","value","isFocused","setTrue","setFocusedTrue","setFalse","setFocusedFalse","generatedId","useId","inputId","hasValue","setHasValue","useState","Boolean","defaultValue","checkHasValue","e","currentTarget","sizeY","adaptiveSizeY","platform","hasAfter","onFocus","onBlur","onCancel","useCallback","nativeInputValueSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","current","ev2","Event","bubbles","dispatchEvent","onIconClickStart","onIconCancelClickStart","preventDefault","focus","undefined","renderIconButton","props","hoverMode","onPointerDown","onClick","showControls","compact","div","host","sizeYNone","sizeYCompact","focused","hasIcon","disabled","withPadding","rtl","ref","field","label","htmlFor","input","Component","type","level","weight","nativeInput","controls","tabIndex","data-testid","mode","size","findButton","focusVisibleMode","activeMode","span","afterTextClip"],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { isSameDate } from "@vkontakte/vkjs";
|
|
3
|
-
import { addMonths, startOfDay, subMonths } from "date-fns";
|
|
4
3
|
import { DEFAULT_MAX_YEAR, DEFAULT_MIN_YEAR, isDayMinMaxRestricted } from "../lib/calendar.js";
|
|
5
|
-
import { endOfDay } from "../lib/date.js";
|
|
4
|
+
import { addMonths, endOfDay, startOfDay, subMonths } from "../lib/date.js";
|
|
6
5
|
export function useCalendar({ value, disablePast, disableFuture, shouldDisableDate, onHeaderChange, onNextMonth, onPrevMonth, minDateTime, maxDateTime }) {
|
|
7
6
|
const [viewDate, setViewDate] = React.useState((Array.isArray(value) ? value[0] : value) ?? new Date());
|
|
8
7
|
// соответствует дню, на котором сейчас есть фокус
|