fix dynamic setting of suggestions modal (#272)

This commit is contained in:
Red J Adaya 2024-08-27 07:33:05 +08:00 committed by GitHub
parent cefc491bf2
commit 7d98aeb2c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 20 deletions

View File

@ -34,6 +34,7 @@
border: 0.5px solid var(--modal-border-color); border: 0.5px solid var(--modal-border-color);
background: var(--modal-bg-color); background: var(--modal-bg-color);
box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25); box-shadow: 0px 8px 32px 0px rgba(0, 0, 0, 0.25);
height: auto;
.modal-close-btn { .modal-close-btn {
position: absolute; position: absolute;

View File

@ -2,7 +2,7 @@ import { Input } from "@/app/element/input";
import { InputDecoration } from "@/app/element/inputdecoration"; import { InputDecoration } from "@/app/element/inputdecoration";
import { useDimensions } from "@/app/hook/useDimensions"; import { useDimensions } from "@/app/hook/useDimensions";
import clsx from "clsx"; import clsx from "clsx";
import React, { useEffect, useRef, useState } from "react"; import React, { forwardRef, useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import "./typeaheadmodal.less"; import "./typeaheadmodal.less";
@ -81,15 +81,9 @@ interface SuggestionsProps {
onSelect?: (_: string) => void; onSelect?: (_: string) => void;
} }
function Suggestions({ suggestions, onSelect }: SuggestionsProps) { const Suggestions = forwardRef<HTMLDivElement, SuggestionsProps>(({ suggestions, onSelect }: SuggestionsProps, ref) => {
const suggestionsWrapperRef = useRef<HTMLDivElement>(null);
return ( return (
<div <div ref={ref} className="suggestions-wrapper" style={{ marginTop: suggestions?.length > 0 ? "8px" : "0" }}>
ref={suggestionsWrapperRef}
className="suggestions-wrapper"
style={{ marginTop: suggestions?.length > 0 ? "8px" : "0" }}
>
{suggestions?.map((suggestion, index) => ( {suggestions?.map((suggestion, index) => (
<div className="suggestion" key={index} onClick={() => onSelect(suggestion.value)}> <div className="suggestion" key={index} onClick={() => onSelect(suggestion.value)}>
{suggestion.label} {suggestion.label}
@ -97,7 +91,7 @@ function Suggestions({ suggestions, onSelect }: SuggestionsProps) {
))} ))}
</div> </div>
); );
} });
interface TypeAheadModalProps { interface TypeAheadModalProps {
anchor: React.MutableRefObject<HTMLDivElement>; anchor: React.MutableRefObject<HTMLDivElement>;
@ -125,20 +119,31 @@ const TypeAheadModal = ({
const { width, height } = useDimensions(anchor); const { width, height } = useDimensions(anchor);
const modalRef = useRef<HTMLDivElement>(null); const modalRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLDivElement>(null); const inputRef = useRef<HTMLDivElement>(null);
const suggestionsWrapperRef = useRef<HTMLDivElement>(null);
const [suggestionsHeight, setSuggestionsHeight] = useState<number | undefined>(undefined); const [suggestionsHeight, setSuggestionsHeight] = useState<number | undefined>(undefined);
const [modalHeight, setModalHeight] = useState<string | undefined>(undefined);
useEffect(() => { useEffect(() => {
if (modalRef.current && inputRef.current) { if (modalRef.current && inputRef.current && suggestionsWrapperRef.current) {
const modalHeight = modalRef.current.getBoundingClientRect().height; const modalPadding = 32;
const inputHeight = inputRef.current.getBoundingClientRect().height; const inputHeight = inputRef.current.getBoundingClientRect().height;
let suggestionsTotalHeight = 0;
// Get the padding value (assuming padding is uniform on all sides) const suggestionItems = suggestionsWrapperRef.current.children;
const padding = 16 * 2; // 16px top + 16px bottom for (let i = 0; i < suggestionItems.length; i++) {
suggestionsTotalHeight += suggestionItems[i].getBoundingClientRect().height;
}
// Subtract the input height and padding from the modal height const totalHeight = modalPadding + inputHeight + suggestionsTotalHeight;
setSuggestionsHeight(modalHeight - inputHeight - padding); const maxHeight = height * 0.8;
const computedHeight = totalHeight > maxHeight ? maxHeight : totalHeight;
setModalHeight(`${computedHeight}px`);
const padding = 16 * 2;
setSuggestionsHeight(computedHeight - inputHeight - padding);
} }
}, [width, height]); }, [height, suggestions.length]);
const renderBackdrop = (onClick) => <div className="type-ahead-modal-backdrop" onClick={onClick}></div>; const renderBackdrop = (onClick) => <div className="type-ahead-modal-backdrop" onClick={onClick}></div>;
@ -162,7 +167,7 @@ const TypeAheadModal = ({
className={clsx("type-ahead-modal", className)} className={clsx("type-ahead-modal", className)}
style={{ style={{
width: width * 0.6, width: width * 0.6,
maxHeight: height * 0.8, maxHeight: modalHeight,
}} }}
> >
<div className="content-wrapper"> <div className="content-wrapper">
@ -187,7 +192,7 @@ const TypeAheadModal = ({
overflowY: "auto", overflowY: "auto",
}} }}
> >
<Suggestions suggestions={suggestions} onSelect={handleSelect} /> <Suggestions ref={suggestionsWrapperRef} suggestions={suggestions} onSelect={handleSelect} />
</div> </div>
</div> </div>
</div> </div>

View File

@ -687,7 +687,6 @@ function PreviewView({ blockId, model }: { blockId: string; model: PreviewModel
anchor={contentRef} anchor={contentRef}
onKeyDown={(e) => keyutil.keydownWrapper(handleKeyDown)(e)} onKeyDown={(e) => keyutil.keydownWrapper(handleKeyDown)(e)}
onSelect={handleFileSuggestionSelect} onSelect={handleFileSuggestionSelect}
onSubmit={(value) => console.log(value)}
/> />
)} )}
<div <div