/* * Copyright 2025 coze-dev Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* eslint-disable complexity */ import { useEffect, useRef, useState, type FC } from 'react'; import classNames from 'classnames'; import { useSize } from 'ahooks'; import { getNumberBetween } from '../../utils'; import styles from './index.module.less'; interface IProps { left?: number; top?: number; offsetY?: number; offsetX?: number; children?: React.ReactNode; position?: 'bottom-center' | 'bottom-right' | 'top-center'; zIndex?: number; onClick?: (e: React.MouseEvent) => void; className?: string; limitRect?: { width?: number; height?: number; }; } export const PopInScreen: FC = props => { const ref = useRef(null); const { left = 0, top = 0, children, position = 'bottom-center', zIndex = 1000, onClick, className, limitRect, } = props; // const documentSize = useSize(document.body); const childrenSize = useSize(ref.current); let maxLeft = (limitRect?.width ?? Infinity) - (childrenSize?.width ?? 0) / 2; let minLeft = (childrenSize?.width ?? 0) / 2; let transform = 'translate(-50%, 0)'; if (position === 'bottom-right') { maxLeft = (limitRect?.width ?? Infinity) - (childrenSize?.width ?? 0); minLeft = 0; transform = 'translate(0, 0)'; } else if (position === 'top-center') { transform = 'translate(-50%, -100%)'; } /** * ahooks useSize returns undefined on first execution, resulting in an error in component location evaluation * This listens to childrenSize. If it is undefined, delay rendering by 100ms to correct the component position. */ const [id, setId] = useState(''); const timer = useRef(); useEffect(() => { clearTimeout(timer.current); if (!childrenSize) { timer.current = setTimeout(() => { setId(`${Math.random()}`); }, 100); } }, [childrenSize]); return (
{/* To trigger secondary rendering */}
{children}
); };