@rockshin/react-image-annotation
Version:
An image annotation tool for ai project that manual annotation for images, easy to use!
149 lines (148 loc) • 7.63 kB
JavaScript
'use client'
import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__ from "react/jsx-runtime";
import * as __WEBPACK_EXTERNAL_MODULE_clsx__ from "clsx";
import * as __WEBPACK_EXTERNAL_MODULE_motion_react_9decfa63__ from "motion/react";
import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
import "./styles.css";
const defaultProps = {
progressInterval: 100,
progressIncrement: 2,
expandDelay: 300,
maxAutoProgress: 90,
loadingText: 'Loading...',
autoProgress: true
};
function Loading({ loadingText = defaultProps.loadingText, className = '', content = '', children, isLoading = false, progressInterval = defaultProps.progressInterval, progressIncrement = defaultProps.progressIncrement, expandDelay = defaultProps.expandDelay, maxAutoProgress = defaultProps.maxAutoProgress, autoProgress = defaultProps.autoProgress, contentClassName = '', loadingSpinnerClassName = '', progressBarClassName = '' }) {
const [state, setState] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)({
progress: 0,
showContent: false,
expanded: false
});
const contentRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(null);
const [contentHeight, setContentHeight] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(0);
(0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
if (isLoading) setState({
progress: 0,
showContent: false,
expanded: false
});
else if (content || children) {
setState((prev)=>({
...prev,
showContent: true
}));
setTimeout(()=>{
setState((prev)=>({
...prev,
expanded: true
}));
}, expandDelay);
}
}, [
isLoading,
content,
children,
expandDelay
]);
(0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
if (!autoProgress || !isLoading) return;
const intervalId = setInterval(()=>{
setState((prev)=>({
...prev,
progress: prev.progress >= maxAutoProgress ? maxAutoProgress : prev.progress + progressIncrement
}));
}, progressInterval);
return ()=>clearInterval(intervalId);
}, [
isLoading,
autoProgress,
maxAutoProgress,
progressIncrement,
progressInterval
]);
(0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
if (!isLoading && state.progress < 100) setState((prev)=>({
...prev,
progress: 100
}));
}, [
isLoading
]);
(0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
if (contentRef.current) setContentHeight(contentRef.current.scrollHeight + 32);
}, [
state.showContent
]);
const renderLoadingState = ()=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)(__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.Fragment, {
children: [
/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
className: "flex items-center",
children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("span", {
className: "text-[14px] font-medium text-[#181b25] whitespace-nowrap",
children: loadingText
})
}),
/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE_motion_react_9decfa63__.motion.div, {
className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__.clsx)('h-4 w-4 border-2 border-[#9672e4] border-t-transparent rounded-full ml-3', loadingSpinnerClassName),
animate: {
rotate: 360
},
transition: {
duration: 1,
repeat: 1 / 0,
ease: 'linear'
}
}),
/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__.clsx)('absolute bottom-0 left-0 h-[2px] bg-gradient-to-r from-[#9672e4] to-[#e0daff] transition-all duration-100', progressBarClassName),
style: {
width: `${state.progress}%`
}
})
]
});
const renderContent = ()=>{
if (children) return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
ref: contentRef,
className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__.clsx)('w-full transition-all duration-500 ease-in-out', state.expanded ? 'opacity-100' : 'opacity-0', contentClassName),
children: children
});
if (content) return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
ref: contentRef,
className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__.clsx)('w-full transition-all duration-500 ease-in-out', state.expanded ? 'opacity-100' : 'opacity-0', contentClassName),
children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
className: "prose prose-gray max-w-none py-4",
children: content.split('\n\n').map((paragraph, index)=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("p", {
className: "mb-4 text-[#181b25] leading-relaxed",
children: paragraph
}, index))
})
});
return null;
};
return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
className: "max-w-2xl mx-auto",
children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
className: "transition-all duration-500 ease-out transform",
children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE_motion_react_9decfa63__.motion.div, {
initial: {
opacity: 0,
scale: 0.95
},
animate: {
opacity: 1,
scale: 1
},
className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__.clsx)('relative bg-white overflow-hidden', 'transition-all duration-500 ease-in-out', state.showContent ? 'rounded-[16px] border border-[#e5e7eb]' : 'rounded-2xl border border-[#e5e7eb]', state.expanded ? 'transform-none' : 'scale-95 opacity-90', 'shadow-sm', state.showContent && 'animate-expand-width', className),
style: {
height: state.expanded ? contentHeight || 'auto' : '40px'
},
children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__.clsx)('px-6 flex items-center h-full justify-between', 'transition-all duration-500 ease-in-out', state.showContent && 'animate-slide-content', state.showContent && 'py-4'),
children: state.showContent ? renderContent() : renderLoadingState()
})
})
})
});
}
export { Loading as default };