
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@tuel/config
Advanced tools
Advanced configuration patterns, animation presets, and settings management
Advanced configuration patterns, animation presets, and settings management for TUEL animation library.
npm install @tuel/config
# or
yarn add @tuel/config
# or
pnpm add @tuel/config
Wrap your app with TuelConfigProvider to enable global configuration:
import { TuelConfigProvider } from '@tuel/config';
function App() {
return (
<TuelConfigProvider
initialConfig={{
globalDuration: 300,
theme: 'auto',
enableDebug: false,
}}
persistConfig={true}
>
<YourApp />
</TuelConfigProvider>
);
}
Access configuration values in any component:
import { useTuelConfig, useAnimationConfig } from '@tuel/config';
function MyComponent() {
const { config, updateConfig } = useTuelConfig();
const animConfig = useAnimationConfig();
return (
<motion.div
animate={{ opacity: 1 }}
transition={{
duration: animConfig.duration / 1000,
ease: animConfig.ease,
}}
>
Content
</motion.div>
);
}
Main configuration provider component.
Props:
interface TuelConfigProviderProps {
children: React.ReactNode;
initialConfig?: Partial<TuelConfig>;
persistConfig?: boolean; // Default: true
storageKey?: string; // Default: 'tuel-config'
}
Example:
<TuelConfigProvider
initialConfig={{
globalDuration: 500,
globalEase: [0.25, 0.46, 0.45, 0.94],
theme: 'dark',
enableOptimizations: true,
}}
persistConfig={true}
storageKey="my-app-tuel-config"
>
<App />
</TuelConfigProvider>
interface TuelConfig {
// Animation settings
globalDuration: number; // Default: 300ms
globalEase: string | number[]; // Default: 'easeInOut'
reducedMotion: boolean; // Auto-detected
// Performance settings
enableFrameControl: boolean; // Default: true
targetFPS: number; // Default: 60
enableOptimizations: boolean; // Default: true
// Theme settings
theme: 'light' | 'dark' | 'auto'; // Default: 'auto'
colorScheme: Record<string, string>;
// Debug settings
enableDebug: boolean; // Default: false
showPerformanceMetrics: boolean; // Default: false
logAnimations: boolean; // Default: false
// Custom settings
custom: Record<string, any>;
}
useTuelConfig()Access and modify configuration:
const { config, updateConfig, resetConfig, getConfigValue, setConfigValue } = useTuelConfig();
// Update multiple values
updateConfig({
globalDuration: 500,
theme: 'dark',
});
// Update single value
setConfigValue('globalDuration', 400);
// Get single value
const duration = getConfigValue('globalDuration');
// Reset to defaults
resetConfig();
useAnimationConfig()Get animation-specific configuration with reduced motion support:
const { duration, ease, reducedMotion, shouldAnimate } = useAnimationConfig();
// Use in animations
<motion.div
animate={{ x: shouldAnimate ? 100 : 0 }}
transition={{ duration: duration / 1000, ease }}
/>
useConfigValue<K>(key: K)Get a specific configuration value with type safety:
const duration = useConfigValue('globalDuration'); // number
const theme = useConfigValue('theme'); // 'light' | 'dark' | 'auto'
import { useTheme, useThemeAnimation } from '@tuel/config';
function ThemedComponent() {
// Get theme configuration
const theme = useTheme('modern', 'dark');
// Get theme animation helpers
const anim = useThemeAnimation(theme);
return (
<motion.div
style={{
backgroundColor: theme.colors.background,
color: theme.colors.text,
borderRadius: theme.borderRadius.md,
padding: theme.spacing.lg,
}}
animate={{ opacity: 1 }}
transition={{
duration: anim.duration('normal') / 1000,
ease: anim.easing('easeOut'),
}}
>
Content
</motion.div>
);
}
Each theme includes light and dark variants.
interface ThemeConfig {
name: string;
colors: Record<string, string>;
animations: {
duration: { fast: 150, normal: 300, slow: 500, slower: 750 };
easing: Record<string, string | number[]>;
timing: { stagger: number, delay: number };
};
spacing: Record<string, number>;
borderRadius: Record<string, number>;
shadows: Record<string, string>;
}
import { createTheme } from '@tuel/config';
const customTheme = createTheme('modern', {
light: {
colors: {
primary: '#ff6b6b',
secondary: '#4ecdc4',
accent: '#ffe66d',
},
animations: {
duration: {
fast: 100,
normal: 250,
},
},
},
dark: {
colors: {
primary: '#ff8787',
secondary: '#5fd9cf',
accent: '#ffef9f',
},
},
});
// Use custom theme
const theme = customTheme.light;
fadeIn - Gentle fade inslideInUp - Slide from bottomslideInDown - Slide from topslideInLeft - Slide from leftslideInRight - Slide from rightscaleIn - Scale uprotateIn - Rotate inbounceIn - Bounce in with elastic effectzoomIn - Zoom in with scaleflipIn - 3D flip infadeOut - Gentle fade outslideOutUp - Slide to topslideOutDown - Slide to bottomslideOutLeft - Slide to leftslideOutRight - Slide to rightscaleOut - Scale downrotateOut - Rotate outbounceOut - Bounce outzoomOut - Zoom out with scaleflipOut - 3D flip outpulse - Pulsing scale effectshake - Horizontal shakewobble - Rotating wobbleflash - Opacity flashbounce - Vertical bounceswing - Pendulum swingrubberBand - Elastic stretchjello - Jello-like wobblelift - Lift up on hovergrow - Grow on hovershrink - Shrink on hovertilt - Slight tilt on hoverglow - Glow effect on hoverfloat - Continuous floatingimport { animationPresets, getPreset } from '@tuel/config';
import { motion } from 'framer-motion';
function AnimatedCard() {
const fadeIn = getPreset('fadeIn');
const lift = getPreset('lift');
return (
<motion.div
initial={fadeIn.variants.initial}
animate={fadeIn.variants.animate}
exit={fadeIn.variants.exit}
whileHover={lift.variants.hover}
transition={{
duration: fadeIn.duration / 1000,
ease: fadeIn.ease,
}}
>
Card Content
</motion.div>
);
}
import { getPresetsByCategory } from '@tuel/config';
// Get all entrance animations
const entranceAnimations = getPresetsByCategory('entrance');
// Get all hover effects
const hoverEffects = getPresetsByCategory('hover');
import { createCustomPreset, getPreset } from '@tuel/config';
const customFadeIn = createCustomPreset('fadeIn', {
duration: 800,
ease: [0.25, 0.46, 0.45, 0.94],
variants: {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
},
});
interface AnimationPreset {
name: string;
description?: string;
duration: number; // in milliseconds
ease: string | number[]; // CSS easing or cubic bezier array
delay?: number;
variants?: Record<string, any>; // Framer Motion variants
options?: Record<string, any>;
}
import { useTuelConfig } from '@tuel/config';
function ResponsiveAnimation() {
const { config } = useTuelConfig();
const isMobile = window.innerWidth < 768;
return (
<motion.div
animate={{ x: 100 }}
transition={{
duration: (config.globalDuration * (isMobile ? 0.7 : 1)) / 1000,
}}
/>
);
}
import { useTuelConfig } from '@tuel/config';
function DebugPanel() {
const { config, updateConfig } = useTuelConfig();
return (
<div>
<button onClick={() => updateConfig({ enableDebug: !config.enableDebug })}>
Toggle Debug: {config.enableDebug ? 'ON' : 'OFF'}
</button>
{config.enableDebug && (
<pre>{JSON.stringify(config, null, 2)}</pre>
)}
</div>
);
}
import { useAnimationConfig } from '@tuel/config';
function ConditionalAnimation() {
const { shouldAnimate, duration } = useAnimationConfig();
return (
<motion.div
animate={shouldAnimate ? { opacity: 1, y: 0 } : { opacity: 1 }}
transition={{ duration: duration / 1000 }}
>
{shouldAnimate ? 'Animated!' : 'Static (reduced motion)'}
</motion.div>
);
}
import { withTuelConfig } from '@tuel/config';
function MyComponent({ duration, ease, reducedMotion }) {
return (
<motion.div
animate={{ scale: reducedMotion ? 1 : 1.2 }}
transition={{ duration: duration / 1000, ease }}
>
Content
</motion.div>
);
}
export default withTuelConfig(MyComponent);
Full TypeScript support with strict typing:
import type {
TuelConfig,
TuelConfigContextValue,
ThemeConfig,
ThemeVariant,
AnimationPreset,
AnimationPresets,
} from '@tuel/config';
// Type-safe configuration
const config: Partial<TuelConfig> = {
globalDuration: 300,
theme: 'dark',
};
// Type-safe theme
const theme: ThemeConfig = useTheme('modern', 'light');
// Type-safe preset access
const preset: AnimationPreset = getPreset('fadeIn');
The package is SSR-safe and handles server-side rendering gracefully:
window and localStorage checks are built-inTuelConfigProvider as high as possible in your component treeshouldAnimate for accessibilitypersistConfig for better UXMIT © Omer Akben
FAQs
Advanced configuration patterns, animation presets, and settings management
We found that @tuel/config demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.