MRK-4890: Компоненты: Добавить возможность закрытия тултипа при скролле (v8) #1307
MRK-4890: Компоненты: Добавить возможность закрытия тултипа при скролле (v8) #1307andreykiselev92 wants to merge 24 commits into
Conversation
Importing from the library's own public_api created a circular dependency (public_api re-exports the tooltip service) and breaks the ng-packagr build. Use the same relative path the directive and other specs already use.
…nted Document the reason the custom strategies wrap a capture-phase document scroll listener instead of reusing CDK's ScrollDispatcher-based strategies, and leave a TODO to revisit.
…ate() The EvoScrollStrategy -> concrete strategy switch was duplicated in the tooltip service and the dropdown component. Move it into EvoScrollStrategyOptions.create() so the union has a single owner, and replace the magic threshold with a named constant in the tooltip service.
EvoScrollStrategyOptions is stateless, so provide it in root and drop the duplicated providers entries from the tooltip directive, the dropdown component and their specs.
It was only used by the element getter / listenScroll that were removed when the dropdown switched to the shared scroll strategies; there are no subclasses.
EvoScrollStrategy and EvoScrollStrategyOptions both live in the common/scroll barrel; import them from a single entry point instead of mixing a deep path with the barrel.
CDK reads the scroll strategy only when the overlay opens, so the BehaviorSubject + async pipe bought nothing. Replace it with a plain field initialized in the constructor (no longer relying on a parameter being assigned before a field initializer) and drop the AsyncPipe import.
isOpen$ is a plain Subject; in the show test it emitted inside showTooltip before the test subscribed, so first() never fired and the expectation was dead. Assert service.hasAttached synchronously instead.
Replace the generic note with the concrete reason the custom stream exists: a capture-phase document listener catches scroll from any container (CDK's bubble listener + cdkScrollable registration misses unmarked overflow:auto blocks), and the close threshold is measured from the trigger rect rather than the viewport scroll position.
Replace the global capture-phase document listener with per-ancestor passive listeners: walk the anchor's DOM ancestors, keep only real scroll containers (getScrollableAncestors, ported from Floating UI's getOverflowAncestors), and attach one passive listener per ancestor plus the window. This reacts only to the few containers in the anchor's chain instead of every scroll on the page, still needs no cdkScrollable markup, and re-discovers ancestors on each enable(). The anchor is passed as a lazy getOrigin() resolved on enable(), so the dropdown origin input need not be set before the strategy is created. Unifies the close / reposition params into EvoScrollStrategyParams.
Assert it collects overflow auto/scroll ancestors, skips overflow:visible, and always appends the window last.
Вопрос 1
Ответна оверлей вешать Альтернативная реализацияБрать паттерн Floating UI: обойти DOM-предков якоря, определить скролл-контейнеры по Где текущая логика с глобальным слушателем лучше:
Главное: как оверлей следит за прокруткойТултип/дропдаун должны «прилипать» к своему якорю (кнопке/иконке) и закрываться/переезжать, когда Сейчас — один слушатель «на всё».
Альтернативно — датчики только там, где надо.
Почему альтернативная (несколько слушателей) лучше1. Меньше холостой работы. 2. Каждое срабатывание у 3. Попутно исправлен баг дропдауна (это уже не перф, а поведение). 4. Проще рассуждать. Насколько плоха текущаяЧестно — не катастрофа, рабочее первое приближение. Для тултипа разница вообще только в Порядок «ущерба» текущей версии:
Итогальтернативная = тот же результат для пользователя, но реагирует точечно (только релевантные прокрутки), Вопрос 4
Ответ Что мы НЕ дублируем (берём у CDK как есть)
Что мы по-прежнему дублируем из CDK
Эту правку per-ancestor не трогала — тела Что в принципе НЕ из CDK
Можно ли убрать дублирование CDKЧастично — да, и это как раз то, на что оставлен Но полностью не выйдет:
Итог
|
…ep dropdown close fix Drop the per-ancestor discovery (getScrollableAncestors) and restore the single capture-phase document scroll listener. Keep the dropdown fix: the close strategy still receives the anchor via getOrigin and decides to close from the anchor's getBoundingClientRect() movement, so the dropdown closes only when its own container actually moves it, not on any page scroll. Reposition no longer takes params.
No description provided.