@hh.ru/magritte-internal-drop-base 7.1.17 → 7.1.19

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/DropBase.js CHANGED
@@ -15,7 +15,7 @@ import { ThemeWrapper } from '@hh.ru/magritte-ui-theme-wrapper';
15
15
  import './findBestFitPlacement.js';
16
16
  import './useMonitorResize.js';
17
17
 
18
- var styles = {"drop-base":"magritte-drop-base___uJNG4_7-1-17","dropBase":"magritte-drop-base___uJNG4_7-1-17"};
18
+ var styles = {"drop-base":"magritte-drop-base___uJNG4_7-1-19","dropBase":"magritte-drop-base___uJNG4_7-1-19"};
19
19
 
20
20
  const DropBaseComponent = ({ visible, children, arrowGuardDistance, activatorRef, preferredViewport, onClose, autoFocusWhenOpened = false, closeByClickOutside = true, animationTimeout, animationClassNames, guardDistanceToActivator = 8, guardDistanceToViewport = 24, minHeight = 200, role, widthEqualToActivator = false, allowShrinkHeightToFitIntoViewport = false, keyboardNavigationMode = null, ignoreIntersections = false, style = {}, onAppear, onBeforeExit, onAfterExit, host, placement, forceDropMetricsUpdate, lockPlacement = false, ...props }, ref) => {
21
21
  const dropNodeRef = useRef(null);
package/DropBase.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"DropBase.js","sources":["../src/DropBase.tsx"],"sourcesContent":["import {\n ForwardedRef,\n ReactElement,\n forwardRef,\n useEffect,\n useRef,\n useState,\n MutableRefObject,\n RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { CSSTransition } from 'react-transition-group';\nimport classnames from 'classnames';\n\nimport {\n findNextFocusableElement,\n isTextElement,\n useEscapeToClose,\n useKeyboardNavigation,\n} from '@hh.ru/magritte-common-keyboard';\nimport { useCloseByClickOutside } from '@hh.ru/magritte-common-mouse';\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { useNoBubbling } from '@hh.ru/magritte-common-use-no-bubbling';\nimport { useWhenFontLoaded } from '@hh.ru/magritte-common-use-when-font-loaded';\nimport { useIntersectionSubscription } from '@hh.ru/magritte-internal-drop-base/intersectionManager';\nimport { usePositionManager } from '@hh.ru/magritte-internal-drop-base/positionManager';\nimport type { DropBasePermanentProps } from '@hh.ru/magritte-internal-drop-base/types';\nimport { ThemeWrapper } from '@hh.ru/magritte-ui-theme-wrapper';\n\nimport styles from './styles.less';\n\n// Этот тип описан отдельно, чтобы данный проп не просачивался в Drop и Tooltip\ntype DropMetricsForceUpdateRef = { forceDropMetricsUpdate?: RefObject<VoidFunction> | MutableRefObject<VoidFunction> };\ntype DropBaseComponentProps = DropBasePermanentProps & DropMetricsForceUpdateRef;\n\nconst DropBaseComponent = (\n {\n visible,\n children,\n arrowGuardDistance,\n activatorRef,\n preferredViewport,\n onClose,\n autoFocusWhenOpened = false,\n closeByClickOutside = true,\n animationTimeout,\n animationClassNames,\n guardDistanceToActivator = 8,\n guardDistanceToViewport = 24,\n minHeight = 200,\n role,\n widthEqualToActivator = false,\n allowShrinkHeightToFitIntoViewport = false,\n keyboardNavigationMode = null,\n ignoreIntersections = false,\n style = {},\n onAppear,\n onBeforeExit,\n onAfterExit,\n host,\n placement,\n forceDropMetricsUpdate,\n lockPlacement = false,\n ...props\n }: DropBaseComponentProps,\n ref: ForwardedRef<HTMLElement>\n): ReactElement => {\n const dropNodeRef = useRef<HTMLDivElement>(null);\n const [renderPortal, setRenderPortal] = useState(false);\n const isVisibleDropDown = !!(renderPortal && visible);\n const [lockClickOutside, setLockClickOutside] = useState(true);\n\n useWhenFontLoaded(() => setRenderPortal(true));\n\n const { bestFitPlacementRect, resizeRefCallbackFactory } = usePositionManager(\n activatorRef,\n dropNodeRef,\n isVisibleDropDown,\n placement,\n preferredViewport,\n allowShrinkHeightToFitIntoViewport,\n widthEqualToActivator,\n arrowGuardDistance || {},\n guardDistanceToActivator,\n guardDistanceToViewport,\n minHeight,\n forceDropMetricsUpdate as MutableRefObject<VoidFunction>,\n lockPlacement\n );\n useIntersectionSubscription(activatorRef, isVisibleDropDown, ignoreIntersections, () => {\n onClose?.();\n });\n\n const escapeToCloseRef = useEscapeToClose(onClose);\n const keyboardNavigationRef = useKeyboardNavigation(\n keyboardNavigationMode !== null\n ? { enabled: isVisibleDropDown, mode: keyboardNavigationMode }\n : { enabled: false }\n );\n const dropNodeRefCallback = useMultipleRefs(ref, dropNodeRef, keyboardNavigationRef, escapeToCloseRef);\n\n useCloseByClickOutside(\n dropNodeRef,\n () => {\n if (isVisibleDropDown && !lockClickOutside && activatorRef.current !== document.activeElement) {\n onClose?.();\n }\n },\n closeByClickOutside\n );\n\n const eventHandlers = useNoBubbling(props);\n\n useEffect(() => {\n if (!isVisibleDropDown) {\n setLockClickOutside(true);\n }\n }, [isVisibleDropDown, setLockClickOutside]);\n\n useEffect(() => {\n if (autoFocusWhenOpened && dropNodeRef.current !== null && isVisibleDropDown && !lockClickOutside) {\n const nextFocusableElement = findNextFocusableElement(dropNodeRef.current, null, 'down', 'list');\n const focusedByKeyboard = document.activeElement?.matches(':focus-visible');\n if (nextFocusableElement !== null && (focusedByKeyboard || isTextElement(nextFocusableElement))) {\n nextFocusableElement.focus();\n } else {\n dropNodeRef.current.focus();\n }\n }\n }, [autoFocusWhenOpened, isVisibleDropDown, lockClickOutside]);\n\n return (\n <>\n {renderPortal &&\n createPortal(\n <CSSTransition\n in={visible}\n onEntered={() => {\n setLockClickOutside(false);\n onAppear?.();\n }}\n onExited={onAfterExit}\n onExit={onBeforeExit}\n timeout={animationTimeout}\n classNames={animationClassNames}\n unmountOnExit\n appear\n nodeRef={dropNodeRef}\n >\n <ThemeWrapper>\n {(themeClass) => (\n <div\n {...props}\n {...eventHandlers}\n data-qa=\"drop-base\"\n tabIndex={-1}\n className={classnames(styles.dropBase, themeClass)}\n ref={dropNodeRefCallback}\n style={{\n ...style,\n ...(bestFitPlacementRect || {}),\n }}\n role={role}\n >\n {children(resizeRefCallbackFactory)}\n </div>\n )}\n </ThemeWrapper>\n </CSSTransition>,\n host?.current ?? document.body\n )}\n </>\n );\n};\n\nconst DropBase = forwardRef<HTMLElement, DropBaseComponentProps>(DropBaseComponent);\n\nexport { DropBase };\n"],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"DropBase.js","sources":["src/DropBase.tsx"],"sourcesContent":["import {\n ForwardedRef,\n ReactElement,\n forwardRef,\n useEffect,\n useRef,\n useState,\n MutableRefObject,\n RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { CSSTransition } from 'react-transition-group';\nimport classnames from 'classnames';\n\nimport {\n findNextFocusableElement,\n isTextElement,\n useEscapeToClose,\n useKeyboardNavigation,\n} from '@hh.ru/magritte-common-keyboard';\nimport { useCloseByClickOutside } from '@hh.ru/magritte-common-mouse';\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { useNoBubbling } from '@hh.ru/magritte-common-use-no-bubbling';\nimport { useWhenFontLoaded } from '@hh.ru/magritte-common-use-when-font-loaded';\nimport { useIntersectionSubscription } from '@hh.ru/magritte-internal-drop-base/intersectionManager';\nimport { usePositionManager } from '@hh.ru/magritte-internal-drop-base/positionManager';\nimport type { DropBasePermanentProps } from '@hh.ru/magritte-internal-drop-base/types';\nimport { ThemeWrapper } from '@hh.ru/magritte-ui-theme-wrapper';\n\nimport styles from './styles.less';\n\n// Этот тип описан отдельно, чтобы данный проп не просачивался в Drop и Tooltip\ntype DropMetricsForceUpdateRef = { forceDropMetricsUpdate?: RefObject<VoidFunction> | MutableRefObject<VoidFunction> };\ntype DropBaseComponentProps = DropBasePermanentProps & DropMetricsForceUpdateRef;\n\nconst DropBaseComponent = (\n {\n visible,\n children,\n arrowGuardDistance,\n activatorRef,\n preferredViewport,\n onClose,\n autoFocusWhenOpened = false,\n closeByClickOutside = true,\n animationTimeout,\n animationClassNames,\n guardDistanceToActivator = 8,\n guardDistanceToViewport = 24,\n minHeight = 200,\n role,\n widthEqualToActivator = false,\n allowShrinkHeightToFitIntoViewport = false,\n keyboardNavigationMode = null,\n ignoreIntersections = false,\n style = {},\n onAppear,\n onBeforeExit,\n onAfterExit,\n host,\n placement,\n forceDropMetricsUpdate,\n lockPlacement = false,\n ...props\n }: DropBaseComponentProps,\n ref: ForwardedRef<HTMLElement>\n): ReactElement => {\n const dropNodeRef = useRef<HTMLDivElement>(null);\n const [renderPortal, setRenderPortal] = useState(false);\n const isVisibleDropDown = !!(renderPortal && visible);\n const [lockClickOutside, setLockClickOutside] = useState(true);\n\n useWhenFontLoaded(() => setRenderPortal(true));\n\n const { bestFitPlacementRect, resizeRefCallbackFactory } = usePositionManager(\n activatorRef,\n dropNodeRef,\n isVisibleDropDown,\n placement,\n preferredViewport,\n allowShrinkHeightToFitIntoViewport,\n widthEqualToActivator,\n arrowGuardDistance || {},\n guardDistanceToActivator,\n guardDistanceToViewport,\n minHeight,\n forceDropMetricsUpdate as MutableRefObject<VoidFunction>,\n lockPlacement\n );\n useIntersectionSubscription(activatorRef, isVisibleDropDown, ignoreIntersections, () => {\n onClose?.();\n });\n\n const escapeToCloseRef = useEscapeToClose(onClose);\n const keyboardNavigationRef = useKeyboardNavigation(\n keyboardNavigationMode !== null\n ? { enabled: isVisibleDropDown, mode: keyboardNavigationMode }\n : { enabled: false }\n );\n const dropNodeRefCallback = useMultipleRefs(ref, dropNodeRef, keyboardNavigationRef, escapeToCloseRef);\n\n useCloseByClickOutside(\n dropNodeRef,\n () => {\n if (isVisibleDropDown && !lockClickOutside && activatorRef.current !== document.activeElement) {\n onClose?.();\n }\n },\n closeByClickOutside\n );\n\n const eventHandlers = useNoBubbling(props);\n\n useEffect(() => {\n if (!isVisibleDropDown) {\n setLockClickOutside(true);\n }\n }, [isVisibleDropDown, setLockClickOutside]);\n\n useEffect(() => {\n if (autoFocusWhenOpened && dropNodeRef.current !== null && isVisibleDropDown && !lockClickOutside) {\n const nextFocusableElement = findNextFocusableElement(dropNodeRef.current, null, 'down', 'list');\n const focusedByKeyboard = document.activeElement?.matches(':focus-visible');\n if (nextFocusableElement !== null && (focusedByKeyboard || isTextElement(nextFocusableElement))) {\n nextFocusableElement.focus();\n } else {\n dropNodeRef.current.focus();\n }\n }\n }, [autoFocusWhenOpened, isVisibleDropDown, lockClickOutside]);\n\n return (\n <>\n {renderPortal &&\n createPortal(\n <CSSTransition\n in={visible}\n onEntered={() => {\n setLockClickOutside(false);\n onAppear?.();\n }}\n onExited={onAfterExit}\n onExit={onBeforeExit}\n timeout={animationTimeout}\n classNames={animationClassNames}\n unmountOnExit\n appear\n nodeRef={dropNodeRef}\n >\n <ThemeWrapper>\n {(themeClass) => (\n <div\n {...props}\n {...eventHandlers}\n data-qa=\"drop-base\"\n tabIndex={-1}\n className={classnames(styles.dropBase, themeClass)}\n ref={dropNodeRefCallback}\n style={{\n ...style,\n ...(bestFitPlacementRect || {}),\n }}\n role={role}\n >\n {children(resizeRefCallbackFactory)}\n </div>\n )}\n </ThemeWrapper>\n </CSSTransition>,\n host?.current ?? document.body\n )}\n </>\n );\n};\n\nconst DropBase = forwardRef<HTMLElement, DropBaseComponentProps>(DropBaseComponent);\n\nexport { DropBase };\n"],"names":["_jsx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"findBestFitPlacement.js","sources":["../src/findBestFitPlacement.ts"],"sourcesContent":["import { RefObject } from 'react';\n\nimport {\n ActivatorElementType,\n Placement,\n VerticalDirection,\n HorizontalDirection,\n AlignmentForVerticalDirection,\n AlignmentForHorizontalDirection,\n ArrowGuardDistance,\n ParsedPlacement,\n} from '@hh.ru/magritte-internal-drop-base/types';\n\ninterface GetMetricsFunc {\n (args: {\n activatorRef: RefObject<ActivatorElementType>;\n customViewport?: RefObject<HTMLElement>;\n dropRef: RefObject<HTMLElement>;\n }): {\n activatorRect: DOMRect;\n viewportRect: DOMRect;\n offsetParentRect: DOMRect;\n };\n}\n\nexport const getMetrics: GetMetricsFunc = ({ activatorRef, customViewport, dropRef }) => {\n let activatorRect: DOMRect = new DOMRect();\n\n if (activatorRef.current) {\n activatorRect = activatorRef.current.getBoundingClientRect();\n }\n const viewportRect =\n customViewport && customViewport.current\n ? customViewport.current.getBoundingClientRect()\n : DOMRect.fromRect({\n width: window.visualViewport?.width,\n height: window.visualViewport?.height,\n x: 0,\n y: 0,\n });\n const offsetParentRect = dropRef.current?.offsetParent?.getBoundingClientRect() || new DOMRect();\n\n return { activatorRect, viewportRect, offsetParentRect };\n};\n\nconst parsePlacement = (\n placement: Placement\n): [VerticalDirection | HorizontalDirection, AlignmentForHorizontalDirection | AlignmentForVerticalDirection] => {\n return placement.split('-') as [\n VerticalDirection | HorizontalDirection,\n AlignmentForHorizontalDirection | AlignmentForVerticalDirection,\n ];\n};\n\ntype Rect = { left: number; top: number; width: number; height: number; right: number; bottom: number };\n// Возвращает описание прямоугольника и размеры и позицию правой и нижней стороны, при этом позволяет не указывать\n// в аргументах либо размеры, либо позицию правой и нижней стороны\nconst createRect = (args: {\n left: number;\n top: number;\n width?: number;\n height?: number;\n right?: number;\n bottom?: number;\n}) => ({\n left: args.left,\n top: args.top,\n width: args.width || (args?.right || 0) - args.left,\n height: args.height || (args?.bottom || 0) - args.top,\n right: args.right || (args?.width || 0) + args.left,\n bottom: args.bottom || (args?.height || 0) + args.top,\n});\n\ninterface GetAvailableRectsForPlacementsFunc {\n (args: { placements: Placement[]; activatorRect: DOMRect; viewportRect: DOMRect }): { [key in Placement]: Rect };\n}\n\nconst getAvailableRectsForPlacements: GetAvailableRectsForPlacementsFunc = ({\n placements,\n activatorRect,\n viewportRect,\n}) => {\n // Вычисляем содержащий прямоугольник для свободного пространство с каждой из сторон от активатора\n // https://excalidraw.com/#json=3O9770_G2g6lkJuIftLiQ,2ZRIYkXrSjCpobPS5Ufh7w\n const freeSpaceBySide = {\n top: () =>\n createRect({\n left: viewportRect.x,\n top: viewportRect.y,\n width: viewportRect.width,\n height: activatorRect.top - viewportRect.top,\n }),\n right: () =>\n createRect({\n left: activatorRect.right,\n top: viewportRect.top,\n width: viewportRect.right - activatorRect.right,\n height: viewportRect.height,\n }),\n bottom: () =>\n createRect({\n left: viewportRect.x,\n top: activatorRect.bottom,\n width: viewportRect.width,\n height: viewportRect.bottom - activatorRect.bottom,\n }),\n left: () =>\n createRect({\n left: viewportRect.x,\n top: viewportRect.y,\n width: activatorRect.left - viewportRect.left,\n height: viewportRect.height,\n }),\n };\n\n // Для каждого варианта позиционирования вычисляем содержащий прямоугольник доступного пространства\n // с учетом позиции активатора и границ вьюпорта\n return placements.reduce(\n (acc, placement) => {\n const [direction, alignment] = parsePlacement(placement);\n\n const freeSpace = freeSpaceBySide[direction]();\n acc[placement] = freeSpace;\n\n // Берем свободное пространство с той стороны от активатора куда должен выпасть дроп\n // и устанавливает позицию стороны соответствующей alignment равно позиции той же стороны активатора.\n // На схеме понятнее откуда берется эта логика:\n // https://excalidraw.com/#json=cTKcB__3Oi3U3lF1Z4FLk,6jWpaYZLXePae-FDUbC9PQ\n if (alignment !== 'center') {\n acc[placement][alignment] = activatorRect[alignment];\n acc[placement] = createRect({ ...acc[placement], width: undefined, height: undefined });\n }\n return acc;\n },\n {} as { [key in Placement]: Rect }\n );\n};\n\nconst vertPlacement = ['top', 'bottom'];\nconst axisStartAlignment = ['left', 'top'];\n\nexport interface FindBestFitPlacementFunc {\n (args: {\n /** Список доступных направлений для выпадения, напр.: `['top-left', 'left-bottom']` */\n placements: Placement[];\n /** Содержащий прямоугольник активатора */\n activatorRect: DOMRect;\n /** Содержащий прямоугольник viewport */\n viewportRect: DOMRect;\n /** Содержащий прямоугольник offsetParent дропа */\n offsetParentRect: DOMRect;\n /** Ширина дропа */\n dropWidth: number;\n /** Высота дропа */\n dropHeight: number;\n /** Расстояние от дропа до активатора */\n guardDistanceToActivator: number;\n /** Расстояние от дропа до верхней и нижней границы экрана */\n guardDistanceToViewport: number;\n /** Расстояние от центра стрелки (например в тултипе), до ближайшего края дропа */\n arrowGuardDistance: ArrowGuardDistance;\n /**\n * Минимальная высота дропа, используется для вычисления позиции и размера дропа в случае когда\n * необходимо уместить дроп во `viewport`. Если дроп не умещается во `viewport`, то его высота будет уменьшаться\n * до достижения этого значения. После достижения будет игнорироваться параметр `guardDistanceToViewport`.\n * */\n minDropHeight: number;\n /** Флаг, указывающий что требуется пытаться уместить дроп во viewport за счет изменения его размеров */\n allowShrinkHeightToFitIntoViewport: boolean;\n /** Флаг, указывающий что ширина дропа должна быть равна ширине активатора */\n widthEqualToActivator: boolean;\n /** Позволяет временно отключить изменение расположения, например при открытии экранной клавиатуры */\n lockPlacement?: boolean;\n prefferedPlacement: Placement | undefined;\n }): {\n /** Содержащий прямоугольник выбранного места размещения дропа. Задает позицию и размер дропа */\n rect: DOMRect;\n /**\n * Вариант из списка переданного в параметре `placements` выбранный в качестве\n * наиболее подходящего для размещения дропа\n * */\n parsedPlacement: ParsedPlacement;\n placement: Placement;\n };\n}\n\n/**\n * Функция находит наилучшее расположение для дропа с учетом доступного пространства.\n * Наилучшее расположение выбирается из списка допустимых (`placements`).\n * Алгоритм выбора следующий:\n * - Если дроп полностью умещается на экране при выпадении в соответствующем направлении, то выбирается это направление.\n * - Если таких направлений несколько, то выбирается направление с наименьшим индексом в списке.\n * - Если ни одно из направлений не может полностью уместить дроп, то выбирается направление, которое умещает наибольшую\n * часть дропа по вертикали. Если таких направлений несколько, то среди них выбирается первое направление полностью\n * умещающее дроп по ширине, или умещающее наибольшую часть его ширины.\n */\nexport const findBestFitPlacement: FindBestFitPlacementFunc = ({\n placements,\n activatorRect,\n viewportRect,\n offsetParentRect,\n dropWidth,\n dropHeight,\n guardDistanceToActivator,\n guardDistanceToViewport,\n minDropHeight,\n allowShrinkHeightToFitIntoViewport,\n widthEqualToActivator,\n arrowGuardDistance,\n prefferedPlacement,\n lockPlacement,\n}) => {\n const availablePlacements = getAvailableRectsForPlacements({ placements, activatorRect, viewportRect });\n const actualWidth = widthEqualToActivator ? activatorRect.width : dropWidth;\n\n // Прямоугольники описывающие место необходимое для размещения дропа при вертикальном и горизонтальном размещении.\n // С учетом отступов от активатора и от краев экрана.\n const dropRectForVertPlacement = DOMRect.fromRect({\n x: 0,\n y: 0,\n width: actualWidth,\n height:\n dropHeight + (allowShrinkHeightToFitIntoViewport ? guardDistanceToViewport : 0) + guardDistanceToActivator,\n });\n\n const dropRectForHorPlacement = DOMRect.fromRect({\n x: 0,\n y: 0,\n width: actualWidth + guardDistanceToActivator,\n height: dropHeight + (allowShrinkHeightToFitIntoViewport ? guardDistanceToViewport : 0),\n });\n const viewport = createRect(viewportRect);\n const activator = createRect(activatorRect);\n\n // хранит выбранный лучший вариант размещения, может меняться в процессе перебора вариантов\n let bestFitPlacement = prefferedPlacement || placements[0];\n let bestFitPlacementDistanceToViewportBorder = Number.MIN_SAFE_INTEGER;\n let bestFitPlacementArrowGuardOffset = 0;\n // Минимальная высота необходимая для размещения дропа\n const minHeightToFit = allowShrinkHeightToFitIntoViewport ? minDropHeight + guardDistanceToViewport : dropHeight;\n\n const iterationsCount = prefferedPlacement ? placements.length + 1 : placements.length;\n for (let i = 0, j = lockPlacement && prefferedPlacement ? 1 : iterationsCount; i < j; i++) {\n // Если передан prefferedPlacement, то сначала надо проверить его\n // При этом если он не подошел, то при дальнейшей обработке массива допустимых размещений\n // снова наткнемся на него, в этом случае нужно сразу перейти к следующему элементу\n let placement = placements[i];\n if (prefferedPlacement) {\n if (i === 0) {\n placement = prefferedPlacement;\n } else {\n placement = placements[i - 1];\n if (placement === prefferedPlacement) {\n // eslint-disable-next-line no-continue\n continue;\n }\n }\n }\n const freeSpace = availablePlacements[placement];\n const [direction, alignment] = parsePlacement(placement);\n const isVertPlacement = vertPlacement.includes(direction);\n const dropRect = isVertPlacement ? dropRectForVertPlacement : dropRectForHorPlacement;\n\n /*\n * Если есть стрелка и для нее задан сдвиг, то стрелка должна лежать со стороны от центра активатора равной\n * alignment. Т.е. чтобы соблюсти это правило нужно проверить что сдвиг стрелки меньше или равен половине ширины\n * или высоты активатора в зависимости от направления размещения дропа. Если это не так, то дроп необходимо\n * сдвинуть так, чтобы стрелка была по середине активатора. Это может повлиять на величину пересечения дропа\n * с границей вьюпорта\n */\n const arrowGuardDistanceForPlacement =\n arrowGuardDistance[direction]?.[\n alignment as AlignmentForVerticalDirection & AlignmentForHorizontalDirection\n ];\n let arrowGuardOffset = 0;\n if (\n arrowGuardDistanceForPlacement &&\n arrowGuardDistanceForPlacement > activatorRect[isVertPlacement ? 'width' : 'height'] / 2\n ) {\n arrowGuardOffset = arrowGuardDistanceForPlacement - activatorRect[isVertPlacement ? 'width' : 'height'] / 2;\n }\n\n // Расчитываем расстояние от стороны по которой выравнен дроп до границы вьюпорта\n // Нужно для обработки случаев когда часть активатора уходит за границы экрана, например вниз.\n // В этом случае от нижнего края активатора до границы вьюпорта места больше чем от верхнего края активатора\n // до границы вьюпорта. Но спозиционировать дроп оптимальнее по верхней границе активатора, т.к. в этом случае\n // меньшая часть дропа будет уходить за границы экрана.\n // https://excalidraw.com/#json=V-b0E4ic-4RYECCPfjQ56,gMxZkd6HDGw9kIBksRBylQ\n let distanceToViewportBorder = 0;\n if (alignment !== 'center') {\n distanceToViewportBorder = axisStartAlignment.includes(alignment)\n ? freeSpace[alignment] - viewport[alignment]\n : viewport[alignment] - freeSpace[alignment];\n distanceToViewportBorder -= arrowGuardOffset;\n } else {\n const dropRect = createRect({\n // Т.к. к варианту с alignment=center не применяется изменение размера дропа, то для вычисления\n // пересечения дропа с границами экрана в этом варианте размещения можно использовать прямоугольник\n // размеры которого равны размерам дропа, центр которого расположен в центре активатора.\n left: activator.left - (actualWidth - activator.width) / 2,\n top: activator.top - (dropHeight - activator.height) / 2,\n width: actualWidth,\n height: dropHeight,\n });\n // С разных сторон может быть разная величина пересечения, берем худший вариант.\n distanceToViewportBorder = isVertPlacement\n ? Math.min(dropRect.left - viewport.left, viewport.right - dropRect.right)\n : Math.min(dropRect.top - viewport.top, viewport.bottom - dropRect.bottom);\n }\n\n if (freeSpace.width >= dropRect.width && freeSpace.height >= dropRect.height && distanceToViewportBorder >= 0) {\n bestFitPlacement = placement;\n bestFitPlacementArrowGuardOffset = arrowGuardOffset;\n break;\n }\n\n const currentCanFitByHeight =\n freeSpace.height >= minHeightToFit + (isVertPlacement ? guardDistanceToActivator : 0);\n const currentNotWorseByHeight =\n freeSpace.height >= availablePlacements[bestFitPlacement].height || freeSpace.height >= dropRect.height;\n const currentFitsBetterByHeight =\n availablePlacements[bestFitPlacement].height < dropHeight &&\n freeSpace.height > availablePlacements[bestFitPlacement].height;\n\n const currentNotWorseByWidth =\n freeSpace.width >= availablePlacements[bestFitPlacement].width || freeSpace.width >= dropRect.width;\n const currentFitsBetterByWidth =\n availablePlacements[bestFitPlacement].width < dropRect.width &&\n freeSpace.width > availablePlacements[bestFitPlacement].width;\n\n const currentFitsBetter =\n (currentFitsBetterByHeight && currentNotWorseByWidth && distanceToViewportBorder >= 0) ||\n (currentFitsBetterByWidth && currentNotWorseByHeight && distanceToViewportBorder >= 0) ||\n (currentCanFitByHeight &&\n currentNotWorseByWidth &&\n bestFitPlacementDistanceToViewportBorder < 0 &&\n distanceToViewportBorder > bestFitPlacementDistanceToViewportBorder);\n\n if (currentFitsBetter) {\n bestFitPlacement = placement;\n bestFitPlacementDistanceToViewportBorder = distanceToViewportBorder;\n bestFitPlacementArrowGuardOffset = arrowGuardOffset;\n }\n }\n\n // После того как найден содержащий прямоугольник для дропа вычисляем высоту дропа, затем позицию\n const [direction, alignment] = parsePlacement(bestFitPlacement);\n const freeSpace = availablePlacements[bestFitPlacement];\n const isVertPlacement = vertPlacement.includes(direction);\n const actualHeight =\n allowShrinkHeightToFitIntoViewport && alignment !== 'center'\n ? Math.min(\n dropHeight,\n Math.max(\n minDropHeight,\n freeSpace.height - guardDistanceToViewport - (isVertPlacement ? guardDistanceToActivator : 0)\n )\n )\n : dropHeight;\n\n // Для определения позиции дропа необходимо вычислить left/top, но для некоторых вариантов размещения проще\n // вычислить right/bottom т.к. они совпадают с соответствующими сторонами содержащего прямоугольника.\n // Поэтому сначала проверяем можем ли мы вычислить right/bottom.\n const position: Partial<Rect> = {};\n if (direction === 'left' || alignment === 'right') {\n position.right = freeSpace.right;\n }\n if (direction === 'top' || alignment === 'bottom') {\n position.bottom = freeSpace.bottom;\n }\n // Вычисляем left/top на основе right/bottom и width/height если они есть. Если их нет - значит в этом варианте\n // размещения с содержащим прямоугольником совпадают left/top.\n position.left = position.right !== undefined ? position.right - actualWidth : freeSpace.left;\n position.top = position.bottom !== undefined ? position.bottom - actualHeight : freeSpace.top;\n\n // Отдельно вычисляем позицию/размер для выравнивания по центру\n if (alignment === 'center') {\n const startPosAttr = isVertPlacement ? 'left' : 'top';\n const sizeAttr = isVertPlacement ? 'width' : 'height';\n const dropSize = isVertPlacement ? actualWidth : actualHeight;\n position[startPosAttr] = activatorRect[startPosAttr] + (activatorRect[sizeAttr] - dropSize) / 2;\n }\n\n // Отодвигаем на заданный отступ от активатора\n const signedActivatorOffset = ['bottom', 'right'].includes(direction)\n ? guardDistanceToActivator\n : -guardDistanceToActivator;\n position.top += isVertPlacement ? signedActivatorOffset : 0;\n position.left += !isVertPlacement ? signedActivatorOffset : 0;\n\n position.width = actualWidth;\n position.height = actualHeight;\n // Создаем новую переменную чтобы поменять тип, потому что на этом этапе мы точно знаем что у нас есть эти поля\n // и нет необходимости писать тайпгарды в каждом месте использования\n const finalPosition = position as { left: number; top: number; width: number; height: number };\n\n // Если необходим сдвиг для выравнивания стрелки относительно активатора - применяем его\n if (bestFitPlacementArrowGuardOffset) {\n finalPosition[isVertPlacement ? 'left' : 'top'] += axisStartAlignment.includes(alignment)\n ? -bestFitPlacementArrowGuardOffset\n : bestFitPlacementArrowGuardOffset;\n // Добавляем дополнительно пространство к размеру дропа\n finalPosition[isVertPlacement ? 'height' : 'width'] += bestFitPlacementArrowGuardOffset;\n // Удостоверяемся что после этого размер дропа не превышает размер необходимый для его контента\n finalPosition.height = Math.min(finalPosition.height, dropHeight);\n finalPosition.width = Math.min(finalPosition.width, actualWidth);\n }\n\n return {\n rect: new DOMRect(\n finalPosition.left - offsetParentRect.left, // Переводим координаты в систему координат offsetParent\n finalPosition.top - offsetParentRect.top,\n finalPosition.width,\n finalPosition.height\n ),\n parsedPlacement: { direction, alignment },\n placement: bestFitPlacement,\n };\n};\n\nexport const applyPlacementToDrop = (dropRef: RefObject<HTMLElement>, placement: DOMRect): void => {\n if (!dropRef.current) {\n return;\n }\n\n dropRef.current.style.top = `${placement.top}px`;\n dropRef.current.style.left = `${placement.left}px`;\n dropRef.current.style.width = `${placement.width}px`;\n dropRef.current.style.height = `${placement.height}px`;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"findBestFitPlacement.js","sources":["src/findBestFitPlacement.ts"],"sourcesContent":["import { RefObject } from 'react';\n\nimport {\n ActivatorElementType,\n Placement,\n VerticalDirection,\n HorizontalDirection,\n AlignmentForVerticalDirection,\n AlignmentForHorizontalDirection,\n ArrowGuardDistance,\n ParsedPlacement,\n} from '@hh.ru/magritte-internal-drop-base/types';\n\ninterface GetMetricsFunc {\n (args: {\n activatorRef: RefObject<ActivatorElementType>;\n customViewport?: RefObject<HTMLElement>;\n dropRef: RefObject<HTMLElement>;\n }): {\n activatorRect: DOMRect;\n viewportRect: DOMRect;\n offsetParentRect: DOMRect;\n };\n}\n\nexport const getMetrics: GetMetricsFunc = ({ activatorRef, customViewport, dropRef }) => {\n let activatorRect: DOMRect = new DOMRect();\n\n if (activatorRef.current) {\n activatorRect = activatorRef.current.getBoundingClientRect();\n }\n const viewportRect =\n customViewport && customViewport.current\n ? customViewport.current.getBoundingClientRect()\n : DOMRect.fromRect({\n width: window.visualViewport?.width,\n height: window.visualViewport?.height,\n x: 0,\n y: 0,\n });\n const offsetParentRect = dropRef.current?.offsetParent?.getBoundingClientRect() || new DOMRect();\n\n return { activatorRect, viewportRect, offsetParentRect };\n};\n\nconst parsePlacement = (\n placement: Placement\n): [VerticalDirection | HorizontalDirection, AlignmentForHorizontalDirection | AlignmentForVerticalDirection] => {\n return placement.split('-') as [\n VerticalDirection | HorizontalDirection,\n AlignmentForHorizontalDirection | AlignmentForVerticalDirection,\n ];\n};\n\ntype Rect = { left: number; top: number; width: number; height: number; right: number; bottom: number };\n// Возвращает описание прямоугольника и размеры и позицию правой и нижней стороны, при этом позволяет не указывать\n// в аргументах либо размеры, либо позицию правой и нижней стороны\nconst createRect = (args: {\n left: number;\n top: number;\n width?: number;\n height?: number;\n right?: number;\n bottom?: number;\n}) => ({\n left: args.left,\n top: args.top,\n width: args.width || (args?.right || 0) - args.left,\n height: args.height || (args?.bottom || 0) - args.top,\n right: args.right || (args?.width || 0) + args.left,\n bottom: args.bottom || (args?.height || 0) + args.top,\n});\n\ninterface GetAvailableRectsForPlacementsFunc {\n (args: { placements: Placement[]; activatorRect: DOMRect; viewportRect: DOMRect }): { [key in Placement]: Rect };\n}\n\nconst getAvailableRectsForPlacements: GetAvailableRectsForPlacementsFunc = ({\n placements,\n activatorRect,\n viewportRect,\n}) => {\n // Вычисляем содержащий прямоугольник для свободного пространство с каждой из сторон от активатора\n // https://excalidraw.com/#json=3O9770_G2g6lkJuIftLiQ,2ZRIYkXrSjCpobPS5Ufh7w\n const freeSpaceBySide = {\n top: () =>\n createRect({\n left: viewportRect.x,\n top: viewportRect.y,\n width: viewportRect.width,\n height: activatorRect.top - viewportRect.top,\n }),\n right: () =>\n createRect({\n left: activatorRect.right,\n top: viewportRect.top,\n width: viewportRect.right - activatorRect.right,\n height: viewportRect.height,\n }),\n bottom: () =>\n createRect({\n left: viewportRect.x,\n top: activatorRect.bottom,\n width: viewportRect.width,\n height: viewportRect.bottom - activatorRect.bottom,\n }),\n left: () =>\n createRect({\n left: viewportRect.x,\n top: viewportRect.y,\n width: activatorRect.left - viewportRect.left,\n height: viewportRect.height,\n }),\n };\n\n // Для каждого варианта позиционирования вычисляем содержащий прямоугольник доступного пространства\n // с учетом позиции активатора и границ вьюпорта\n return placements.reduce(\n (acc, placement) => {\n const [direction, alignment] = parsePlacement(placement);\n\n const freeSpace = freeSpaceBySide[direction]();\n acc[placement] = freeSpace;\n\n // Берем свободное пространство с той стороны от активатора куда должен выпасть дроп\n // и устанавливает позицию стороны соответствующей alignment равно позиции той же стороны активатора.\n // На схеме понятнее откуда берется эта логика:\n // https://excalidraw.com/#json=cTKcB__3Oi3U3lF1Z4FLk,6jWpaYZLXePae-FDUbC9PQ\n if (alignment !== 'center') {\n acc[placement][alignment] = activatorRect[alignment];\n acc[placement] = createRect({ ...acc[placement], width: undefined, height: undefined });\n }\n return acc;\n },\n {} as { [key in Placement]: Rect }\n );\n};\n\nconst vertPlacement = ['top', 'bottom'];\nconst axisStartAlignment = ['left', 'top'];\n\nexport interface FindBestFitPlacementFunc {\n (args: {\n /** Список доступных направлений для выпадения, напр.: `['top-left', 'left-bottom']` */\n placements: Placement[];\n /** Содержащий прямоугольник активатора */\n activatorRect: DOMRect;\n /** Содержащий прямоугольник viewport */\n viewportRect: DOMRect;\n /** Содержащий прямоугольник offsetParent дропа */\n offsetParentRect: DOMRect;\n /** Ширина дропа */\n dropWidth: number;\n /** Высота дропа */\n dropHeight: number;\n /** Расстояние от дропа до активатора */\n guardDistanceToActivator: number;\n /** Расстояние от дропа до верхней и нижней границы экрана */\n guardDistanceToViewport: number;\n /** Расстояние от центра стрелки (например в тултипе), до ближайшего края дропа */\n arrowGuardDistance: ArrowGuardDistance;\n /**\n * Минимальная высота дропа, используется для вычисления позиции и размера дропа в случае когда\n * необходимо уместить дроп во `viewport`. Если дроп не умещается во `viewport`, то его высота будет уменьшаться\n * до достижения этого значения. После достижения будет игнорироваться параметр `guardDistanceToViewport`.\n * */\n minDropHeight: number;\n /** Флаг, указывающий что требуется пытаться уместить дроп во viewport за счет изменения его размеров */\n allowShrinkHeightToFitIntoViewport: boolean;\n /** Флаг, указывающий что ширина дропа должна быть равна ширине активатора */\n widthEqualToActivator: boolean;\n /** Позволяет временно отключить изменение расположения, например при открытии экранной клавиатуры */\n lockPlacement?: boolean;\n prefferedPlacement: Placement | undefined;\n }): {\n /** Содержащий прямоугольник выбранного места размещения дропа. Задает позицию и размер дропа */\n rect: DOMRect;\n /**\n * Вариант из списка переданного в параметре `placements` выбранный в качестве\n * наиболее подходящего для размещения дропа\n * */\n parsedPlacement: ParsedPlacement;\n placement: Placement;\n };\n}\n\n/**\n * Функция находит наилучшее расположение для дропа с учетом доступного пространства.\n * Наилучшее расположение выбирается из списка допустимых (`placements`).\n * Алгоритм выбора следующий:\n * - Если дроп полностью умещается на экране при выпадении в соответствующем направлении, то выбирается это направление.\n * - Если таких направлений несколько, то выбирается направление с наименьшим индексом в списке.\n * - Если ни одно из направлений не может полностью уместить дроп, то выбирается направление, которое умещает наибольшую\n * часть дропа по вертикали. Если таких направлений несколько, то среди них выбирается первое направление полностью\n * умещающее дроп по ширине, или умещающее наибольшую часть его ширины.\n */\nexport const findBestFitPlacement: FindBestFitPlacementFunc = ({\n placements,\n activatorRect,\n viewportRect,\n offsetParentRect,\n dropWidth,\n dropHeight,\n guardDistanceToActivator,\n guardDistanceToViewport,\n minDropHeight,\n allowShrinkHeightToFitIntoViewport,\n widthEqualToActivator,\n arrowGuardDistance,\n prefferedPlacement,\n lockPlacement,\n}) => {\n const availablePlacements = getAvailableRectsForPlacements({ placements, activatorRect, viewportRect });\n const actualWidth = widthEqualToActivator ? activatorRect.width : dropWidth;\n\n // Прямоугольники описывающие место необходимое для размещения дропа при вертикальном и горизонтальном размещении.\n // С учетом отступов от активатора и от краев экрана.\n const dropRectForVertPlacement = DOMRect.fromRect({\n x: 0,\n y: 0,\n width: actualWidth,\n height:\n dropHeight + (allowShrinkHeightToFitIntoViewport ? guardDistanceToViewport : 0) + guardDistanceToActivator,\n });\n\n const dropRectForHorPlacement = DOMRect.fromRect({\n x: 0,\n y: 0,\n width: actualWidth + guardDistanceToActivator,\n height: dropHeight + (allowShrinkHeightToFitIntoViewport ? guardDistanceToViewport : 0),\n });\n const viewport = createRect(viewportRect);\n const activator = createRect(activatorRect);\n\n // хранит выбранный лучший вариант размещения, может меняться в процессе перебора вариантов\n let bestFitPlacement = prefferedPlacement || placements[0];\n let bestFitPlacementDistanceToViewportBorder = Number.MIN_SAFE_INTEGER;\n let bestFitPlacementArrowGuardOffset = 0;\n // Минимальная высота необходимая для размещения дропа\n const minHeightToFit = allowShrinkHeightToFitIntoViewport ? minDropHeight + guardDistanceToViewport : dropHeight;\n\n const iterationsCount = prefferedPlacement ? placements.length + 1 : placements.length;\n for (let i = 0, j = lockPlacement && prefferedPlacement ? 1 : iterationsCount; i < j; i++) {\n // Если передан prefferedPlacement, то сначала надо проверить его\n // При этом если он не подошел, то при дальнейшей обработке массива допустимых размещений\n // снова наткнемся на него, в этом случае нужно сразу перейти к следующему элементу\n let placement = placements[i];\n if (prefferedPlacement) {\n if (i === 0) {\n placement = prefferedPlacement;\n } else {\n placement = placements[i - 1];\n if (placement === prefferedPlacement) {\n // eslint-disable-next-line no-continue\n continue;\n }\n }\n }\n const freeSpace = availablePlacements[placement];\n const [direction, alignment] = parsePlacement(placement);\n const isVertPlacement = vertPlacement.includes(direction);\n const dropRect = isVertPlacement ? dropRectForVertPlacement : dropRectForHorPlacement;\n\n /*\n * Если есть стрелка и для нее задан сдвиг, то стрелка должна лежать со стороны от центра активатора равной\n * alignment. Т.е. чтобы соблюсти это правило нужно проверить что сдвиг стрелки меньше или равен половине ширины\n * или высоты активатора в зависимости от направления размещения дропа. Если это не так, то дроп необходимо\n * сдвинуть так, чтобы стрелка была по середине активатора. Это может повлиять на величину пересечения дропа\n * с границей вьюпорта\n */\n const arrowGuardDistanceForPlacement =\n arrowGuardDistance[direction]?.[\n alignment as AlignmentForVerticalDirection & AlignmentForHorizontalDirection\n ];\n let arrowGuardOffset = 0;\n if (\n arrowGuardDistanceForPlacement &&\n arrowGuardDistanceForPlacement > activatorRect[isVertPlacement ? 'width' : 'height'] / 2\n ) {\n arrowGuardOffset = arrowGuardDistanceForPlacement - activatorRect[isVertPlacement ? 'width' : 'height'] / 2;\n }\n\n // Расчитываем расстояние от стороны по которой выравнен дроп до границы вьюпорта\n // Нужно для обработки случаев когда часть активатора уходит за границы экрана, например вниз.\n // В этом случае от нижнего края активатора до границы вьюпорта места больше чем от верхнего края активатора\n // до границы вьюпорта. Но спозиционировать дроп оптимальнее по верхней границе активатора, т.к. в этом случае\n // меньшая часть дропа будет уходить за границы экрана.\n // https://excalidraw.com/#json=V-b0E4ic-4RYECCPfjQ56,gMxZkd6HDGw9kIBksRBylQ\n let distanceToViewportBorder = 0;\n if (alignment !== 'center') {\n distanceToViewportBorder = axisStartAlignment.includes(alignment)\n ? freeSpace[alignment] - viewport[alignment]\n : viewport[alignment] - freeSpace[alignment];\n distanceToViewportBorder -= arrowGuardOffset;\n } else {\n const dropRect = createRect({\n // Т.к. к варианту с alignment=center не применяется изменение размера дропа, то для вычисления\n // пересечения дропа с границами экрана в этом варианте размещения можно использовать прямоугольник\n // размеры которого равны размерам дропа, центр которого расположен в центре активатора.\n left: activator.left - (actualWidth - activator.width) / 2,\n top: activator.top - (dropHeight - activator.height) / 2,\n width: actualWidth,\n height: dropHeight,\n });\n // С разных сторон может быть разная величина пересечения, берем худший вариант.\n distanceToViewportBorder = isVertPlacement\n ? Math.min(dropRect.left - viewport.left, viewport.right - dropRect.right)\n : Math.min(dropRect.top - viewport.top, viewport.bottom - dropRect.bottom);\n }\n\n if (freeSpace.width >= dropRect.width && freeSpace.height >= dropRect.height && distanceToViewportBorder >= 0) {\n bestFitPlacement = placement;\n bestFitPlacementArrowGuardOffset = arrowGuardOffset;\n break;\n }\n\n const currentCanFitByHeight =\n freeSpace.height >= minHeightToFit + (isVertPlacement ? guardDistanceToActivator : 0);\n const currentNotWorseByHeight =\n freeSpace.height >= availablePlacements[bestFitPlacement].height || freeSpace.height >= dropRect.height;\n const currentFitsBetterByHeight =\n availablePlacements[bestFitPlacement].height < dropHeight &&\n freeSpace.height > availablePlacements[bestFitPlacement].height;\n\n const currentNotWorseByWidth =\n freeSpace.width >= availablePlacements[bestFitPlacement].width || freeSpace.width >= dropRect.width;\n const currentFitsBetterByWidth =\n availablePlacements[bestFitPlacement].width < dropRect.width &&\n freeSpace.width > availablePlacements[bestFitPlacement].width;\n\n const currentFitsBetter =\n (currentFitsBetterByHeight && currentNotWorseByWidth && distanceToViewportBorder >= 0) ||\n (currentFitsBetterByWidth && currentNotWorseByHeight && distanceToViewportBorder >= 0) ||\n (currentCanFitByHeight &&\n currentNotWorseByWidth &&\n bestFitPlacementDistanceToViewportBorder < 0 &&\n distanceToViewportBorder > bestFitPlacementDistanceToViewportBorder);\n\n if (currentFitsBetter) {\n bestFitPlacement = placement;\n bestFitPlacementDistanceToViewportBorder = distanceToViewportBorder;\n bestFitPlacementArrowGuardOffset = arrowGuardOffset;\n }\n }\n\n // После того как найден содержащий прямоугольник для дропа вычисляем высоту дропа, затем позицию\n const [direction, alignment] = parsePlacement(bestFitPlacement);\n const freeSpace = availablePlacements[bestFitPlacement];\n const isVertPlacement = vertPlacement.includes(direction);\n const actualHeight =\n allowShrinkHeightToFitIntoViewport && alignment !== 'center'\n ? Math.min(\n dropHeight,\n Math.max(\n minDropHeight,\n freeSpace.height - guardDistanceToViewport - (isVertPlacement ? guardDistanceToActivator : 0)\n )\n )\n : dropHeight;\n\n // Для определения позиции дропа необходимо вычислить left/top, но для некоторых вариантов размещения проще\n // вычислить right/bottom т.к. они совпадают с соответствующими сторонами содержащего прямоугольника.\n // Поэтому сначала проверяем можем ли мы вычислить right/bottom.\n const position: Partial<Rect> = {};\n if (direction === 'left' || alignment === 'right') {\n position.right = freeSpace.right;\n }\n if (direction === 'top' || alignment === 'bottom') {\n position.bottom = freeSpace.bottom;\n }\n // Вычисляем left/top на основе right/bottom и width/height если они есть. Если их нет - значит в этом варианте\n // размещения с содержащим прямоугольником совпадают left/top.\n position.left = position.right !== undefined ? position.right - actualWidth : freeSpace.left;\n position.top = position.bottom !== undefined ? position.bottom - actualHeight : freeSpace.top;\n\n // Отдельно вычисляем позицию/размер для выравнивания по центру\n if (alignment === 'center') {\n const startPosAttr = isVertPlacement ? 'left' : 'top';\n const sizeAttr = isVertPlacement ? 'width' : 'height';\n const dropSize = isVertPlacement ? actualWidth : actualHeight;\n position[startPosAttr] = activatorRect[startPosAttr] + (activatorRect[sizeAttr] - dropSize) / 2;\n }\n\n // Отодвигаем на заданный отступ от активатора\n const signedActivatorOffset = ['bottom', 'right'].includes(direction)\n ? guardDistanceToActivator\n : -guardDistanceToActivator;\n position.top += isVertPlacement ? signedActivatorOffset : 0;\n position.left += !isVertPlacement ? signedActivatorOffset : 0;\n\n position.width = actualWidth;\n position.height = actualHeight;\n // Создаем новую переменную чтобы поменять тип, потому что на этом этапе мы точно знаем что у нас есть эти поля\n // и нет необходимости писать тайпгарды в каждом месте использования\n const finalPosition = position as { left: number; top: number; width: number; height: number };\n\n // Если необходим сдвиг для выравнивания стрелки относительно активатора - применяем его\n if (bestFitPlacementArrowGuardOffset) {\n finalPosition[isVertPlacement ? 'left' : 'top'] += axisStartAlignment.includes(alignment)\n ? -bestFitPlacementArrowGuardOffset\n : bestFitPlacementArrowGuardOffset;\n // Добавляем дополнительно пространство к размеру дропа\n finalPosition[isVertPlacement ? 'height' : 'width'] += bestFitPlacementArrowGuardOffset;\n // Удостоверяемся что после этого размер дропа не превышает размер необходимый для его контента\n finalPosition.height = Math.min(finalPosition.height, dropHeight);\n finalPosition.width = Math.min(finalPosition.width, actualWidth);\n }\n\n return {\n rect: new DOMRect(\n finalPosition.left - offsetParentRect.left, // Переводим координаты в систему координат offsetParent\n finalPosition.top - offsetParentRect.top,\n finalPosition.width,\n finalPosition.height\n ),\n parsedPlacement: { direction, alignment },\n placement: bestFitPlacement,\n };\n};\n\nexport const applyPlacementToDrop = (dropRef: RefObject<HTMLElement>, placement: DOMRect): void => {\n if (!dropRef.current) {\n return;\n }\n\n dropRef.current.style.top = `${placement.top}px`;\n dropRef.current.style.left = `${placement.left}px`;\n dropRef.current.style.width = `${placement.width}px`;\n dropRef.current.style.height = `${placement.height}px`;\n};\n"],"names":[],"mappings":"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"}
package/index.css CHANGED
@@ -1,4 +1,4 @@
1
- .magritte-drop-base___uJNG4_7-1-17{
1
+ .magritte-drop-base___uJNG4_7-1-19{
2
2
  position:absolute;
3
3
  outline:none;
4
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"intersectionManager.js","sources":["../src/intersectionManager.ts"],"sourcesContent":["import { RefObject, useCallback, useEffect, useRef } from 'react';\n\nimport { ActivatorElementType } from '@hh.ru/magritte-internal-drop-base/types';\n\n// теоретически на один активатор может быть завязано несколько дропов (например дроп и тултип)\n// поэтому храним коллекцию коллбеков для каждого активатора\nconst intersectionCallbacks = new Map<ActivatorElementType, VoidFunction[]>();\nlet observer: IntersectionObserver;\n// Т.к. IntersectionObserver при первом вызове observe(element) сразу вызывает коллбек для элемента\n// необходимо игнорировать первый вызов коллбека после вызова observe, т.к. о изменении состояния сигнализирует только\n// второй вызов коллбека. Для этого используем set элементов, для которых был вызван observe, но еще не был вызван коллбек\nconst ignoreImmediateCallback = new Set<ActivatorElementType>();\n\nconst notifyAndClearSubscriptions = (element: HTMLElement) => {\n if (ignoreImmediateCallback.has(element)) {\n ignoreImmediateCallback.delete(element);\n return;\n }\n const callbacks = intersectionCallbacks.get(element);\n if (callbacks) {\n callbacks.forEach((callback) => callback());\n }\n intersectionCallbacks.delete(element);\n observer.unobserve(element);\n};\n\nconst initialize = () => {\n if (observer) {\n return;\n }\n\n observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n notifyAndClearSubscriptions(entry.target as HTMLElement);\n });\n });\n};\n\nconst observeIntersectionsOfElement = (element: ActivatorElementType, callback: VoidFunction) => {\n initialize();\n if (!intersectionCallbacks.has(element)) {\n intersectionCallbacks.set(element, []);\n ignoreImmediateCallback.add(element);\n observer.observe(element);\n }\n intersectionCallbacks.get(element)?.push(callback);\n};\n\nconst unobserveIntersectionsOfElement = (element: ActivatorElementType | null, callback: VoidFunction) => {\n if (!element) {\n return;\n }\n const callbacks = intersectionCallbacks.get(element);\n if (!callbacks) {\n return;\n }\n const filteredCallbacks = callbacks.filter((cb) => cb !== callback);\n if (filteredCallbacks.length === 0) {\n intersectionCallbacks.delete(element);\n observer.unobserve(element);\n return;\n }\n\n intersectionCallbacks.set(element, filteredCallbacks);\n};\n\nexport const useIntersectionSubscription = (\n activatorRef: RefObject<ActivatorElementType>,\n isVisible: boolean,\n ignore: boolean,\n callback: VoidFunction\n): void => {\n const intersectionCallbackRef = useRef(callback);\n intersectionCallbackRef.current = callback;\n\n const intersectionCallback = useCallback(() => intersectionCallbackRef.current(), []);\n\n useEffect(() => {\n if (!activatorRef.current || !isVisible || ignore) {\n return;\n }\n const target = activatorRef.current;\n observeIntersectionsOfElement(target, intersectionCallback);\n // eslint-disable-next-line consistent-return\n return () => {\n unobserveIntersectionsOfElement(target, intersectionCallback);\n };\n }, [isVisible, activatorRef, intersectionCallback, ignore]);\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"intersectionManager.js","sources":["src/intersectionManager.ts"],"sourcesContent":["import { RefObject, useCallback, useEffect, useRef } from 'react';\n\nimport { ActivatorElementType } from '@hh.ru/magritte-internal-drop-base/types';\n\n// теоретически на один активатор может быть завязано несколько дропов (например дроп и тултип)\n// поэтому храним коллекцию коллбеков для каждого активатора\nconst intersectionCallbacks = new Map<ActivatorElementType, VoidFunction[]>();\nlet observer: IntersectionObserver;\n// Т.к. IntersectionObserver при первом вызове observe(element) сразу вызывает коллбек для элемента\n// необходимо игнорировать первый вызов коллбека после вызова observe, т.к. о изменении состояния сигнализирует только\n// второй вызов коллбека. Для этого используем set элементов, для которых был вызван observe, но еще не был вызван коллбек\nconst ignoreImmediateCallback = new Set<ActivatorElementType>();\n\nconst notifyAndClearSubscriptions = (element: HTMLElement) => {\n if (ignoreImmediateCallback.has(element)) {\n ignoreImmediateCallback.delete(element);\n return;\n }\n const callbacks = intersectionCallbacks.get(element);\n if (callbacks) {\n callbacks.forEach((callback) => callback());\n }\n intersectionCallbacks.delete(element);\n observer.unobserve(element);\n};\n\nconst initialize = () => {\n if (observer) {\n return;\n }\n\n observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n notifyAndClearSubscriptions(entry.target as HTMLElement);\n });\n });\n};\n\nconst observeIntersectionsOfElement = (element: ActivatorElementType, callback: VoidFunction) => {\n initialize();\n if (!intersectionCallbacks.has(element)) {\n intersectionCallbacks.set(element, []);\n ignoreImmediateCallback.add(element);\n observer.observe(element);\n }\n intersectionCallbacks.get(element)?.push(callback);\n};\n\nconst unobserveIntersectionsOfElement = (element: ActivatorElementType | null, callback: VoidFunction) => {\n if (!element) {\n return;\n }\n const callbacks = intersectionCallbacks.get(element);\n if (!callbacks) {\n return;\n }\n const filteredCallbacks = callbacks.filter((cb) => cb !== callback);\n if (filteredCallbacks.length === 0) {\n intersectionCallbacks.delete(element);\n observer.unobserve(element);\n return;\n }\n\n intersectionCallbacks.set(element, filteredCallbacks);\n};\n\nexport const useIntersectionSubscription = (\n activatorRef: RefObject<ActivatorElementType>,\n isVisible: boolean,\n ignore: boolean,\n callback: VoidFunction\n): void => {\n const intersectionCallbackRef = useRef(callback);\n intersectionCallbackRef.current = callback;\n\n const intersectionCallback = useCallback(() => intersectionCallbackRef.current(), []);\n\n useEffect(() => {\n if (!activatorRef.current || !isVisible || ignore) {\n return;\n }\n const target = activatorRef.current;\n observeIntersectionsOfElement(target, intersectionCallback);\n // eslint-disable-next-line consistent-return\n return () => {\n unobserveIntersectionsOfElement(target, intersectionCallback);\n };\n }, [isVisible, activatorRef, intersectionCallback, ignore]);\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hh.ru/magritte-internal-drop-base",
3
- "version": "7.1.17",
3
+ "version": "7.1.19",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "sideEffects": [
@@ -19,12 +19,12 @@
19
19
  "watch": "yarn root:watch $(pwd)"
20
20
  },
21
21
  "dependencies": {
22
- "@hh.ru/magritte-common-keyboard": "4.3.0",
23
- "@hh.ru/magritte-common-mouse": "1.1.18",
24
- "@hh.ru/magritte-common-use-multiple-refs": "1.1.10",
25
- "@hh.ru/magritte-common-use-no-bubbling": "1.0.7",
26
- "@hh.ru/magritte-common-use-when-font-loaded": "1.0.13",
27
- "@hh.ru/magritte-ui-theme-wrapper": "1.1.11"
22
+ "@hh.ru/magritte-common-keyboard": "4.3.1",
23
+ "@hh.ru/magritte-common-mouse": "1.1.19",
24
+ "@hh.ru/magritte-common-use-multiple-refs": "1.1.11",
25
+ "@hh.ru/magritte-common-use-no-bubbling": "1.0.8",
26
+ "@hh.ru/magritte-common-use-when-font-loaded": "1.0.14",
27
+ "@hh.ru/magritte-ui-theme-wrapper": "1.1.13"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "classnames": "2.3.2",
@@ -35,5 +35,5 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "dbdbcad65f9d7dc14f074ed3e1e83a48d1ef832c"
38
+ "gitHead": "773d4352b733cf17fd5c2e1a5eb0a047d63fd8a0"
39
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"positionManager.js","sources":["../src/positionManager.ts"],"sourcesContent":["import { RefObject, useCallback, useEffect, useRef, useLayoutEffect, MutableRefObject } from 'react';\n\nimport {\n findBestFitPlacement,\n getMetrics,\n applyPlacementToDrop,\n} from '@hh.ru/magritte-internal-drop-base/findBestFitPlacement';\nimport type {\n ArrowGuardDistance,\n ActivatorElementType,\n Placement,\n RefCallbackFactory,\n} from '@hh.ru/magritte-internal-drop-base/types';\nimport { useMonitorResize } from '@hh.ru/magritte-internal-drop-base/useMonitorResize';\n\nlet isInitialized = false;\n\ninterface SubscriptionCallback {\n (target: HTMLElement): void;\n}\n\nconst scrollSubscriptions: Array<SubscriptionCallback> = [];\nconst canceledScrollSubscriptions: Map<HTMLElement, Array<SubscriptionCallback>> = new Map();\n\nconst scrollHandler = (event: Event) => {\n const target = event.target as HTMLElement;\n if (!target) {\n return;\n }\n\n if (scrollSubscriptions.length === 0) {\n return;\n }\n const canceledSubscriptions = canceledScrollSubscriptions.get(target);\n\n const subscriptions =\n canceledSubscriptions === undefined\n ? scrollSubscriptions\n : scrollSubscriptions.filter((subscription) => !canceledSubscriptions.includes(subscription));\n\n subscriptions.forEach((subscription) => subscription(target));\n};\n\nconst initialize = () => {\n if (isInitialized) {\n return;\n }\n\n isInitialized = true;\n document.addEventListener('scroll', scrollHandler, { capture: true, passive: false });\n};\n\nconst suspendSubscription = (callback: SubscriptionCallback): void => {\n const index = scrollSubscriptions.indexOf(callback);\n if (index !== -1) {\n scrollSubscriptions.splice(index, 1);\n }\n};\n\nconst reviveSubscription = (callback: SubscriptionCallback): void => {\n initialize();\n scrollSubscriptions.push(callback);\n};\n\nexport const deleteScrollSubscription = (callback: SubscriptionCallback): void => {\n const index = scrollSubscriptions.indexOf(callback);\n if (index !== -1) {\n scrollSubscriptions.splice(index, 1);\n }\n for (const [target, callbacks] of canceledScrollSubscriptions.entries()) {\n const index = callbacks.indexOf(callback);\n if (index !== -1) {\n const updatedCallbacks = callbacks.splice(index, 1);\n if (updatedCallbacks.length > 0) {\n canceledScrollSubscriptions.set(target, updatedCallbacks);\n } else {\n canceledScrollSubscriptions.delete(target);\n }\n }\n }\n};\n\nconst unsubscribeFromTarget = (target: HTMLElement, callback: SubscriptionCallback): void => {\n if (!canceledScrollSubscriptions.has(target)) {\n canceledScrollSubscriptions.set(target, []);\n }\n canceledScrollSubscriptions.get(target)?.push(callback);\n};\n\nexport const usePositionManager = (\n activatorRef: RefObject<ActivatorElementType>,\n dropRef: RefObject<HTMLElement>,\n isVisible: boolean,\n placement: Placement | Placement[],\n customViewport: RefObject<HTMLElement> | undefined,\n allowShrinkHeightToFitIntoViewport: boolean,\n widthEqualToActivator: boolean,\n arrowGuardDistance: ArrowGuardDistance,\n guardDistanceToActivator: number,\n guardDistanceToViewport: number,\n minDropHeight: number,\n forceDropMetricsUpdate: MutableRefObject<VoidFunction> | undefined,\n lockPlacement = false\n): {\n resizeRefCallbackFactory: RefCallbackFactory;\n bestFitPlacementRect: DOMRect | undefined;\n} => {\n const bestFitPlacementRef = useRef<DOMRect>();\n const dropMetricsRef = useRef<DOMRect>();\n\n const prefferedPlacementRef = useRef<Placement>();\n\n const updateMetricsSyncRef = useRef<VoidFunction>(() => void 0);\n\n const { getResizeObserver, observeResizeRefCallbackFactory, getObservedElementsInfoMap } = useMonitorResize(\n dropMetricsRef,\n updateMetricsSyncRef\n );\n\n const getDropMetrics = useCallback(\n (activatorRect: DOMRect, widthEqualToActivator: boolean) => {\n if (dropMetricsRef.current) {\n return dropMetricsRef.current;\n }\n if (!dropRef.current) {\n return new DOMRect();\n }\n\n const scrollPositions: { node: HTMLElement; top: number; left: number }[] = [];\n for (const info of getObservedElementsInfoMap().values()) {\n if (info.isScrollable && info.node) {\n scrollPositions.push({\n node: info.node,\n top: info.node.scrollTop,\n left: info.node.scrollLeft,\n });\n }\n }\n\n // Ширина не должна превышать максимально допустимую, т.к. это может повлиять на высоту, например из-за\n // переноса текста на новую строку.\n dropRef.current.style.width = widthEqualToActivator ? `${activatorRect.width}px` : 'auto';\n dropRef.current.style.height = 'auto';\n // Если на задать этот сдвиг, то в случае если дроп отрисовывается в хосте небольшого размера он будет\n // пытаться занять минимально возможное пространство. В случае если внутри дропа текст это может привести к\n // изменению размеров дропа в зависимости от направления выпадения и нестабильным результатам вычисления\n // наилучшей позиции.\n dropRef.current.style.top = '-100000px';\n dropRef.current.style.left = '-100000px';\n\n dropMetricsRef.current = dropRef.current.getBoundingClientRect();\n if (bestFitPlacementRef.current) {\n applyPlacementToDrop(dropRef, bestFitPlacementRef.current);\n }\n for (const { node, top, left } of scrollPositions) {\n node.scrollTop = top;\n node.scrollLeft = left;\n }\n return dropMetricsRef.current;\n },\n [dropRef, getObservedElementsInfoMap]\n );\n\n updateMetricsSyncRef.current = () => {\n if (!dropRef.current || !isVisible) {\n bestFitPlacementRef.current = undefined;\n return;\n }\n const { activatorRect, viewportRect, offsetParentRect } = getMetrics({\n activatorRef,\n customViewport,\n dropRef,\n });\n const dropRect = getDropMetrics(activatorRect, widthEqualToActivator);\n const {\n rect,\n parsedPlacement: choosenPlacement,\n placement: prefferedPlacement,\n } = findBestFitPlacement({\n placements: Array.isArray(placement) ? placement : [placement],\n activatorRect,\n viewportRect,\n offsetParentRect,\n dropWidth: dropRect.width,\n dropHeight: dropRect.height,\n guardDistanceToActivator,\n guardDistanceToViewport,\n minDropHeight,\n widthEqualToActivator,\n allowShrinkHeightToFitIntoViewport,\n arrowGuardDistance,\n prefferedPlacement: prefferedPlacementRef.current,\n lockPlacement,\n });\n prefferedPlacementRef.current = prefferedPlacement;\n applyPlacementToDrop(dropRef, rect);\n dropRef.current.dataset.magritteDropBaseDirection = choosenPlacement.direction;\n dropRef.current.dataset.magritteDropBaseAlignment = choosenPlacement.alignment;\n bestFitPlacementRef.current = rect;\n };\n\n if (forceDropMetricsUpdate) {\n forceDropMetricsUpdate.current = () => {\n dropMetricsRef.current = undefined;\n updateMetricsSyncRef.current();\n };\n }\n\n useEffect(() => {\n if (!isVisible) {\n prefferedPlacementRef.current = undefined;\n return () => void 0;\n }\n const activatorElement = activatorRef.current;\n const customViewportElement = customViewport?.current;\n const resizeHandler = () => updateMetricsSyncRef.current();\n activatorElement && getResizeObserver().observe(activatorElement);\n customViewportElement && getResizeObserver().observe(customViewportElement);\n window.addEventListener('resize', resizeHandler);\n return () => {\n activatorElement && getResizeObserver().unobserve(activatorElement);\n customViewportElement && getResizeObserver().unobserve(customViewportElement);\n window.removeEventListener('resize', resizeHandler);\n };\n }, [activatorRef, getResizeObserver, customViewport, isVisible]);\n\n useLayoutEffect(() => {\n isVisible && updateMetricsSyncRef.current();\n }, [isVisible, placement]);\n\n /**\n * список id скроллящихся элементов для которых была выполнена проверка\n * влияет ли их скролл на взаимное положение активатора и дропа.\n * Получение сделано с помощью отдельной функции чтобы не создавать сет на каждый ререндер.\n */\n const processedScrollContainers = useRef<Set<HTMLElement>>();\n const getProcessedScrollContainers = (): Set<HTMLElement> => {\n processedScrollContainers.current = processedScrollContainers.current || new Set();\n return processedScrollContainers.current;\n };\n\n const visibleRef = useRef(isVisible);\n visibleRef.current = isVisible;\n\n const unsubscribedTargetsRef = useRef<Set<HTMLElement>>(new Set());\n\n const scrollHandler = useCallback(\n (target: HTMLElement) => {\n if (!visibleRef.current || !dropRef.current || !activatorRef.current) {\n return;\n }\n\n // Если это первый скролл данного контейнера, то проверяем содержит ли он активатор\n // Если он не содержит активатор, то можно отписаться от дальнейших оповещений о его скролле.\n if (!getProcessedScrollContainers().has(target)) {\n if (!target.contains(activatorRef.current)) {\n unsubscribeFromTarget(target, scrollHandler);\n if (dropRef.current.contains?.(target)) {\n unsubscribedTargetsRef.current.add(target);\n }\n return;\n }\n getProcessedScrollContainers().add(target);\n }\n\n updateMetricsSyncRef.current();\n },\n [activatorRef, dropRef]\n );\n\n useEffect(() => {\n if (!isVisible) {\n for (const target of unsubscribedTargetsRef.current) {\n canceledScrollSubscriptions.delete(target);\n }\n unsubscribedTargetsRef.current.clear();\n }\n }, [isVisible]);\n\n useEffect(() => {\n if (isVisible) {\n reviveSubscription(scrollHandler);\n } else {\n suspendSubscription(scrollHandler);\n }\n }, [isVisible, scrollHandler]);\n\n useEffect(() => {\n return () => deleteScrollSubscription(scrollHandler);\n }, [scrollHandler]);\n\n return {\n resizeRefCallbackFactory: observeResizeRefCallbackFactory,\n bestFitPlacementRect: bestFitPlacementRef.current,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"positionManager.js","sources":["src/positionManager.ts"],"sourcesContent":["import { RefObject, useCallback, useEffect, useRef, useLayoutEffect, MutableRefObject } from 'react';\n\nimport {\n findBestFitPlacement,\n getMetrics,\n applyPlacementToDrop,\n} from '@hh.ru/magritte-internal-drop-base/findBestFitPlacement';\nimport type {\n ArrowGuardDistance,\n ActivatorElementType,\n Placement,\n RefCallbackFactory,\n} from '@hh.ru/magritte-internal-drop-base/types';\nimport { useMonitorResize } from '@hh.ru/magritte-internal-drop-base/useMonitorResize';\n\nlet isInitialized = false;\n\ninterface SubscriptionCallback {\n (target: HTMLElement): void;\n}\n\nconst scrollSubscriptions: Array<SubscriptionCallback> = [];\nconst canceledScrollSubscriptions: Map<HTMLElement, Array<SubscriptionCallback>> = new Map();\n\nconst scrollHandler = (event: Event) => {\n const target = event.target as HTMLElement;\n if (!target) {\n return;\n }\n\n if (scrollSubscriptions.length === 0) {\n return;\n }\n const canceledSubscriptions = canceledScrollSubscriptions.get(target);\n\n const subscriptions =\n canceledSubscriptions === undefined\n ? scrollSubscriptions\n : scrollSubscriptions.filter((subscription) => !canceledSubscriptions.includes(subscription));\n\n subscriptions.forEach((subscription) => subscription(target));\n};\n\nconst initialize = () => {\n if (isInitialized) {\n return;\n }\n\n isInitialized = true;\n document.addEventListener('scroll', scrollHandler, { capture: true, passive: false });\n};\n\nconst suspendSubscription = (callback: SubscriptionCallback): void => {\n const index = scrollSubscriptions.indexOf(callback);\n if (index !== -1) {\n scrollSubscriptions.splice(index, 1);\n }\n};\n\nconst reviveSubscription = (callback: SubscriptionCallback): void => {\n initialize();\n scrollSubscriptions.push(callback);\n};\n\nexport const deleteScrollSubscription = (callback: SubscriptionCallback): void => {\n const index = scrollSubscriptions.indexOf(callback);\n if (index !== -1) {\n scrollSubscriptions.splice(index, 1);\n }\n for (const [target, callbacks] of canceledScrollSubscriptions.entries()) {\n const index = callbacks.indexOf(callback);\n if (index !== -1) {\n const updatedCallbacks = callbacks.splice(index, 1);\n if (updatedCallbacks.length > 0) {\n canceledScrollSubscriptions.set(target, updatedCallbacks);\n } else {\n canceledScrollSubscriptions.delete(target);\n }\n }\n }\n};\n\nconst unsubscribeFromTarget = (target: HTMLElement, callback: SubscriptionCallback): void => {\n if (!canceledScrollSubscriptions.has(target)) {\n canceledScrollSubscriptions.set(target, []);\n }\n canceledScrollSubscriptions.get(target)?.push(callback);\n};\n\nexport const usePositionManager = (\n activatorRef: RefObject<ActivatorElementType>,\n dropRef: RefObject<HTMLElement>,\n isVisible: boolean,\n placement: Placement | Placement[],\n customViewport: RefObject<HTMLElement> | undefined,\n allowShrinkHeightToFitIntoViewport: boolean,\n widthEqualToActivator: boolean,\n arrowGuardDistance: ArrowGuardDistance,\n guardDistanceToActivator: number,\n guardDistanceToViewport: number,\n minDropHeight: number,\n forceDropMetricsUpdate: MutableRefObject<VoidFunction> | undefined,\n lockPlacement = false\n): {\n resizeRefCallbackFactory: RefCallbackFactory;\n bestFitPlacementRect: DOMRect | undefined;\n} => {\n const bestFitPlacementRef = useRef<DOMRect>();\n const dropMetricsRef = useRef<DOMRect>();\n\n const prefferedPlacementRef = useRef<Placement>();\n\n const updateMetricsSyncRef = useRef<VoidFunction>(() => void 0);\n\n const { getResizeObserver, observeResizeRefCallbackFactory, getObservedElementsInfoMap } = useMonitorResize(\n dropMetricsRef,\n updateMetricsSyncRef\n );\n\n const getDropMetrics = useCallback(\n (activatorRect: DOMRect, widthEqualToActivator: boolean) => {\n if (dropMetricsRef.current) {\n return dropMetricsRef.current;\n }\n if (!dropRef.current) {\n return new DOMRect();\n }\n\n const scrollPositions: { node: HTMLElement; top: number; left: number }[] = [];\n for (const info of getObservedElementsInfoMap().values()) {\n if (info.isScrollable && info.node) {\n scrollPositions.push({\n node: info.node,\n top: info.node.scrollTop,\n left: info.node.scrollLeft,\n });\n }\n }\n\n // Ширина не должна превышать максимально допустимую, т.к. это может повлиять на высоту, например из-за\n // переноса текста на новую строку.\n dropRef.current.style.width = widthEqualToActivator ? `${activatorRect.width}px` : 'auto';\n dropRef.current.style.height = 'auto';\n // Если на задать этот сдвиг, то в случае если дроп отрисовывается в хосте небольшого размера он будет\n // пытаться занять минимально возможное пространство. В случае если внутри дропа текст это может привести к\n // изменению размеров дропа в зависимости от направления выпадения и нестабильным результатам вычисления\n // наилучшей позиции.\n dropRef.current.style.top = '-100000px';\n dropRef.current.style.left = '-100000px';\n\n dropMetricsRef.current = dropRef.current.getBoundingClientRect();\n if (bestFitPlacementRef.current) {\n applyPlacementToDrop(dropRef, bestFitPlacementRef.current);\n }\n for (const { node, top, left } of scrollPositions) {\n node.scrollTop = top;\n node.scrollLeft = left;\n }\n return dropMetricsRef.current;\n },\n [dropRef, getObservedElementsInfoMap]\n );\n\n updateMetricsSyncRef.current = () => {\n if (!dropRef.current || !isVisible) {\n bestFitPlacementRef.current = undefined;\n return;\n }\n const { activatorRect, viewportRect, offsetParentRect } = getMetrics({\n activatorRef,\n customViewport,\n dropRef,\n });\n const dropRect = getDropMetrics(activatorRect, widthEqualToActivator);\n const {\n rect,\n parsedPlacement: choosenPlacement,\n placement: prefferedPlacement,\n } = findBestFitPlacement({\n placements: Array.isArray(placement) ? placement : [placement],\n activatorRect,\n viewportRect,\n offsetParentRect,\n dropWidth: dropRect.width,\n dropHeight: dropRect.height,\n guardDistanceToActivator,\n guardDistanceToViewport,\n minDropHeight,\n widthEqualToActivator,\n allowShrinkHeightToFitIntoViewport,\n arrowGuardDistance,\n prefferedPlacement: prefferedPlacementRef.current,\n lockPlacement,\n });\n prefferedPlacementRef.current = prefferedPlacement;\n applyPlacementToDrop(dropRef, rect);\n dropRef.current.dataset.magritteDropBaseDirection = choosenPlacement.direction;\n dropRef.current.dataset.magritteDropBaseAlignment = choosenPlacement.alignment;\n bestFitPlacementRef.current = rect;\n };\n\n if (forceDropMetricsUpdate) {\n forceDropMetricsUpdate.current = () => {\n dropMetricsRef.current = undefined;\n updateMetricsSyncRef.current();\n };\n }\n\n useEffect(() => {\n if (!isVisible) {\n prefferedPlacementRef.current = undefined;\n return () => void 0;\n }\n const activatorElement = activatorRef.current;\n const customViewportElement = customViewport?.current;\n const resizeHandler = () => updateMetricsSyncRef.current();\n activatorElement && getResizeObserver().observe(activatorElement);\n customViewportElement && getResizeObserver().observe(customViewportElement);\n window.addEventListener('resize', resizeHandler);\n return () => {\n activatorElement && getResizeObserver().unobserve(activatorElement);\n customViewportElement && getResizeObserver().unobserve(customViewportElement);\n window.removeEventListener('resize', resizeHandler);\n };\n }, [activatorRef, getResizeObserver, customViewport, isVisible]);\n\n useLayoutEffect(() => {\n isVisible && updateMetricsSyncRef.current();\n }, [isVisible, placement]);\n\n /**\n * список id скроллящихся элементов для которых была выполнена проверка\n * влияет ли их скролл на взаимное положение активатора и дропа.\n * Получение сделано с помощью отдельной функции чтобы не создавать сет на каждый ререндер.\n */\n const processedScrollContainers = useRef<Set<HTMLElement>>();\n const getProcessedScrollContainers = (): Set<HTMLElement> => {\n processedScrollContainers.current = processedScrollContainers.current || new Set();\n return processedScrollContainers.current;\n };\n\n const visibleRef = useRef(isVisible);\n visibleRef.current = isVisible;\n\n const unsubscribedTargetsRef = useRef<Set<HTMLElement>>(new Set());\n\n const scrollHandler = useCallback(\n (target: HTMLElement) => {\n if (!visibleRef.current || !dropRef.current || !activatorRef.current) {\n return;\n }\n\n // Если это первый скролл данного контейнера, то проверяем содержит ли он активатор\n // Если он не содержит активатор, то можно отписаться от дальнейших оповещений о его скролле.\n if (!getProcessedScrollContainers().has(target)) {\n if (!target.contains(activatorRef.current)) {\n unsubscribeFromTarget(target, scrollHandler);\n if (dropRef.current.contains?.(target)) {\n unsubscribedTargetsRef.current.add(target);\n }\n return;\n }\n getProcessedScrollContainers().add(target);\n }\n\n updateMetricsSyncRef.current();\n },\n [activatorRef, dropRef]\n );\n\n useEffect(() => {\n if (!isVisible) {\n for (const target of unsubscribedTargetsRef.current) {\n canceledScrollSubscriptions.delete(target);\n }\n unsubscribedTargetsRef.current.clear();\n }\n }, [isVisible]);\n\n useEffect(() => {\n if (isVisible) {\n reviveSubscription(scrollHandler);\n } else {\n suspendSubscription(scrollHandler);\n }\n }, [isVisible, scrollHandler]);\n\n useEffect(() => {\n return () => deleteScrollSubscription(scrollHandler);\n }, [scrollHandler]);\n\n return {\n resizeRefCallbackFactory: observeResizeRefCallbackFactory,\n bestFitPlacementRect: bestFitPlacementRef.current,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useArrayMemo.js","sources":["../src/useArrayMemo.ts"],"sourcesContent":["import { useRef } from 'react';\n\nexport const isEqual = (first: unknown[], second: unknown[]): boolean =>\n first === second || (first.length === second.length && first.every((e: unknown, i: number) => e === second[i]));\n\nconst useArrayMemo = <T, R>(cb: () => R, array: T[], ...restArgs: unknown[]): R => {\n const prevArrayRef = useRef(array);\n const prevRestArgsRef = useRef(restArgs);\n\n const resultRef = useRef<undefined | R>();\n\n const isArrayEqual = isEqual(prevArrayRef.current, array);\n const isRestArgsEqual = isEqual(prevRestArgsRef.current, restArgs);\n\n prevArrayRef.current = array;\n prevRestArgsRef.current = restArgs;\n\n if (resultRef.current === undefined || !isArrayEqual || !isRestArgsEqual) {\n resultRef.current = cb();\n }\n\n return resultRef.current;\n};\n\nexport { useArrayMemo };\n"],"names":[],"mappings":";;AAEa,MAAA,OAAO,GAAG,CAAC,KAAgB,EAAE,MAAiB,KACvD,KAAK,KAAK,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,CAAS,KAAK,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AAE9G,MAAA,YAAY,GAAG,CAAO,EAAW,EAAE,KAAU,EAAE,GAAG,QAAmB,KAAO;AAC9E,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACnC,IAAA,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEzC,IAAA,MAAM,SAAS,GAAG,MAAM,EAAiB,CAAC;IAE1C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAEnE,IAAA,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC;AAC7B,IAAA,eAAe,CAAC,OAAO,GAAG,QAAQ,CAAC;AAEnC,IAAA,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,EAAE;AACtE,QAAA,SAAS,CAAC,OAAO,GAAG,EAAE,EAAE,CAAC;KAC5B;IAED,OAAO,SAAS,CAAC,OAAO,CAAC;AAC7B;;;;"}
1
+ {"version":3,"file":"useArrayMemo.js","sources":["src/useArrayMemo.ts"],"sourcesContent":["import { useRef } from 'react';\n\nexport const isEqual = (first: unknown[], second: unknown[]): boolean =>\n first === second || (first.length === second.length && first.every((e: unknown, i: number) => e === second[i]));\n\nconst useArrayMemo = <T, R>(cb: () => R, array: T[], ...restArgs: unknown[]): R => {\n const prevArrayRef = useRef(array);\n const prevRestArgsRef = useRef(restArgs);\n\n const resultRef = useRef<undefined | R>();\n\n const isArrayEqual = isEqual(prevArrayRef.current, array);\n const isRestArgsEqual = isEqual(prevRestArgsRef.current, restArgs);\n\n prevArrayRef.current = array;\n prevRestArgsRef.current = restArgs;\n\n if (resultRef.current === undefined || !isArrayEqual || !isRestArgsEqual) {\n resultRef.current = cb();\n }\n\n return resultRef.current;\n};\n\nexport { useArrayMemo };\n"],"names":[],"mappings":";;AAEa,MAAA,OAAO,GAAG,CAAC,KAAgB,EAAE,MAAiB,KACvD,KAAK,KAAK,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,CAAS,KAAK,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AAE9G,MAAA,YAAY,GAAG,CAAO,EAAW,EAAE,KAAU,EAAE,GAAG,QAAmB,KAAO;AAC9E,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACnC,IAAA,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEzC,IAAA,MAAM,SAAS,GAAG,MAAM,EAAiB,CAAC;IAE1C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAEnE,IAAA,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC;AAC7B,IAAA,eAAe,CAAC,OAAO,GAAG,QAAQ,CAAC;AAEnC,IAAA,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,EAAE;AACtE,QAAA,SAAS,CAAC,OAAO,GAAG,EAAE,EAAE,CAAC;KAC5B;IAED,OAAO,SAAS,CAAC,OAAO,CAAC;AAC7B;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useMonitorResize.js","sources":["../src/useMonitorResize.ts"],"sourcesContent":["import { useCallback, useRef, RefCallback, MutableRefObject } from 'react';\n\nimport { RefCallbackFactory } from '@hh.ru/magritte-internal-drop-base/types';\n\ninterface ObservedElementInfo {\n node: HTMLElement | null;\n isScrollable: boolean;\n refCallback: RefCallback<HTMLElement>;\n}\n\n/**\n * При изменении размера содержимого дропа необходимо перезапускать пересчет позиции.\n * Для отслеживания изменения размер используется ResizeObserver вызывающий код обновления позиции и размера дропа.\n * Проблема в том, что нельзя просто подписаться на изменение размера самой внешней обертки дропа, т.к. для нее\n * размер жестко задается кодом отвечающим за позиционирование. Т.е. даже при изменении размера содержимого внешняя\n * обертка не поменяет свой размер. Кроме того в дропе может быть несколько независимых частей размер которых\n * может измениться. Этот хук возвращает фабрику refcallback'ов. При вызове фабрики создается refcallback который\n * подписывает ResizeObserver на изменение размера элемента. При передаче в аргументе для фабрики одного и того же\n * id, будет возвращен тот же самый refcallback, т.е. проблемы с изменением ссылки передаваемой в проп не возникает.\n * Далее эта фабрика передается в рендер функцию Drop/Tooltip и используется для подписки на изменение размера\n * различных частей.\n */\nexport const useMonitorResize = (\n dropMetricsRef: MutableRefObject<DOMRect | undefined>,\n updateMetricsRef: MutableRefObject<VoidFunction>\n): {\n observeResizeRefCallbackFactory: RefCallbackFactory;\n getResizeObserver: () => ResizeObserver;\n getObservedElementsInfoMap: () => Map<string, ObservedElementInfo>;\n} => {\n const resizeObserverRef = useRef<ResizeObserver>();\n const getResizeObserver = useCallback(() => {\n if (!resizeObserverRef.current) {\n resizeObserverRef.current = new ResizeObserver(() => {\n dropMetricsRef.current = undefined;\n updateMetricsRef.current();\n });\n }\n return resizeObserverRef.current;\n }, [dropMetricsRef, updateMetricsRef]);\n\n const observedElementsInfoMapRef = useRef<Map<string, ObservedElementInfo>>();\n const getObservedElementsInfoMap = useCallback(() => {\n observedElementsInfoMapRef.current = observedElementsInfoMapRef.current || new Map();\n return observedElementsInfoMapRef.current;\n }, []);\n\n const observeResizeRefCallbackFactory: RefCallbackFactory = (id, observe = true, isScrollable = false) => {\n if (getObservedElementsInfoMap().has(id)) {\n return getObservedElementsInfoMap().get(id)?.refCallback as RefCallback<HTMLElement>;\n }\n\n const refCallback = (node: HTMLElement | null) => {\n const info = getObservedElementsInfoMap().get(id) as ObservedElementInfo;\n const currentNode = info.node;\n if (currentNode === node) {\n return;\n }\n currentNode && observe && getResizeObserver().unobserve(currentNode);\n info.node = node;\n node && observe && getResizeObserver().observe(node);\n };\n\n getObservedElementsInfoMap().set(id, {\n node: null,\n refCallback,\n isScrollable,\n });\n return refCallback;\n };\n\n return {\n observeResizeRefCallbackFactory,\n getResizeObserver,\n getObservedElementsInfoMap,\n };\n};\n"],"names":[],"mappings":";;AAUA;;;;;;;;;;;AAWG;MACU,gBAAgB,GAAG,CAC5B,cAAqD,EACrD,gBAAgD,KAKhD;AACA,IAAA,MAAM,iBAAiB,GAAG,MAAM,EAAkB,CAAC;AACnD,IAAA,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAK;AACvC,QAAA,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE;AAC5B,YAAA,iBAAiB,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,MAAK;AAChD,gBAAA,cAAc,CAAC,OAAO,GAAG,SAAS,CAAC;gBACnC,gBAAgB,CAAC,OAAO,EAAE,CAAC;AAC/B,aAAC,CAAC,CAAC;SACN;QACD,OAAO,iBAAiB,CAAC,OAAO,CAAC;AACrC,KAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEvC,IAAA,MAAM,0BAA0B,GAAG,MAAM,EAAoC,CAAC;AAC9E,IAAA,MAAM,0BAA0B,GAAG,WAAW,CAAC,MAAK;QAChD,0BAA0B,CAAC,OAAO,GAAG,0BAA0B,CAAC,OAAO,IAAI,IAAI,GAAG,EAAE,CAAC;QACrF,OAAO,0BAA0B,CAAC,OAAO,CAAC;KAC7C,EAAE,EAAE,CAAC,CAAC;AAEP,IAAA,MAAM,+BAA+B,GAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,EAAE,YAAY,GAAG,KAAK,KAAI;QACrG,IAAI,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACtC,OAAO,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,WAAuC,CAAC;SACxF;AAED,QAAA,MAAM,WAAW,GAAG,CAAC,IAAwB,KAAI;YAC7C,MAAM,IAAI,GAAG,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,CAAwB,CAAC;AACzE,YAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;AAC9B,YAAA,IAAI,WAAW,KAAK,IAAI,EAAE;gBACtB,OAAO;aACV;YACD,WAAW,IAAI,OAAO,IAAI,iBAAiB,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;AACrE,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,IAAI,OAAO,IAAI,iBAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzD,SAAC,CAAC;AAEF,QAAA,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE;AACjC,YAAA,IAAI,EAAE,IAAI;YACV,WAAW;YACX,YAAY;AACf,SAAA,CAAC,CAAC;AACH,QAAA,OAAO,WAAW,CAAC;AACvB,KAAC,CAAC;IAEF,OAAO;QACH,+BAA+B;QAC/B,iBAAiB;QACjB,0BAA0B;KAC7B,CAAC;AACN;;;;"}
1
+ {"version":3,"file":"useMonitorResize.js","sources":["src/useMonitorResize.ts"],"sourcesContent":["import { useCallback, useRef, RefCallback, MutableRefObject } from 'react';\n\nimport { RefCallbackFactory } from '@hh.ru/magritte-internal-drop-base/types';\n\ninterface ObservedElementInfo {\n node: HTMLElement | null;\n isScrollable: boolean;\n refCallback: RefCallback<HTMLElement>;\n}\n\n/**\n * При изменении размера содержимого дропа необходимо перезапускать пересчет позиции.\n * Для отслеживания изменения размер используется ResizeObserver вызывающий код обновления позиции и размера дропа.\n * Проблема в том, что нельзя просто подписаться на изменение размера самой внешней обертки дропа, т.к. для нее\n * размер жестко задается кодом отвечающим за позиционирование. Т.е. даже при изменении размера содержимого внешняя\n * обертка не поменяет свой размер. Кроме того в дропе может быть несколько независимых частей размер которых\n * может измениться. Этот хук возвращает фабрику refcallback'ов. При вызове фабрики создается refcallback который\n * подписывает ResizeObserver на изменение размера элемента. При передаче в аргументе для фабрики одного и того же\n * id, будет возвращен тот же самый refcallback, т.е. проблемы с изменением ссылки передаваемой в проп не возникает.\n * Далее эта фабрика передается в рендер функцию Drop/Tooltip и используется для подписки на изменение размера\n * различных частей.\n */\nexport const useMonitorResize = (\n dropMetricsRef: MutableRefObject<DOMRect | undefined>,\n updateMetricsRef: MutableRefObject<VoidFunction>\n): {\n observeResizeRefCallbackFactory: RefCallbackFactory;\n getResizeObserver: () => ResizeObserver;\n getObservedElementsInfoMap: () => Map<string, ObservedElementInfo>;\n} => {\n const resizeObserverRef = useRef<ResizeObserver>();\n const getResizeObserver = useCallback(() => {\n if (!resizeObserverRef.current) {\n resizeObserverRef.current = new ResizeObserver(() => {\n dropMetricsRef.current = undefined;\n updateMetricsRef.current();\n });\n }\n return resizeObserverRef.current;\n }, [dropMetricsRef, updateMetricsRef]);\n\n const observedElementsInfoMapRef = useRef<Map<string, ObservedElementInfo>>();\n const getObservedElementsInfoMap = useCallback(() => {\n observedElementsInfoMapRef.current = observedElementsInfoMapRef.current || new Map();\n return observedElementsInfoMapRef.current;\n }, []);\n\n const observeResizeRefCallbackFactory: RefCallbackFactory = (id, observe = true, isScrollable = false) => {\n if (getObservedElementsInfoMap().has(id)) {\n return getObservedElementsInfoMap().get(id)?.refCallback as RefCallback<HTMLElement>;\n }\n\n const refCallback = (node: HTMLElement | null) => {\n const info = getObservedElementsInfoMap().get(id) as ObservedElementInfo;\n const currentNode = info.node;\n if (currentNode === node) {\n return;\n }\n currentNode && observe && getResizeObserver().unobserve(currentNode);\n info.node = node;\n node && observe && getResizeObserver().observe(node);\n };\n\n getObservedElementsInfoMap().set(id, {\n node: null,\n refCallback,\n isScrollable,\n });\n return refCallback;\n };\n\n return {\n observeResizeRefCallbackFactory,\n getResizeObserver,\n getObservedElementsInfoMap,\n };\n};\n"],"names":[],"mappings":";;AAUA;;;;;;;;;;;AAWG;MACU,gBAAgB,GAAG,CAC5B,cAAqD,EACrD,gBAAgD,KAKhD;AACA,IAAA,MAAM,iBAAiB,GAAG,MAAM,EAAkB,CAAC;AACnD,IAAA,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAK;AACvC,QAAA,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE;AAC5B,YAAA,iBAAiB,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,MAAK;AAChD,gBAAA,cAAc,CAAC,OAAO,GAAG,SAAS,CAAC;gBACnC,gBAAgB,CAAC,OAAO,EAAE,CAAC;AAC/B,aAAC,CAAC,CAAC;SACN;QACD,OAAO,iBAAiB,CAAC,OAAO,CAAC;AACrC,KAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEvC,IAAA,MAAM,0BAA0B,GAAG,MAAM,EAAoC,CAAC;AAC9E,IAAA,MAAM,0BAA0B,GAAG,WAAW,CAAC,MAAK;QAChD,0BAA0B,CAAC,OAAO,GAAG,0BAA0B,CAAC,OAAO,IAAI,IAAI,GAAG,EAAE,CAAC;QACrF,OAAO,0BAA0B,CAAC,OAAO,CAAC;KAC7C,EAAE,EAAE,CAAC,CAAC;AAEP,IAAA,MAAM,+BAA+B,GAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,EAAE,YAAY,GAAG,KAAK,KAAI;QACrG,IAAI,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACtC,OAAO,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,WAAuC,CAAC;SACxF;AAED,QAAA,MAAM,WAAW,GAAG,CAAC,IAAwB,KAAI;YAC7C,MAAM,IAAI,GAAG,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,CAAwB,CAAC;AACzE,YAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;AAC9B,YAAA,IAAI,WAAW,KAAK,IAAI,EAAE;gBACtB,OAAO;aACV;YACD,WAAW,IAAI,OAAO,IAAI,iBAAiB,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;AACrE,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,IAAI,OAAO,IAAI,iBAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzD,SAAC,CAAC;AAEF,QAAA,0BAA0B,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE;AACjC,YAAA,IAAI,EAAE,IAAI;YACV,WAAW;YACX,YAAY;AACf,SAAA,CAAC,CAAC;AACH,QAAA,OAAO,WAAW,CAAC;AACvB,KAAC,CAAC;IAEF,OAAO;QACH,+BAA+B;QAC/B,iBAAiB;QACjB,0BAA0B;KAC7B,CAAC;AACN;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePlacements.js","sources":["../src/usePlacements.ts"],"sourcesContent":["import type {\n Placement,\n VerticalDirection,\n HorizontalDirection,\n AlignmentForVerticalDirection,\n AlignmentForHorizontalDirection,\n} from '@hh.ru/magritte-internal-drop-base/types';\nimport { useArrayMemo } from '@hh.ru/magritte-internal-drop-base/useArrayMemo';\n\nconst HOR_DIRECTION_ALIGNMENT_PRIORITIES = ['center', 'top', 'bottom'] as const;\nconst VER_DIRECTION_ALIGNMENT_PRIORITIES = ['center', 'left', 'right'] as const;\nconst PLACEMENTS_MAP = {\n right: HOR_DIRECTION_ALIGNMENT_PRIORITIES,\n left: HOR_DIRECTION_ALIGNMENT_PRIORITIES,\n top: VER_DIRECTION_ALIGNMENT_PRIORITIES,\n bottom: VER_DIRECTION_ALIGNMENT_PRIORITIES,\n} as const satisfies { [key in VerticalDirection]: readonly AlignmentForVerticalDirection[] } & {\n [key in HorizontalDirection]: readonly AlignmentForHorizontalDirection[];\n};\nconst HOR_DIRECTIONS: (VerticalDirection | HorizontalDirection)[] = ['right', 'left'];\nconst VER_DIRECTIONS: (VerticalDirection | HorizontalDirection)[] = ['top', 'bottom'];\n\nexport const usePlacement = (\n preferredPlacements: Placement[] | Placement,\n availablePlacements: Set<Placement>,\n forcePlacement: boolean\n): Placement[] => {\n const placements = Array.isArray(preferredPlacements) ? preferredPlacements : [preferredPlacements];\n\n const result = useArrayMemo(\n () => {\n if (forcePlacement) {\n return placements;\n }\n\n const result = [...placements];\n const processedDirections: Record<string, boolean> = {};\n\n // массив, содержащий только уникальные directions из prefferedPlacements в порядке их первого\n // упоминания в массиве\n const preferredDirections = placements\n .map((placement) => placement.split('-')[0])\n .reduce<string[]>((result, direction) => {\n if (processedDirections[direction]) {\n return result;\n }\n\n processedDirections[direction] = true;\n result.push(direction);\n return result;\n }, []) as (VerticalDirection | HorizontalDirection)[];\n\n // Если перечислены не все возможные directions добавляем недостающие\n // причем если наиболее приоритетный direction был вертикальным, то сначала добавляем вертикальные\n // иначе горизонтальные\n if (preferredDirections.length < 4) {\n const directions = HOR_DIRECTIONS.includes(preferredDirections[0])\n ? [...HOR_DIRECTIONS, ...VER_DIRECTIONS]\n : [...VER_DIRECTIONS, ...HOR_DIRECTIONS];\n for (const direction of directions) {\n !preferredDirections.includes(direction) && preferredDirections.push(direction);\n }\n }\n\n // проходимся по всем directions в порядке приоритета\n // для каждого из них генерируем все placements перебирая alignment в порядке приоритета\n // для каждого placement проверяем есть ли он в preferredPlacements и в availablePlacements\n // если нет в preferredPlacements и есть в availablePlacements, то добавляем этот placements к результату\n // в итоге получаем список placement отсортированный по приоритетам directions в исходном массиве\n for (const direction of preferredDirections) {\n const alignments = PLACEMENTS_MAP[direction];\n for (const alignment of alignments) {\n const placement = `${direction}-${alignment}` as Placement;\n if (!preferredPlacements.includes(placement) && availablePlacements.has(placement)) {\n result.push(placement);\n }\n }\n }\n\n return result;\n },\n placements,\n forcePlacement,\n availablePlacements\n );\n\n return result;\n};\n"],"names":[],"mappings":";;;AASA,MAAM,kCAAkC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAU,CAAC;AAChF,MAAM,kCAAkC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAChF,MAAM,cAAc,GAAG;AACnB,IAAA,KAAK,EAAE,kCAAkC;AACzC,IAAA,IAAI,EAAE,kCAAkC;AACxC,IAAA,GAAG,EAAE,kCAAkC;AACvC,IAAA,MAAM,EAAE,kCAAkC;CAG7C,CAAC;AACF,MAAM,cAAc,GAAgD,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACtF,MAAM,cAAc,GAAgD,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAEzE,MAAA,YAAY,GAAG,CACxB,mBAA4C,EAC5C,mBAAmC,EACnC,cAAuB,KACV;AACb,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAEpG,IAAA,MAAM,MAAM,GAAG,YAAY,CACvB,MAAK;QACD,IAAI,cAAc,EAAE;AAChB,YAAA,OAAO,UAAU,CAAC;SACrB;AAED,QAAA,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QAC/B,MAAM,mBAAmB,GAA4B,EAAE,CAAC;;;QAIxD,MAAM,mBAAmB,GAAG,UAAU;AACjC,aAAA,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,aAAA,MAAM,CAAW,CAAC,MAAM,EAAE,SAAS,KAAI;AACpC,YAAA,IAAI,mBAAmB,CAAC,SAAS,CAAC,EAAE;AAChC,gBAAA,OAAO,MAAM,CAAC;aACjB;AAED,YAAA,mBAAmB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AACtC,YAAA,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACvB,YAAA,OAAO,MAAM,CAAC;SACjB,EAAE,EAAE,CAAgD,CAAC;;;;AAK1D,QAAA,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAC9D,kBAAE,CAAC,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC;kBACtC,CAAC,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC,CAAC;AAC7C,YAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;AAChC,gBAAA,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aACnF;SACJ;;;;;;AAOD,QAAA,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE;AACzC,YAAA,MAAM,UAAU,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;AAC7C,YAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;AAChC,gBAAA,MAAM,SAAS,GAAG,CAAA,EAAG,SAAS,CAAI,CAAA,EAAA,SAAS,EAAe,CAAC;AAC3D,gBAAA,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;AAChF,oBAAA,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;iBAC1B;aACJ;SACJ;AAED,QAAA,OAAO,MAAM,CAAC;AAClB,KAAC,EACD,UAAU,EACV,cAAc,EACd,mBAAmB,CACtB,CAAC;AAEF,IAAA,OAAO,MAAM,CAAC;AAClB;;;;"}
1
+ {"version":3,"file":"usePlacements.js","sources":["src/usePlacements.ts"],"sourcesContent":["import type {\n Placement,\n VerticalDirection,\n HorizontalDirection,\n AlignmentForVerticalDirection,\n AlignmentForHorizontalDirection,\n} from '@hh.ru/magritte-internal-drop-base/types';\nimport { useArrayMemo } from '@hh.ru/magritte-internal-drop-base/useArrayMemo';\n\nconst HOR_DIRECTION_ALIGNMENT_PRIORITIES = ['center', 'top', 'bottom'] as const;\nconst VER_DIRECTION_ALIGNMENT_PRIORITIES = ['center', 'left', 'right'] as const;\nconst PLACEMENTS_MAP = {\n right: HOR_DIRECTION_ALIGNMENT_PRIORITIES,\n left: HOR_DIRECTION_ALIGNMENT_PRIORITIES,\n top: VER_DIRECTION_ALIGNMENT_PRIORITIES,\n bottom: VER_DIRECTION_ALIGNMENT_PRIORITIES,\n} as const satisfies { [key in VerticalDirection]: readonly AlignmentForVerticalDirection[] } & {\n [key in HorizontalDirection]: readonly AlignmentForHorizontalDirection[];\n};\nconst HOR_DIRECTIONS: (VerticalDirection | HorizontalDirection)[] = ['right', 'left'];\nconst VER_DIRECTIONS: (VerticalDirection | HorizontalDirection)[] = ['top', 'bottom'];\n\nexport const usePlacement = (\n preferredPlacements: Placement[] | Placement,\n availablePlacements: Set<Placement>,\n forcePlacement: boolean\n): Placement[] => {\n const placements = Array.isArray(preferredPlacements) ? preferredPlacements : [preferredPlacements];\n\n const result = useArrayMemo(\n () => {\n if (forcePlacement) {\n return placements;\n }\n\n const result = [...placements];\n const processedDirections: Record<string, boolean> = {};\n\n // массив, содержащий только уникальные directions из prefferedPlacements в порядке их первого\n // упоминания в массиве\n const preferredDirections = placements\n .map((placement) => placement.split('-')[0])\n .reduce<string[]>((result, direction) => {\n if (processedDirections[direction]) {\n return result;\n }\n\n processedDirections[direction] = true;\n result.push(direction);\n return result;\n }, []) as (VerticalDirection | HorizontalDirection)[];\n\n // Если перечислены не все возможные directions добавляем недостающие\n // причем если наиболее приоритетный direction был вертикальным, то сначала добавляем вертикальные\n // иначе горизонтальные\n if (preferredDirections.length < 4) {\n const directions = HOR_DIRECTIONS.includes(preferredDirections[0])\n ? [...HOR_DIRECTIONS, ...VER_DIRECTIONS]\n : [...VER_DIRECTIONS, ...HOR_DIRECTIONS];\n for (const direction of directions) {\n !preferredDirections.includes(direction) && preferredDirections.push(direction);\n }\n }\n\n // проходимся по всем directions в порядке приоритета\n // для каждого из них генерируем все placements перебирая alignment в порядке приоритета\n // для каждого placement проверяем есть ли он в preferredPlacements и в availablePlacements\n // если нет в preferredPlacements и есть в availablePlacements, то добавляем этот placements к результату\n // в итоге получаем список placement отсортированный по приоритетам directions в исходном массиве\n for (const direction of preferredDirections) {\n const alignments = PLACEMENTS_MAP[direction];\n for (const alignment of alignments) {\n const placement = `${direction}-${alignment}` as Placement;\n if (!preferredPlacements.includes(placement) && availablePlacements.has(placement)) {\n result.push(placement);\n }\n }\n }\n\n return result;\n },\n placements,\n forcePlacement,\n availablePlacements\n );\n\n return result;\n};\n"],"names":[],"mappings":";;;AASA,MAAM,kCAAkC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAU,CAAC;AAChF,MAAM,kCAAkC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAChF,MAAM,cAAc,GAAG;AACnB,IAAA,KAAK,EAAE,kCAAkC;AACzC,IAAA,IAAI,EAAE,kCAAkC;AACxC,IAAA,GAAG,EAAE,kCAAkC;AACvC,IAAA,MAAM,EAAE,kCAAkC;CAG7C,CAAC;AACF,MAAM,cAAc,GAAgD,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACtF,MAAM,cAAc,GAAgD,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAEzE,MAAA,YAAY,GAAG,CACxB,mBAA4C,EAC5C,mBAAmC,EACnC,cAAuB,KACV;AACb,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAEpG,IAAA,MAAM,MAAM,GAAG,YAAY,CACvB,MAAK;QACD,IAAI,cAAc,EAAE;AAChB,YAAA,OAAO,UAAU,CAAC;SACrB;AAED,QAAA,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QAC/B,MAAM,mBAAmB,GAA4B,EAAE,CAAC;;;QAIxD,MAAM,mBAAmB,GAAG,UAAU;AACjC,aAAA,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,aAAA,MAAM,CAAW,CAAC,MAAM,EAAE,SAAS,KAAI;AACpC,YAAA,IAAI,mBAAmB,CAAC,SAAS,CAAC,EAAE;AAChC,gBAAA,OAAO,MAAM,CAAC;aACjB;AAED,YAAA,mBAAmB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AACtC,YAAA,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACvB,YAAA,OAAO,MAAM,CAAC;SACjB,EAAE,EAAE,CAAgD,CAAC;;;;AAK1D,QAAA,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAC9D,kBAAE,CAAC,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC;kBACtC,CAAC,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC,CAAC;AAC7C,YAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;AAChC,gBAAA,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aACnF;SACJ;;;;;;AAOD,QAAA,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE;AACzC,YAAA,MAAM,UAAU,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;AAC7C,YAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;AAChC,gBAAA,MAAM,SAAS,GAAG,CAAA,EAAG,SAAS,CAAI,CAAA,EAAA,SAAS,EAAe,CAAC;AAC3D,gBAAA,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;AAChF,oBAAA,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;iBAC1B;aACJ;SACJ;AAED,QAAA,OAAO,MAAM,CAAC;AAClB,KAAC,EACD,UAAU,EACV,cAAc,EACd,mBAAmB,CACtB,CAAC;AAEF,IAAA,OAAO,MAAM,CAAC;AAClB;;;;"}