@erosnicolau/animated-text
Version:
Advanced React animated text component with comprehensive animation effects
200 lines (199 loc) • 11.3 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from 'react';
const ConfigModal = ({ isOpen, onClose, componentProps }) => {
const [copySuccess, setCopySuccess] = useState(false);
if (!isOpen)
return null;
// Check if this is a group configuration
const isGroupConfig = 'isGroup' in componentProps && componentProps.isGroup;
// Generate JSX code from props
const generateCode = (props) => {
const lines = ['<AnimatedText'];
// Add content prop
if (props.content) {
lines.push(` content="${props.content}"`);
}
// Add animation props
if (props.animation && props.animation !== 'block') {
lines.push(` animation="${props.animation}"`);
}
if (props.align && props.align !== 'left') {
lines.push(` align="${props.align}"`);
}
if (props.verticalAlign && props.verticalAlign !== 'top') {
lines.push(` verticalAlign="${props.verticalAlign}"`);
}
// Layout props
if (props.width)
lines.push(` width="${props.width}"`);
if (props.minWidth)
lines.push(` minWidth="${props.minWidth}"`);
if (props.maxWidth)
lines.push(` maxWidth="${props.maxWidth}"`);
if (props.height)
lines.push(` height="${props.height}"`);
if (props.minHeight)
lines.push(` minHeight="${props.minHeight}"`);
if (props.maxHeight)
lines.push(` maxHeight="${props.maxHeight}"`);
// Static styling props
if (props.transformOrigin)
lines.push(` transformOrigin="${props.transformOrigin}"`);
if (props.textShadow)
lines.push(` textShadow="${props.textShadow}"`);
// Animation timing props
if (props.startDelay && props.startDelay !== 300) {
lines.push(` startDelay={${props.startDelay}}`);
}
if (props.itemSpacing && props.itemSpacing !== 600) {
lines.push(` itemSpacing={${props.itemSpacing}}`);
}
// Block animation props
if (props.blockEffect && JSON.stringify(props.blockEffect) !== JSON.stringify(['fadeIn', 'slide-up'])) {
lines.push(` blockEffect={${JSON.stringify(props.blockEffect)}}`);
}
if (props.blockDuration && props.blockDuration !== 600) {
lines.push(` blockDuration={${props.blockDuration}}`);
}
if (props.blockEasing && props.blockEasing !== 'ease-out') {
lines.push(` blockEasing="${props.blockEasing}"`);
}
// Word animation props
if (props.animation === 'word') {
if (props.wordEffect && JSON.stringify(props.wordEffect) !== JSON.stringify(['fadeIn'])) {
lines.push(` wordEffect={${JSON.stringify(props.wordEffect)}}`);
}
if (props.wordDuration && props.wordDuration !== 400) {
lines.push(` wordDuration={${props.wordDuration}}`);
}
if (props.wordSpacing && props.wordSpacing !== 200) {
lines.push(` wordSpacing={${props.wordSpacing}}`);
}
if (props.wordEasing && props.wordEasing !== 'ease-out') {
lines.push(` wordEasing="${props.wordEasing}"`);
}
}
// Typewriter animation props
if (props.animation === 'typewriter') {
if (props.typewriterEffect && JSON.stringify(props.typewriterEffect) !== JSON.stringify(['fadeIn'])) {
lines.push(` typewriterEffect={${JSON.stringify(props.typewriterEffect)}}`);
}
if (props.typewriterDuration && props.typewriterDuration !== 200) {
lines.push(` typewriterDuration={${props.typewriterDuration}}`);
}
if (props.typewriterDelay && props.typewriterDelay !== 50) {
lines.push(` typewriterDelay={${props.typewriterDelay}}`);
}
if (props.typewriterEasing && props.typewriterEasing !== 'ease-out') {
lines.push(` typewriterEasing="${props.typewriterEasing}"`);
}
}
// Word-typewriter animation props
if (props.animation === 'word-typewriter') {
if (props.wordTypewriterEffect && JSON.stringify(props.wordTypewriterEffect) !== JSON.stringify(['fadeIn'])) {
lines.push(` wordTypewriterEffect={${JSON.stringify(props.wordTypewriterEffect)}}`);
}
if (props.wordTypewriterDuration && props.wordTypewriterDuration !== 150) {
lines.push(` wordTypewriterDuration={${props.wordTypewriterDuration}}`);
}
if (props.wordTypewriterLetterDelay && props.wordTypewriterLetterDelay !== 50) {
lines.push(` wordTypewriterLetterDelay={${props.wordTypewriterLetterDelay}}`);
}
if (props.wordTypewriterWordDelay && props.wordTypewriterWordDelay !== 400) {
lines.push(` wordTypewriterWordDelay={${props.wordTypewriterWordDelay}}`);
}
if (props.wordTypewriterEasing && props.wordTypewriterEasing !== 'ease-out') {
lines.push(` wordTypewriterEasing="${props.wordTypewriterEasing}"`);
}
}
// Phrase styles (simplified for readability)
if (props.phraseStyles && props.phraseStyles.length > 0) {
lines.push(` phraseStyles={[`);
props.phraseStyles.forEach((style, index) => {
const styleLines = [' {'];
// Add phrase targeting
if (Array.isArray(style.phrase)) {
styleLines.push(` phrase: [${style.phrase.join(', ')}],`);
}
else {
styleLines.push(` phrase: ${style.phrase},`);
}
// Add key props only
if (style.className)
styleLines.push(` className: '${style.className}',`);
if (style.maxWidth)
styleLines.push(` maxWidth: '${style.maxWidth}',`);
if (style.effect)
styleLines.push(` effect: ${JSON.stringify(style.effect)},`);
if (style.delayBefore !== undefined)
styleLines.push(` delayBefore: ${style.delayBefore},`);
styleLines.push(` }${index < (props.phraseStyles?.length || 0) - 1 ? ',' : ''}`);
lines.push(...styleLines);
});
lines.push(` ]}`);
}
// Element type
if (props.as && props.as !== 'div') {
lines.push(` as="${props.as}"`);
}
// Other props (excluding demo-specific props)
if (props.allowHtml)
lines.push(` allowHtml={true}`);
if (props.className)
lines.push(` className="${props.className}"`);
// Note: showReplay and showConfig are demo-specific and excluded from generated code
lines.push('/>');
return lines.join('\n');
};
// Generate group configuration code for groups, or component code for individual components
const generateGroupCode = (groupConfig) => {
const lines = ['<AnimatedTextGroup'];
if (groupConfig.coordinationMode !== 'parallel') {
lines.push(` coordinationMode="${groupConfig.coordinationMode}"`);
}
if (groupConfig.groupStartDelay !== 0) {
lines.push(` groupStartDelay={${groupConfig.groupStartDelay}}`);
}
if (groupConfig.staggerDelay !== 300) {
lines.push(` staggerDelay={${groupConfig.staggerDelay}}`);
}
if (groupConfig.showReplay) {
lines.push(` showReplay={true}`);
}
if (groupConfig.showConfig) {
lines.push(` showConfig={true}`);
}
if (groupConfig.debugMode) {
lines.push(` debugMode={true}`);
}
lines.push(' className="your-container-styles"');
lines.push('>');
lines.push(' {/* Your AnimatedText components */}');
lines.push(' <AnimatedText content="Your content" />');
lines.push('</AnimatedTextGroup>');
return lines.join('\n');
};
const code = isGroupConfig
? generateGroupCode(componentProps.groupConfig)
: generateCode(componentProps);
const copyToClipboard = async () => {
try {
await navigator.clipboard.writeText(code);
setCopySuccess(true);
setTimeout(() => setCopySuccess(false), 3000); // Reset after 3 seconds
}
catch {
// Fallback for older browsers
const textArea = document.createElement('textarea');
textArea.value = code;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
setCopySuccess(true);
setTimeout(() => setCopySuccess(false), 3000); // Reset after 3 seconds
}
};
return (_jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4", children: _jsxs("div", { className: "bg-white rounded-lg shadow-xl max-w-4xl w-full max-h-[80vh] overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between p-4 border-b", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "Component Configuration" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: copyToClipboard, className: `px-3 py-1 text-white text-sm rounded flex items-center gap-1 transition-all duration-300 ${copySuccess ? 'bg-green-500 hover:bg-green-600 scale-105' : 'bg-blue-500 hover:bg-blue-600'}`, title: copySuccess ? 'Copied successfully!' : 'Copy code to clipboard', children: copySuccess ? (_jsxs(_Fragment, { children: [_jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }), "Copied!"] })) : (_jsxs(_Fragment, { children: [_jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) }), "Copy"] })) }), _jsx("button", { onClick: onClose, className: "text-gray-400 hover:text-gray-600 transition-colors", "aria-label": "Close modal", children: _jsx("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] })] }), _jsx("div", { className: "p-4 overflow-auto max-h-[calc(80vh-120px)] text-left", children: _jsx("pre", { className: "bg-gray-100 p-4 rounded-lg text-sm overflow-x-auto", children: _jsx("code", { className: "text-gray-800 font-mono", children: code }) }) })] }) }));
};
export default ConfigModal;