A React Native app for the ultimate thinking partner.
at sdk-v1-upgrade 134 lines 3.4 kB view raw
1// Letta Brand Animation System 2 3// Duration constants (in milliseconds) 4export const duration = { 5 instant: 0, 6 fast: 200, 7 normal: 300, 8 slow: 400, 9 slower: 600, 10} as const; 11 12// Easing functions 13export const easing = { 14 // Standard easing 15 linear: 'linear', 16 easeIn: 'ease-in', 17 easeOut: 'ease-out', 18 easeInOut: 'ease-in-out', 19 20 // Custom cubic-bezier curves 21 bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)', 22 smooth: 'cubic-bezier(0.4, 0, 0.2, 1)', 23 sharp: 'cubic-bezier(0.4, 0, 0.6, 1)', 24} as const; 25 26// Pre-defined animation configurations 27export const animations = { 28 // Micro-interactions 29 buttonHover: { 30 duration: duration.fast, 31 easing: easing.smooth, 32 transform: 'scale(1.02)', 33 }, 34 buttonPress: { 35 duration: duration.fast, 36 easing: easing.sharp, 37 transform: 'scale(0.98)', 38 }, 39 40 // Message animations 41 messageAppear: { 42 duration: duration.normal, 43 easing: easing.smooth, 44 from: { opacity: 0, transform: 'translateY(10px)' }, 45 to: { opacity: 1, transform: 'translateY(0px)' }, 46 }, 47 reasoningReveal: { 48 duration: duration.slow, 49 easing: easing.smooth, 50 from: { opacity: 0, maxHeight: 0 }, 51 to: { opacity: 1, maxHeight: '200px' }, 52 }, 53 54 // Loading states 55 pulse: { 56 duration: 1500, 57 easing: easing.easeInOut, 58 iterationCount: 'infinite', 59 direction: 'alternate', 60 from: { opacity: 0.4 }, 61 to: { opacity: 1 }, 62 }, 63 spin: { 64 duration: 1000, 65 easing: easing.linear, 66 iterationCount: 'infinite', 67 from: { transform: 'rotate(0deg)' }, 68 to: { transform: 'rotate(360deg)' }, 69 }, 70 71 // Layout transitions 72 slideIn: { 73 duration: duration.normal, 74 easing: easing.smooth, 75 from: { transform: 'translateX(-100%)' }, 76 to: { transform: 'translateX(0%)' }, 77 }, 78 slideOut: { 79 duration: duration.normal, 80 easing: easing.smooth, 81 from: { transform: 'translateX(0%)' }, 82 to: { transform: 'translateX(-100%)' }, 83 }, 84 fadeIn: { 85 duration: duration.normal, 86 easing: easing.smooth, 87 from: { opacity: 0 }, 88 to: { opacity: 1 }, 89 }, 90 fadeOut: { 91 duration: duration.fast, 92 easing: easing.smooth, 93 from: { opacity: 1 }, 94 to: { opacity: 0 }, 95 }, 96 97 // Focus states 98 focusGlow: { 99 duration: duration.fast, 100 easing: easing.smooth, 101 boxShadow: '0 0 20px rgba(0, 102, 255, 0.4)', 102 }, 103 104 // Geometric loading (Letta-specific) 105 geometricAssembly: { 106 duration: duration.slower, 107 easing: easing.bounce, 108 keyframes: [ 109 { transform: 'scale(0) rotate(0deg)', opacity: 0 }, 110 { transform: 'scale(0.5) rotate(180deg)', opacity: 0.5 }, 111 { transform: 'scale(1) rotate(360deg)', opacity: 1 }, 112 ], 113 }, 114} as const; 115 116// Animation utility functions 117export const createKeyframes = (keyframes: Record<string, any>) => { 118 return Object.entries(keyframes) 119 .map(([key, value]) => `${key} { ${Object.entries(value).map(([prop, val]) => `${prop}: ${val};`).join(' ')} }`) 120 .join(' '); 121}; 122 123export const createTransition = ( 124 property: string | string[], 125 duration: number = 300, 126 easing: string = 'ease-in-out' 127) => { 128 const properties = Array.isArray(property) ? property : [property]; 129 return properties.map(prop => `${prop} ${duration}ms ${easing}`).join(', '); 130}; 131 132export type Duration = typeof duration; 133export type Easing = typeof easing; 134export type Animations = typeof animations;