- Slide the "Ready in about" value when it changes (new EtaMessage) - Drop the "Running late" banner; delays only move the ETA now - Remove the cancel-info tooltip and its icon button - Shorten the steps toggle to "Steps" / "Hide" - Add icons and more padding to the order card action buttons Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import { motion, useReducedMotion } from 'framer-motion'
|
|
|
|
import styles from './ItemStatusBanner.module.scss'
|
|
|
|
export type ItemStatusBannerVariant = 'ready' | 'pickedUp' | 'cancelled'
|
|
|
|
const iconPaths = {
|
|
ready: ['M7.5 12.5l3 3 6-6.5'],
|
|
pickedUp: ['M7.5 12.5l3 3 6-6.5'],
|
|
cancelled: ['M8.5 8.5l7 7', 'M15.5 8.5l-7 7'],
|
|
} satisfies Record<ItemStatusBannerVariant, Array<string>>
|
|
|
|
type ItemStatusBannerProps = {
|
|
variant: ItemStatusBannerVariant
|
|
label: string
|
|
detail?: string
|
|
animateIn: boolean
|
|
}
|
|
|
|
export const ItemStatusBanner = ({
|
|
variant,
|
|
label,
|
|
detail,
|
|
animateIn,
|
|
}: ItemStatusBannerProps) => {
|
|
const reduceMotion = useReducedMotion()
|
|
const skipAnimation = !animateIn || reduceMotion
|
|
|
|
return (
|
|
<motion.div
|
|
className={styles.banner}
|
|
data-variant={variant}
|
|
role="status"
|
|
initial={skipAnimation ? false : { opacity: 0, y: 4 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.3 }}
|
|
>
|
|
<svg className={styles.icon} viewBox="0 0 24 24" aria-hidden="true">
|
|
<motion.circle
|
|
cx="12"
|
|
cy="12"
|
|
r="10"
|
|
initial={skipAnimation ? false : { pathLength: 0, rotate: -90 }}
|
|
animate={{ pathLength: 1, rotate: -90 }}
|
|
transition={{ duration: 0.5, ease: 'easeOut' }}
|
|
/>
|
|
{iconPaths[variant].map((d, index) => (
|
|
<motion.path
|
|
key={d}
|
|
d={d}
|
|
initial={skipAnimation ? false : { pathLength: 0 }}
|
|
animate={{ pathLength: 1 }}
|
|
transition={{
|
|
duration: 0.3,
|
|
ease: 'easeOut',
|
|
delay: 0.45 + index * 0.2,
|
|
}}
|
|
/>
|
|
))}
|
|
</svg>
|
|
<span className={styles.text}>
|
|
<span className={styles.label}>{label}</span>
|
|
{detail && <span className={styles.detail}>{detail}</span>}
|
|
</span>
|
|
</motion.div>
|
|
)
|
|
}
|