diff --git a/packages/slate-editor/src/components/SearchInput/SearchInput.tsx b/packages/slate-editor/src/components/SearchInput/SearchInput.tsx index 8eb339d3d..fbfc1fc6d 100644 --- a/packages/slate-editor/src/components/SearchInput/SearchInput.tsx +++ b/packages/slate-editor/src/components/SearchInput/SearchInput.tsx @@ -128,6 +128,7 @@ export function SearchInput({ suggestions, onClose: handleClose, onSelect, + origin: rootRef.current, children: suggestions.map((suggestion) => renderSuggestion({ suggestion, @@ -184,6 +185,7 @@ export namespace SearchInput { activeElement: HTMLElement | undefined; activeSuggestion: Suggestion | undefined; loading: boolean; + origin: HTMLElement | null; query: string; suggestions: Suggestion[]; onClose: () => void; @@ -227,6 +229,7 @@ function defaultRenderSuggestions({ activeElement, query, suggestions, + origin, children, }: SearchInput.Props.Suggestions) { return ( @@ -234,6 +237,7 @@ function defaultRenderSuggestions({ activeElement={activeElement} query={query} suggestions={suggestions} + origin={origin} > {children} diff --git a/packages/slate-editor/src/components/SearchInput/Suggestions.module.scss b/packages/slate-editor/src/components/SearchInput/Suggestions.module.scss index bd9a6693e..e2e7b614d 100644 --- a/packages/slate-editor/src/components/SearchInput/Suggestions.module.scss +++ b/packages/slate-editor/src/components/SearchInput/Suggestions.module.scss @@ -3,4 +3,5 @@ .Suggestions { display: flex; flex-direction: column; + width: 100%; } diff --git a/packages/slate-editor/src/components/SearchInput/Suggestions.tsx b/packages/slate-editor/src/components/SearchInput/Suggestions.tsx index de1310d52..de5dec144 100644 --- a/packages/slate-editor/src/components/SearchInput/Suggestions.tsx +++ b/packages/slate-editor/src/components/SearchInput/Suggestions.tsx @@ -1,6 +1,9 @@ +import type { FlipModifier } from '@popperjs/core/lib/modifiers/flip'; +import type { PreventOverflowModifier } from '@popperjs/core/lib/modifiers/preventOverflow'; import classNames from 'classnames'; import type { HTMLAttributes, ReactNode } from 'react'; import React, { useEffect, useRef, useState } from 'react'; +import { usePopper } from 'react-popper'; import { useFunction } from '#lib'; @@ -12,11 +15,12 @@ import type { Suggestion } from './types'; export interface Props extends HTMLAttributes { activeElement: HTMLElement | undefined; - minHeight?: number; + footer?: ReactNode; maxHeight?: number; + minHeight?: number; + origin: HTMLElement | null; query: string; suggestions: Suggestion[]; - footer?: ReactNode; } export function Suggestions({ @@ -24,28 +28,41 @@ export function Suggestions({ children, className, footer, - minHeight = 200, maxHeight = 500, + minHeight = 200, + origin, query, suggestions, ...attributes }: Props) { const [height, setHeight] = useState(); - const [calculatedMaxHeight, setMaxHeight] = useState(); const container = useRef(null); const childrenContainer = useRef(null); const [scrollarea, setScrollarea] = useState(null); + const popper = usePopper(origin, container.current, { + modifiers: [ + { + name: 'flip', + enabled: true, + options: { + fallbackPlacements: ['top'], + }, + } satisfies Partial, + { + name: 'preventOverflow', + enabled: true, + options: { + altAxis: true, + mainAxis: true, + }, + } satisfies Partial + ], + placement: 'bottom', + }); + const updatePanelSize = useFunction(() => { setHeight(childrenContainer.current?.getBoundingClientRect().height); - - if (container.current) { - const viewport = document.body.getBoundingClientRect(); - const rect = container.current.getBoundingClientRect(); - setMaxHeight(clamp(viewport.height - rect.top - 4, minHeight, maxHeight)); - } else { - setMaxHeight(undefined); - } }); useEffect(() => { @@ -71,7 +88,8 @@ export function Suggestions({ return ( ({ ); } - -function clamp(num: number, min: number, max: number) { - if (num < min) return min; - if (num > max) return max; - return num; -} diff --git a/packages/slate-editor/src/extensions/placeholders/elements/ContactPlaceholderElement.tsx b/packages/slate-editor/src/extensions/placeholders/elements/ContactPlaceholderElement.tsx index 8a8e683fd..e892f71f5 100644 --- a/packages/slate-editor/src/extensions/placeholders/elements/ContactPlaceholderElement.tsx +++ b/packages/slate-editor/src/extensions/placeholders/elements/ContactPlaceholderElement.tsx @@ -72,6 +72,7 @@ export function ContactPlaceholderElement({ query={props.query} suggestions={props.suggestions} footer={renderSuggestionsFooter?.(props)} + origin={props.origin} > {props.children} diff --git a/packages/slate-editor/src/extensions/placeholders/elements/CoveragePlaceholderElement.tsx b/packages/slate-editor/src/extensions/placeholders/elements/CoveragePlaceholderElement.tsx index 425e7672b..c3b070e21 100644 --- a/packages/slate-editor/src/extensions/placeholders/elements/CoveragePlaceholderElement.tsx +++ b/packages/slate-editor/src/extensions/placeholders/elements/CoveragePlaceholderElement.tsx @@ -145,6 +145,7 @@ export function CoveragePlaceholderElement({ query={props.query} suggestions={props.suggestions} footer={renderSuggestionsFooter?.({ ...props, onMode })} + origin={props.origin} > {props.children} diff --git a/packages/slate-editor/src/extensions/placeholders/elements/GalleryBookmarkPlaceholderElement.tsx b/packages/slate-editor/src/extensions/placeholders/elements/GalleryBookmarkPlaceholderElement.tsx index dce7dc62e..dddbe8ac6 100644 --- a/packages/slate-editor/src/extensions/placeholders/elements/GalleryBookmarkPlaceholderElement.tsx +++ b/packages/slate-editor/src/extensions/placeholders/elements/GalleryBookmarkPlaceholderElement.tsx @@ -95,6 +95,7 @@ export function GalleryBookmarkPlaceholderElement({ query={props.query} suggestions={props.suggestions} footer={renderSuggestionsFooter?.(props)} + origin={props.origin} > {props.children} diff --git a/packages/slate-editor/src/extensions/placeholders/elements/InlineContactPlaceholderElement/InlineContactPlaceholderElement.tsx b/packages/slate-editor/src/extensions/placeholders/elements/InlineContactPlaceholderElement/InlineContactPlaceholderElement.tsx index eb14aa0db..bdd2af456 100644 --- a/packages/slate-editor/src/extensions/placeholders/elements/InlineContactPlaceholderElement/InlineContactPlaceholderElement.tsx +++ b/packages/slate-editor/src/extensions/placeholders/elements/InlineContactPlaceholderElement/InlineContactPlaceholderElement.tsx @@ -101,6 +101,7 @@ export function InlineContactPlaceholderElement({ query={props.query} suggestions={props.suggestions} footer={renderSuggestionsFooter?.(props)} + origin={props.origin} > {props.children} diff --git a/packages/slate-editor/src/extensions/placeholders/elements/StoryBookmarkPlaceholderElement.tsx b/packages/slate-editor/src/extensions/placeholders/elements/StoryBookmarkPlaceholderElement.tsx index aef09964c..b28bc312e 100644 --- a/packages/slate-editor/src/extensions/placeholders/elements/StoryBookmarkPlaceholderElement.tsx +++ b/packages/slate-editor/src/extensions/placeholders/elements/StoryBookmarkPlaceholderElement.tsx @@ -71,6 +71,7 @@ export function StoryBookmarkPlaceholderElement({ query={props.query} suggestions={props.suggestions} footer={renderSuggestionsFooter?.(props)} + origin={props.origin} > {props.children} diff --git a/packages/slate-editor/src/extensions/placeholders/elements/StoryEmbedPlaceholderElement.tsx b/packages/slate-editor/src/extensions/placeholders/elements/StoryEmbedPlaceholderElement.tsx index c9d471ca1..d94d13ccf 100644 --- a/packages/slate-editor/src/extensions/placeholders/elements/StoryEmbedPlaceholderElement.tsx +++ b/packages/slate-editor/src/extensions/placeholders/elements/StoryEmbedPlaceholderElement.tsx @@ -71,6 +71,7 @@ export function StoryEmbedPlaceholderElement({ query={props.query} suggestions={props.suggestions} footer={renderSuggestionsFooter?.(props)} + origin={props.origin} > {props.children}