style: format all files with prettier

This commit is contained in:
Seth Hobson
2026-01-19 17:07:03 -05:00
parent 8d37048deb
commit 56848874a2
355 changed files with 15215 additions and 10241 deletions

View File

@@ -23,6 +23,7 @@ Create engaging, intuitive interactions through motion, feedback, and thoughtful
### 1. Purposeful Motion
Motion should communicate, not decorate:
- **Feedback**: Confirm user actions occurred
- **Orientation**: Show where elements come from/go to
- **Focus**: Direct attention to important changes
@@ -30,27 +31,27 @@ Motion should communicate, not decorate:
### 2. Timing Guidelines
| Duration | Use Case |
|----------|----------|
| 100-150ms | Micro-feedback (hovers, clicks) |
| 200-300ms | Small transitions (toggles, dropdowns) |
| Duration | Use Case |
| --------- | ----------------------------------------- |
| 100-150ms | Micro-feedback (hovers, clicks) |
| 200-300ms | Small transitions (toggles, dropdowns) |
| 300-500ms | Medium transitions (modals, page changes) |
| 500ms+ | Complex choreographed animations |
| 500ms+ | Complex choreographed animations |
### 3. Easing Functions
```css
/* Common easings */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* Decelerate - entering */
--ease-in: cubic-bezier(0.55, 0, 1, 0.45); /* Accelerate - exiting */
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* Both - moving between */
--spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Overshoot - playful */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* Decelerate - entering */
--ease-in: cubic-bezier(0.55, 0, 1, 0.45); /* Accelerate - exiting */
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* Both - moving between */
--spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Overshoot - playful */
```
## Quick Start: Button Microinteraction
```tsx
import { motion } from 'framer-motion';
import { motion } from "framer-motion";
export function InteractiveButton({ children, onClick }) {
return (
@@ -58,7 +59,7 @@ export function InteractiveButton({ children, onClick }) {
onClick={onClick}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
transition={{ type: 'spring', stiffness: 400, damping: 17 }}
transition={{ type: "spring", stiffness: 400, damping: 17 }}
className="px-4 py-2 bg-blue-600 text-white rounded-lg"
>
{children}
@@ -72,6 +73,7 @@ export function InteractiveButton({ children, onClick }) {
### 1. Loading States
**Skeleton Screens**: Preserve layout while loading
```tsx
function CardSkeleton() {
return (
@@ -85,6 +87,7 @@ function CardSkeleton() {
```
**Progress Indicators**: Show determinate progress
```tsx
function ProgressBar({ progress }: { progress: number }) {
return (
@@ -93,7 +96,7 @@ function ProgressBar({ progress }: { progress: number }) {
className="h-full bg-blue-600"
initial={{ width: 0 }}
animate={{ width: `${progress}%` }}
transition={{ ease: 'easeOut' }}
transition={{ ease: "easeOut" }}
/>
</div>
);
@@ -103,6 +106,7 @@ function ProgressBar({ progress }: { progress: number }) {
### 2. State Transitions
**Toggle with smooth transition**:
```tsx
function Toggle({ checked, onChange }) {
return (
@@ -112,13 +116,13 @@ function Toggle({ checked, onChange }) {
onClick={() => onChange(!checked)}
className={`
relative w-12 h-6 rounded-full transition-colors duration-200
${checked ? 'bg-blue-600' : 'bg-gray-300'}
${checked ? "bg-blue-600" : "bg-gray-300"}
`}
>
<motion.span
className="absolute top-1 left-1 w-4 h-4 bg-white rounded-full shadow"
animate={{ x: checked ? 24 : 0 }}
transition={{ type: 'spring', stiffness: 500, damping: 30 }}
transition={{ type: "spring", stiffness: 500, damping: 30 }}
/>
</button>
);
@@ -128,8 +132,9 @@ function Toggle({ checked, onChange }) {
### 3. Page Transitions
**Framer Motion layout animations**:
```tsx
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, motion } from "framer-motion";
function PageTransition({ children, key }) {
return (
@@ -151,6 +156,7 @@ function PageTransition({ children, key }) {
### 4. Feedback Patterns
**Ripple effect on click**:
```tsx
function RippleButton({ children, onClick }) {
const [ripples, setRipples] = useState([]);
@@ -162,9 +168,9 @@ function RippleButton({ children, onClick }) {
y: e.clientY - rect.top,
id: Date.now(),
};
setRipples(prev => [...prev, ripple]);
setRipples((prev) => [...prev, ripple]);
setTimeout(() => {
setRipples(prev => prev.filter(r => r.id !== ripple.id));
setRipples((prev) => prev.filter((r) => r.id !== ripple.id));
}, 600);
onClick?.(e);
};
@@ -172,7 +178,7 @@ function RippleButton({ children, onClick }) {
return (
<button onClick={handleClick} className="relative overflow-hidden">
{children}
{ripples.map(ripple => (
{ripples.map((ripple) => (
<span
key={ripple.id}
className="absolute bg-white/30 rounded-full animate-ripple"
@@ -187,6 +193,7 @@ function RippleButton({ children, onClick }) {
### 5. Gesture Interactions
**Swipe to dismiss**:
```tsx
function SwipeCard({ children, onDismiss }) {
return (
@@ -212,29 +219,50 @@ function SwipeCard({ children, onDismiss }) {
```css
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
@keyframes spin {
to { transform: rotate(360deg); }
to {
transform: rotate(360deg);
}
}
.animate-fadeIn { animation: fadeIn 0.3s ease-out; }
.animate-pulse { animation: pulse 2s ease-in-out infinite; }
.animate-spin { animation: spin 1s linear infinite; }
.animate-fadeIn {
animation: fadeIn 0.3s ease-out;
}
.animate-pulse {
animation: pulse 2s ease-in-out infinite;
}
.animate-spin {
animation: spin 1s linear infinite;
}
```
### CSS Transitions
```css
.card {
transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
transition:
transform 0.2s ease-out,
box-shadow 0.2s ease-out;
}
.card:hover {
@@ -248,7 +276,9 @@ function SwipeCard({ children, onDismiss }) {
```css
/* Respect user motion preferences */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
@@ -259,7 +289,7 @@ function SwipeCard({ children, onDismiss }) {
```tsx
function AnimatedComponent() {
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
"(prefers-reduced-motion: reduce)",
).matches;
return (